When does a dynamically loaded class that references a non-existent classes/methods fail in Java?

早过忘川 提交于 2020-01-14 10:43:28

问题


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?


回答1:


When will it fail?

as soon as C is loaded?

No. Only if when loaded it makes reference to the non existing class ( ie. you have a class attribute of that type )

or when a method that calls a non-existant class/method is run?

Yes. This will be the case.

For instance this runs well.

C:\>more > A.java
class A {}
^C
C:\>more > B.java
class B {
   public void method() {
      A a = new A();
    }
    public void other() {
       System.out.println("Hello there");
    }
    public static void main( String ... args ) {
        B b = new B();
        b.other();
    }
}

C:\>javac A.java B.java

C:\>erase A.class

C:\>java B
Hello there

The class B is loaded by java but since none of the code used method it works well.

As opposed to:

C:\>more > A.java
class A {}

C:\>more > B.java
class B {
   void method() {
      A a = new A();
   }
   public static void main( String ... args ) {
       B b = new B();
       b.method();
   }
}
^C
C:\>javac A.java B.java

C:\>erase A.class

C:\>java B
Exception in thread "main" java.lang.NoClassDefFoundError: A
        at B.method(B.java:3)
        at B.main(B.java:7)
Caused by: java.lang.ClassNotFoundException: A
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 2 more

Fails because B attempted to access A.




回答2:


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.




回答3:


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 method loadClass(name,resolve) which you may use to force resolution at loading time. However its exact behavior isn't well documented.




回答4:


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.



来源:https://stackoverflow.com/questions/4742499/when-does-a-dynamically-loaded-class-that-references-a-non-existent-classes-meth

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!