1

I need the same code to work on different servers with different libraries.

So for example serverB contains libraryB. ClassB while serverA doesn't.

To make the code work on both servers I do not import the class explicitly but I declare it only when needed. For example:

If(serverB) {
   libraryB.ClassB foo = new libraryB. ClassB();

   foo.doSomething();
}else{
   whatever();
}

This usually works for me but now I installed my code on new servers and I get a NoClassFoundException. I decompile my class and the library is imported. Why? Can I avoid it?

Thanks

M_M
  • 11
  • 2
  • Can you define interfaces and inject the specific implementation with the correct classes/types depending on if you are on server B or server A? – Progman Oct 07 '21 at 18:03
  • 1
    Imports are just syntactic sugar. Whether you import something out use its fully qualified name, it makes no difference. – Andy Turner Oct 07 '21 at 18:03
  • Are you sure that the "is server B" logic is working correctly? – Andy Turner Oct 07 '21 at 18:16

1 Answers1

0

Importing some class from a package has nothing to do with trying to locate that class at runtime. Whenever the JVM detects that a class like ClassB is needed, it will try to locate and load that class.

The exact specification when this will happen has some complexities, but it makes no difference whether you wrote the fully qualified libraryB.ClassB or the abbreviated ClassB and an import statement. And locating that class will surely happen before the JVM even tries to execute code that contains a reference to the class (like the code snippet you showed us).

Don't be mislead by the decompilation containing an import statement. You can try for yourself and compare two versions of your code, one written with import, and the other with fully qualified classname. The results will be the same. It's just a convenience of the decompiler preferring short classnames, so it always adds the relevant import statements (as long as that doesn't cause name collisions).

It's hard to understand why code like yours ever ran without throwing that error.

Ralf Kleberhoff
  • 6,990
  • 1
  • 13
  • 7
  • Ok thanks a lot. So you saying that it should not be possible to run the code on two machines having different libraries installed, right? – M_M Oct 07 '21 at 19:24
  • Yes. If it's the very same compiled binary class file, I can't understand how this part of code can ever be executed on a machine without the `ClassB` available (even if the execution always takes the `else` path). As a prerequisite to executing a method, the class must have been fully linked by the JVM, and this throws an error if a referenced class is missing. – Ralf Kleberhoff Oct 07 '21 at 19:34
  • I found a similar thread https://stackoverflow.com/questions/34259275/when-is-a-java-class-loaded. Here someone says it may depend on the JVM and on how the class is invoked. – M_M Oct 07 '21 at 22:06