Class.forName("FQN") throws ClassNotFoundException Intermittently - java

I have a Java based RMI Server in which one of the interface method is like this :
public Properties process(String operation, Properties params) {
Class nodecls = Class.forName("com.example.commands." + operation);
}
This method runs fine all the time but sometimes (say once in a million RMI calls) throws ClassNotFoundException. What could be the reason for this? I am sure that the name passed is correct.

From XYZWS - What does Class forname method do?:
A call to Class.forName("X") causes the class named X to be dynamically loaded (at runtime). A call to forName("X") causes the class named X to be initialized (i.e., JVM executes all its static block after class loading). Class.forName("X") returns the Class object associated with the "X" class. The returned Class object is not an instance of the "x" class itself.
Class.forName("X") loads the class if it not already loaded. The JVM keeps track of all the classes that have been previously loaded. This method uses the classloader of the class that invokes it. The "X" is the fully qualified name of the desired class.
The tag wiki for classnotfoundexception has a simpler description:
The Java exception thrown when an application tries to load a class by name. Usually raised by one of:
the forName method in class Class [...]
when no definition for the class with the specified name could be found in the classpath.
Therefore, there can only be two causes for this:
The class named "com.example.commands." + operation is not present on the Class Path.
The ClassLoader of the Class which your method is in cannot find the "com.example.commands." + operation class. Maybe some reflection trick broke it.
However, you should never have to bother with this, as your method wouldn't even compile - it's of a non-void return type, while you never included a proper return statement.

Related

How to understand "Every Class object contains a reference to the ClassLoader that defined it. "?

