지금까지 jdk 6, 7에 항상 일어나는 버그이다.

String [], Byte[]와 같은  Array type ([] )으로 된 클래스를 ClassLoader를 이용해서 클래스 로딩시ClassNotFoundException이 발생한다.

그러나 Class.forName 으로 바꾸면 괜찮다. 이 문제는 reflection을 이용할 때 동일하게 나기 때문에 주의하면서 개발해야 한다.

 

jdk 6, jdk 7에서의 테스트 코드이다.

public class test {
    public static void main(String[] args) throws Exception {
        String[] s = new String[] { "aaa" };
        String clName = s.getClass().getName();
        Class c = test.class.getClassLoader().loadClass(clName);
       System.out.println(c);
    }
}

실행 결과는 다음과 같다.

Exception in thread "main" java.lang.ClassNotFoundException: [Ljava.lang.String;
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at test.main(test.java:5)

 

문제가 안 일어나게 하려면 다음과 같이 코딩해야 한다.

public class test {
    public static void main(String[] args) throws Exception {
        String[] s = new String[] { "aaa" };
        String clName = s.getClass().getName();
        Class c = Class.forName(clName,false,Thread.currentThread().getContextClassLoader());
        System.out.println(c);
    }
}

결과는 다음과 같다.

class [Ljava.lang.String;

 

이 문제는 “http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6434149”에 올라와 있다.

비슷한 이슈로 다른 버그(“http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6446627”)도 있다.

public class test {
    public static void main(String[] args) throws Exception {
        String[] objs = new String[10];
        objs[0] = new String();
        String[] objs2 = (String[]) cloneObject(objs,
                test.class.getClassLoader());
    }

    public static Object cloneObject(Object toClone,
            final ClassLoader classLoader) throws Exception {
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        ObjectOutputStream oOut = new ObjectOutputStream(bOut);
        oOut.writeObject(toClone);
        oOut.close();
        ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray());
        bOut.close();
        ObjectInputStream oIn = new ObjectInputStream(bIn) {
            protected Class resolveClass(ObjectStreamClass desc)
                    throws IOException, ClassNotFoundException {
                System.out
                        .println("Attempting to load class " + desc.getName());
                return classLoader.loadClass(desc.getName());
            }
        };
        bIn.close();
        Object copy = oIn.readObject();
        oIn.close();
        return copy;
    }

}

 

결과.

Exception in thread "main" java.lang.ClassNotFoundException: [Ljava.lang.String;
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at test.main(test.java:5)

 

이문제는 현재 많은 개발자들은 오라클이 해주기를 기다리고 있다….

오라클 버그 데이터베이스에서는 개발자들이 투표를 통해서 bug를 빨리 처리해달라는 주소도 있으니 참조할 것.
http://bugs.sun.com/bugdatabase/top25_bugs.do

 

Posted by '김용환'
,