Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I was testing an example of accessing private method from another class and got an exception

public class WithoutMain 
{       
    public static void main(String args[]) throws Exception
    {
        Class c = Class.forName("A");
        Object o = c.newInstance();
        Method m = c.getDeclaredMethod("message", null);
        m.setAccessible(true);
        m.invoke(o, null);
    }
}

public class A {

    private void message(){ 
        System.out.println("This is a private method.");
    }
}

Getting following exception

Exception in thread "main" java.lang.ClassNotFoundException: A
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)

These 2 class resides in same package. Can anyone tell me why this exception shows?

share|improve this question
2  
what package A is in ? –  sanbhat Aug 31 at 18:51
 
Both class resides in same package. –  skabir Aug 31 at 18:53
 
@skabir What's the package name? –  arshajii Aug 31 at 18:54

6 Answers

up vote 1 down vote accepted

You have to provide the fully qualified name of the class, not only the simple class name.

Class c = Class.forName("<package>.A");
share|improve this answer

You need to use the fully qualified name of a class to load it using Class.forName()

Now you may argue why? As in your case both the classes are in the same directory/package.

I would argue the other way, there is no rule defined in java that the class loader will look in the same directory first.

If you want to learn how class loading works, I would suggest you source code for the class java.lang.ClassLoader class

So when you invoke the Class.forName it uses delegation and the class loader which is assigned the job to load this class will not know the current package or any location. Hence, it needs the fully qualified class name.

One more tip, in java a fully qualified class name of a loaded class is <ClassLoader><packageName><className>. This is how the classes in JVM are uniquely identified.

Hope this helps

EDIT

Your code will work only in one condition and that is, if both the classes are in default package.

share|improve this answer

Try changing

    Class c = Class.forName("A");

to

    Class c = Class.forName("yourPackagePath.A");

the forName method does not take in account the package of the user call.

share|improve this answer

You need the FQN as per the docs:

Parameters:
   className - the fully qualified name of the desired class.

share|improve this answer

The Java Class class isn't in your package, so it needs to know where the class is located otherwise it doesn't know where it is in order to load it(just like the classloader loads it from a full file path).

so

Class<? extends Object> c = Class.forName("A");

needs to be

Class<? extends Object> c = Class.forName("package.A");

where package is the full qualified name of the package so if the package is

foo.bar

it would become

Class<? extends Object> c = Class.forName("foo.bar.A");
share|improve this answer

As already stated in answers before, needs full name.

To avoid manually typing it you can simply use:

Class<?> clazz = Class.forName(A.class.getName());
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.