views:

175

answers:

4

I'm writing a program that loads all the classes from a specified folder.

Some of the classes are creating objects in static block and these objects in turn are making some native calls during their creation. Since I do not have the native library I'm seeing a java.lang.UnsatisfiedLinkError

Here is a example scenario.

Class A extends SuperA
{
  public static B b = new B(); 
  ...
  ...
}

Class B
{
   public B()
   {
      someNativeCall(); // Causing the LinkError
   }
}

Class.forName("A"); // Loading of Class A

I'm loading the Class A here to check some of its properties like its Super Classes etc. So I don't even care if B is created or not :) Since there can be many classes like A in a given folder, is there a generic way of making sure that loading of classes like A doesn't fail?

Update: I know that native library needs to be present and how it needs to be added. But I don't have the native library and thus am asking for this hack.

+2  A: 

The .DLL or .so that implements the native function needs to be on the system path. The VM will call loadlibrary to load the relevant .dll/.so and if it's not found it will throw an UnsatisfiedLinkError.

You can catch the UnsatisfiedLinkError to ignore the problem but you won't be able to use the classes that depend on it.

If you want to examine the classes but not actually use them, you could use the Java Dissasembeler, javap. You may be able to access the features you need programatically - javap is defined in the package sun.tools.javap and the implementation is in $JDK\lib\tools.jar

Robert Christie
Note it does not "need" to be in the System path , only in the JVM path. See the Java launch flag mentioned above.
whatnick
I don't have the native library with me. Since I don't want to run the application and just need to load a bunch of classes, I'm looking for a hack
Varun
@whatnick Quite correct - you can use either approach - although using java.library.path will be more specific/safe in the presence of multiple versions of the library.
Robert Christie
@Varun - updated answer with some references to the Java Disassembler that may do what you need.
Robert Christie
@cb160 Thanks a lot. Ability to access features of Disassembler pragmatically will provide me the needed solution.
Varun
A: 

Why do you have the class without the native library ? The derived class will not work if the base class cannot be initialized. Use -Djava.library.path to specify location of the native library.

whatnick
Unavailability of the native library is the whole problem here. If available I would have added it :)
Varun
What's the purpose of the native library, maybe it can be substituted with something similar?
Esko
+1  A: 

You'll have to either modify A so that it no longer depends on B, or else modify B so it no longer has the dependency on the native code, or else replace B.

Specifically, you can use a custom ClassLoader and manually load your own version of B that differs from the provided one in that it doesn't have any native dependencies. Then load A in your same ClassLoader and do what you want with it.

Dan
@Dan Very Interesting. Can you please explain a little further.
Varun
+1  A: 

Perhaps you could code generate, compile, and load mock versions of the missing native libraries? Seems like a lot of work though.

erturne