Suppose I dynamically load a Java class C
, that references non-existent class/methods. Such a case might occur when C
was written for a newer version of Java. When will it fail - as soon as C
is loaded, or when a method that calls a non-existent class/method is run? Does this change with the VM - including other versions of Java, such as Java ME?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
It will fail to load. This can actually be pretty annoying - but of course it's not enough to be careful. The way to work around this is to dynamically load different classes depending on what other definitions you know are available.
No. Only if when loaded it makes reference to the non existing class ( ie. you have a class attribute of that type )
Yes. This will be the case.
For instance this runs well.
The class B is loaded by java but since none of the code used
method
it works well.As opposed to:
Fails because B attempted to access A.
This step is called "resolution", loading other classes referenced by this class.
The language spec allows variation on when this step is performed. It can be done most eagerly, at the beginning of VM, recursively resolving all classess referenced directly and indirectly from the main class. Or it can be done most lazily, resolving a class only when absolutely necessary.
My experience with server JVMs is that it's done as late as possible. So as long as no code referencing the missing classes has been executed, no error is seen.
It also depends on how your load your class.
java.lang.Classloader.loadClass(name)
does not do resolution. However there is a protected methodloadClass(name,resolve)
which you may use to force resolution at loading time. However its exact behavior isn't well documented.On at least regular old Java, I've found that it will fail at the moment where you reference the broken class or method:
Example from my own recent history:
I use a Java editor (written in Java) with a simple plugin system. I had updated the editor, but was using a plugin, compiled with the old version of the editor, that still referenced a class, where for brevity we'll call
Foo
, that was moved out from being an inner class and into a package by itself.When I called the plugin, it did not fail until it tried to create an instance of
Foo
. Since Foo was not in the place the plugin's code said it would be, it threw a NoClassDefFoundError.On a side note, between at least Java versions like Java 1.5 and Java 1.6, you usually don't have to worry about them removing or moving something, since people will scream bloody murder if you mess with an established API.