I know I can get a the classloader of a class by
xxxclass.class.getClassLoader(), but where exactly does the xxxclass
hold the reference of its classloader who defines it?
e.g.
public class ClassA {
System.out.println("I am class A");
}
I don't see any clue of the classloader reference in ClassA. However,
I can get the classloader of ClassA by using
ClassA.class.getClassLoader().
How does ClassA.class.getClassLoader() work?
The sentence as it appears in the documentation of ClassLoader is:
Every Class object contains a reference to the ClassLoader that defined it.
Note the two links? What they tell you is that the documentation refers to the Class object, not to the plain object of class ClassA.
Every class that you define in Java has a Class object associated with it, which allows you to look at that class in the meta level. That is, treat the class itself as an object, pass it as parameter, use reflection on it etc.
As you have noticed, one way to access the Class object is use ClassA.class. If you have a reference to an object of type ClassA:
ClassA myObj = new ClassA();
Then you can get the Class object using myObj.getClass().
So there is no reference to the ClassLoader in the myObj object, Only in its associated Class object.
Now, the other link tells you how to get the reference to the ClassLoader object once you have a Class object - through the getClassLoader() method.
Now, if you look at the source code of the Class class, you will see:
#CallerSensitive
public ClassLoader getClassLoader() {
ClassLoader cl = getClassLoader0();
if (cl == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
}
return cl;
}
So it calls getClassLoader0() to get the class loader. Its source is:
native ClassLoader getClassLoader0();
That is, the class loader reference is actually part of the native structure of this Java class, and it is not available to see using Java language tools. Nevertheless, it exists there, and available to you through the aforesaid method.
If you write this:
public class Ball {
private Person thrower;
public Ball(Person thrower) {
this.thrower = thrower;
}
public Person getThrower() {return thrower;}
}
then every Ball object contains a reference to the Person that threw it, right?
Similarly, the Class class has something like this: (although I'm not showing how classLoader gets assigned)
public class Class {
... other stuff ...
private ClassLoader classLoader;
public ClassLoader getClassLoader() {return classLoader;}
... other stuff ...
}
and so every Class object has a reference to the ClassLoader that loaded it.
In your example, ClassA is not a Class object, so the statement doesn't apply to it. It does apply to ClassA.class which is a Class object (or refers to one at least).
In fact, it's not so simple in this case.
(Or at least, it was not so simple, until a recent update)
Java is a very high-level language, and the JVM is a rather complex beast, which is (fortunately!) hiding many details that you don't want to be concerned with when using a high-level, object-oriented language.
As already pointed out in the other answers, the Class#getClassLoader() method delegates to a private native method getClassLoader0(). Usually, you simply don't know (and should not have to care about) what a private native method does.
But thanks to the open source JDK, one can trace the path of this method call (here, for a recent version of the JDK8) :
The native getClassLoader0 method of Class is bound to JVM_GetClassLoader
The JVM_GetClassLoader method eventually calls Klass::class_loader()
The Klass::class_loader() method only returns the result of ClassLoaderData::class_loader()
The ClassLoaderData::class_loader() method finally returns the field that you are looking for
However, note that this has changed in a recent commit of the JDK9: Now, the ClassLoader is stored as a private instance field in the Class class, in order to improve performance.
If you look at the source code of java.lang.Class it appears that it delegates to a native method called getClassLoader0. So the implementation details are down to the JVM.
I'm no expert on this, but I suppose this might allow garbage collection to work by not having reference cycles in Java.

Difference static behaviour between MyClass.class and Class.forName(“MyClass”)

I'm not sure what's the difference of loading static variables/blocks between MyClass.class and Class.forName("MyClass"), for example, I have below class:
package test;
public class SampleClass{
public static SampleClass instance = new SampleClass();
private SampleClass(){
System.out.println("SampleClass Instance Created");
}
}
Then, in another class, I accessed the class object of above SampleClass by using:
System.out.println(SampleClass.class);
Then, the output will be:
class test.SampleClass
If I changed to use class.forName(), as below:
System.out.println(Class.forName("test.SampleClass"));
Then, the output will be:
SampleClass Instance Created
class test.SampleClass
Does anybody can give me an explanation?
Thanks a lot.
The call to the Class.forName("MyClass") causes the class to be loaded at runtime. JVM also initializes that class after the class has been loaded by the classloader, so static blocks get executed.
In your case you have a static field which is the instance of your class, as this static block get executed your object is being initialized. That's why you are seeing the System.out get printed.
The .class syntax is used to get the Class of the called class. It doesn't not load the class actually.
Reference:
What does Class.forname method do?
Java Doc
Retrieving Class Object
Class.forName() uses the ClassLoader and tries to resolve class name at runtime, while .class is resolved at compile time.
class.forName() loads the class using the "caller's" class loader if the class is not already loaded.
.class doesn't load the class.
Its is just because of Class.forName() is dynamically loaded at run time your class into memory(RAM). and it will execute all static block within this class without creating reference of that class,
From offical doc:
A call to Class.forName("X") causes the class named X to be dynamically loaded (at runtime). A call to forName("X") causes the class named X to be initialized (i.e., JVM executes all its static block after class loading). Class.forName("X") returns the Class object associated with the "X" class. The returned Class object is not an instance of the "x" class itself.
Class.forName("X") loads the class if it not already loaded. The JVM
keeps track of all the classes that have been previously loaded. This
method uses the classloader of the class that invokes it. The "X" is
the fully qualified name of the desired class.
here is more information about it: http://www.xyzws.com/Javafaq/what-does-classforname-method-do/17
Thank you all above for your answers and discussions.
I thought the class will be loaded no matter using Class.forName() or MyClass.class, obviously I'm wrong. But I don't understand why it doesn't load the class when using MyClass.class.

JNI RegisterNatives does not work on class loaded by ClassLoader.loadClass()

I am embedding a JVM in an existing C++ application and need to register implementation of native Java functions with a class.
Consider this simple class with native functions:
class Native {
static {
System.out.println("Class 'Native' static initializer called.");
}
public native int f(int i);
}
Inside the JVM I am running OSGi which is the reason I need to get the classes using Java code (using the correct class loader) instead of loading them from JNI. However, to keep this example simple, I have left out OSGi.
I have these four different Java methods for getting a jclass value in C++:
class Bridge {
public Class<?> getNativeClass1() throws ClassNotFoundException {
return getClass().getClassLoader().loadClass("org.example.Native");
}
public Class<?> getNativeClass2() throws ClassNotFoundException {
return Class.forName("org.example.Native", false, getClass().getClassLoader());
}
public Class<?> getNativeClass3() throws ClassNotFoundException {
final Class<?> clazz = getClass().getClassLoader()
.loadClass("org.example.Native");
clazz.getMethods();
return clazz;
}
public Class<?> getNativeClass4() throws ClassNotFoundException {
return Class.forName("org.example.Native", true, getClass().getClassLoader());
}
}
To register the native function implementation in C++ for Native.f() I call:
JNIEnv* env = ...
jclass clazz = ...; // Calling one of the four methods above.
JNINativeMethod nativeMethod = {
(char*) "f", // Method name 'f'.
(char*) "(I)I;", // Signature 'int --> int'.
(void*) f // Pointer to C++ implementation of function.
};
env->RegisterNatives(clazz, &nativeMethod, 1);
Depending on which method I use for getting the Class<?> instance, I get different results:
getNativeClass1(): The static initializer is not executed in class Native when loading the class (but of course when creating an instance of the class) and the native implementation is not bound correctly. (Calling the native function in Java gives incorrect results or crashes the JVM.)
getNativeClass2(): Same as above.
getNativeClass3(): The static initializer is still not called in class Native when the class is loaded but the native implementation is bound correctly and I can call f() successfully.
getNativeClass3(): The static initializer is called in class Native when the class is loaded and the native implementation is bound correctly.
So it seems that ClassLoader.loadClass() loads the class in a way so it is not properly initialized and JNIEnv::RegisterNatives() will not work properly. However, calling Class.getMethods() will somehow initalize the class (without invoking the static initializer) so that binding the native methods works.
On the other hand, Class.forName(clazz, false, classLoader) seems to work exactly like Class.loadClass() returning an uninitialized Class instance.
Can anybody explain the difference between
an uninitialized class like the one returned by getNativeClass1() and getNativeClass2()
a partially initialized class like the one returned by getNativeClass3()
a fully initialized class like the one returned by getNativeClass4()
and what is the most portable way to load a class before calling JNIEnv::RegisterNatives()?
So it seems that ClassLoader.loadClass() loads the class in a way so it is not properly initialized
According to the documentation:
loadClass(String): "Invoking this method is equivalent to invoking loadClass(name, false)."
loadClass(String,boolean) (emphasis added): "If the class was found using the above steps, and the resolve flag is true, this method will then invoke the resolveClass(Class) method on the resulting Class object"
Those two methods are intended for internal use by classloaders that need to do something between loading and linking. I'm not sure why loadClass(String) is marked public, but it arguably shouldn't be.
and what is the most portable way to load a class before calling
Class.forName(), which uses the context classloader and ensures that the class is ready for use.

When exactly is NoClassDefFoundError thrown?

How do runtime dependencies in Java work exactly. For example, is code like this possible if Impl1 or Impl2 are not in the classpath at runtime:
Thinger t;
if (classIsAvailable(Impl1.class)) t = new Impl1();
else t = new Impl2();
t.doThing();
Or if there is no common interface:
if (classIsAvailable(Impl1.class)) Impl1.doThingThisWay();
else Impl2.doThingTheOtherWay();
You can't do it exactly like this, because in order to evaluate Impl1.class, said class must be available (i.e. loaded). You can however try to load a specific class by its name
Class aClass = classLoader.forName("Impl1");
If this does not fail (throw an Exception) you can create an instance of this class using newInstance().
Of course, in order to be able to use your class, you have to make sure it implements an Interface, which is known at compile time. In this case you can cast your created object to that interface type and continue using it.
This article has some sample code.
ClassNotFoundException is thrown when
an application tries to load in a class through its string name using:
* The forName method in class Class.
* The findSystemClass method in class ClassLoader .
* The loadClass method in class ClassLoader.
but no definition for the class with the specified name could be found.
You may also find http://www.xyzws.com/javafaq/what-does-classforname-method-do/17 useful.
HTH
Your example would fail with a NoClassDefFoundError when your class is loaded with either Impl1 or Impl2 not in the classpath, so none of the code would execute in that case.

How does Class.forName() work?

I just learned about java.sql package. It uses Class.forName() to dynamically load the driver which extends DriverManager.
Then we get connection using DriverManager.getConnection() method.
So how does the entire thing work?
How does DriverManager class know how to get the connection without using class name of the actual driver.
Also can we use Class.forName() for custom applications... if this is explained with an example I will be very happy.
Class.forName simply loads a class, including running its static initializers, like this:
class Foo {
static {
System.out.println("Foo initializing");
}
}
public class Test {
public static void main(String [] args) throws Exception {
Class.forName("Foo");
}
}
All the rest of the procedure you're talking about is JDBC-specific. The driver - which implements Driver, it doesn't extend DriverManager - simply registers an appropriate instance using DriverManager.registerDriver. Then when DriverManager needs to find a driver for a particular connection string, it calls connect on each registered driver in turn until one succeeds and returns a non-null connection.
Note that this way of registering drivers is reasonably old-fashioned - look at the docs for DriverManager for more modern ways of getting at a data source.
When we create an instace of a class using new operator, it does two things
Load the class in to memory, if it is not loaded -
which means creating in-memory representation of the class from the .class file so that an instance can be created out of it. This includes initializing static variables (resolving of that class)
create an instance of that class and store the reference to the variable.
Class.forName does only the first thing.
It loads the class in to memory and return that reference as an instance of Class. If we want to create an instance then, we can call newInstance method of that class. which will invoke the default constructor (no argument constructor).
Note that if the default constructor is not accessible, then newInstance method will throw an IllegalAccessException. and if the class is an abstract class or interface or it does not have a default constructor, then it will throw an InstantiationException. If any exception araises during resolving of that class, it will throw an ExceptionInInitializerError.
If the default constructor is not defined, then we have to invoke the defiend constructor using reflection API.
But the main advantage with Class.forName is, it can accept the class name as a String argument. So we can pass the class name dynamically. But if we create an instance of a class using new operator, the class name can't be changed dynamically.
Class.forName() inturn will call loadClass method of the caller ClassLoader (ClassLoder of the class from where Class.forName is invoked).
By default, the Class.forName() resolve that class. which means, initialize all static variables inside that class.
same can be changed using the overloaded method of Class.forName(String name,boolean initialize,ClassLoader loader)
The main reason for loading jdbc driver using Class.forName() is, the driver can change dynamically.
in the static block all Drivers will create an instance of itself and register that class with DriverManager using DriverManager.registerDriver() method. Since the Class.forName(String className) by default resolve the class, it will initialize the static initializer.
So when we call Class.forName("com.sun.jdbc.odbc.JdbcOdbcDriver"),
the Driver class will be loaded, instanciated and registers with DriverManager
So if you are using new Operator you have to do the following things.
Code:
Driver drv = new com.sun.jdbc.odbc.JdbcOdbcDriver();
DriverManager.registerDriver(drv);
Class.forName(..) loads and initializes the target class. This in turn means that the static initializer blocks are invoked (code defined in static { .. }.
If you look at, for example, MySQL's driver, in that static block the driver is registering itself: DriverManager.registerDriver(new Driver());
You can omit the Class.forName(..) and register the driver yourself if you can "afford" the compile-time dependency on MySQL's driver.
That said, it will rarely be relevant to use Class.forName(..) to initialize classes from your application, because compile-time dependency is not an issue there.
Also note that Class.forName(..) is no longer required for JDBC since version 4. By using the service provider mechanism you can instruct the driver manager what to load by a system property.
The reason why Class.forName() is frequently mentioned in SQL examples, is because there was no magic to tell the JDBC DriverManager how to map the JDBC URL provided to a real driver.
E.g. "mysql" should map to a given MySQL class, "thin" maps to the Oracle class, "as400" maps to the DB2/400 class.
By explicitly loading the class, this allowed the code within the class registering itself with the DriverManager to be run.
These days the magic hooks are present allowing the JVM to autodiscover the drivers (if new enough) so the call is superfluous, but out of habit many still use it.

Categories

Resources