user641687
user641687

Reputation:

Java Reflection library - using Class.forName() without package info

I have a project which requires creating Classes dynamically at runtime, where the only information available is the Class name in String form. I'm testing right now with some dead simple Reflection library methods, but my question is, why do I have to provide a fully qualified Class name if the Classes I'm trying to 'dynamically' load are in the same directory? I'm using linux, no development environment, just all the Classes I'm trying to invoke in the same directory with no package declarations whatsoever. Do I have to set up a package system to use Reflection? Here's this little code snippet....

public class ReflectionTest {
    public static void main(String[] args) {
        try {
            Class nodeClass = Class.forName("Node");
            System.out.println(nodeClass.toString());
        } catch (ClassNotFoundException cnfe) {
            System.out.println("Error");
        }
    }
}

Now, this throws the error. But when I create an instance of Node, and then get it's fully qualified Class name with Node.getClass().getName(), I just get "Node" in return. So I don't understand why the Reflection library doesn't work the same as invoking the JVM with 'java', where if no package name is supplied it simply looks in the same directory. I'm not sure how to use this library with user-defined Classes when none of my Classes have an associated package name.

Upvotes: 4

Views: 10223

Answers (5)

Morfic
Morfic

Reputation: 15508

First of all you need to make sure that the classes that you're trying to load are in the classpath, so when launching the jvm try adding the current folder to it: java -cp . ReflectionTest

The concept of packages is to keep your stuff organized and to be able to reuse names. Providing the fully qualified name, ensures that you are using the correct Node class, and for example not org.w3c.dom.Nodeor something similar which would be implicitly shipped with java.

Upvotes: 0

Ben Kunz
Ben Kunz

Reputation: 136

The package name is an integral part of the java naming system. However, if your class does not declare a package, it is in the root package, the code you posted should work.

My guess: the directory is not actually in the CLASSPATH. Try adding the current directory (./) and making sure it is actually the current directory, or include the directory explicitly (absolute path) in your CLASSPATH. Refer to the docs to find out how to set CLASSPATH (environment, jvm options, runtime are your options)

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 691695

There is no concept of a directory for classes in Java. Classes are in a package, or are in the default package, and are loaded from directories or jars that must be in the classpath.

If the directory containing Node.class is in the classpath, the above code should work.

But it's a very very bad practice to use the default package. Every class should be in a package.

Upvotes: 0

pb2q
pb2q

Reputation: 59607

Your code should work as described. That is, if you can call new Node() you should also be able to call Class.forName("Node"). I've just tried this with a package-less class to verify and everything works as expected.

Is Node.class available in the classpath? You may get this to work by adding the current directory to the classpath.

Upvotes: 3

matts
matts

Reputation: 6887

It works for me using the exact ReflectionTest.java above and the following Node.java:

public class Node { }

Did you compile Node.java as well as ReflectionTest.java? Since the ReflectionTest class does not have a compile-time dependency on the Node class, javac won't automatically compile Node.class when it compiles ReflectionTest.class.

Upvotes: 0

Related Questions