Reputation: 1004
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.
Upvotes: 3
Views: 1272
Reputation: 28865
There's an overload of Class.forName
which lets you specify whether you want to initialize the class or not (and you don't, if you only want to reflect it a little):
class X {
static { if (true) throw new ExceptionInInitializerError("OH NOES!!!"); }
}
public class Y {
public static void main(String[] args) throws Throwable{
// Breaks:
System.out.println(Class.forName("X").getSuperclass());
// Works:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
System.out.println(Class.forName("X", false, cl).getSuperclass());
}
}
Upvotes: 2
Reputation: 1824
Perhaps you could code generate, compile, and load mock versions of the missing native libraries? Seems like a lot of work though.
Upvotes: 1
Reputation: 11069
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.
Upvotes: 1
Reputation: 20685
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
Upvotes: 3
Reputation: 5470
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.
Upvotes: 0