1

I'm trying to find a way to dynamically load a platform dependent library jar for the current OS. I need to access a third party library that uses JNI calls, and has different jars for Mac and Windows. All of the calls and returns for the two libraries are identical, and simply swapping out the jar file in the lib dir after compiling works, but I would like my app to be able to determine which jar should be loaded at runtime.

I have found similar posts on here, but nothing that addresses this question directly. this post shows how to dynamically load jars via the ClassLoader, but from what I gather this means I would have to use the Method method = clazz.getDeclaredMethod("methodName"), method.invoke() approach to call any methods provided by that class, as well as explicitly call out each class to be loaded to the class loader (which I would very much like to avoid).

I'm hoping to find a solution that looks something like:

import external.lib.namespace.LibClassA;
import external.lib.namespace.LibClassB;

public class MyClass {
    static {
        if (System.getProperty("os.name").contains("Windows") {
            ClassLoader.getSystemClassLoader().load("Lib_win.jar");
        } else {
            ClassLoader.getSystemClassLoader().load("Lib_mac.jar");
        }
    }

    public static void Main(String[] args) {
        LibClassA.platformDependantCall();
        LibClassB.someOtherCall();
    }
}
Community
  • 1
  • 1
IgnisFatuus
  • 1,998
  • 1
  • 12
  • 8
  • What happens if both jars are in the classpath? – Mark Robinson Mar 08 '12 at 00:22
  • @MarkRobinson - I'm no expert on how the Java ClassLoader works, but in my experience, if a jar contains classes that have the same namespace and name as those form another jar or the Java APIs, the ClassLoader arbitrarily decides which to load. There is probably some method used to decide which to load, but this doesn't help in this situation regardless. If I'm wrong about this and someone would like to explain further, please do. Thanks. – IgnisFatuus Apr 06 '12 at 19:50

2 Answers2

0
System.getProperty("os.name") 

cannot be used to get the information about OS everytime. It will fail with SecurityException exception if the user invoking JVM does not have required security permissions.

pabitra mohan
  • 77
  • 1
  • 5
0

The post that you refer to has an answer about the JCL ClassLoader framework - see https://stackoverflow.com/a/1450837/982341

If you look at the documentation for that framework, you'll see that it supports creating instances of the loaded classes, and provides methods for casting them to proper objects, so that you don't have to use reflection.

Community
  • 1
  • 1
GreyBeardedGeek
  • 29,460
  • 2
  • 47
  • 67
  • Thanks for pointing out that response GreyBeardedGeek. I missed that one. I'll look into the JCL framework and see if it can do what I'm hoping. – IgnisFatuus Apr 06 '12 at 19:46
  • My real goal here is to be able to dynamically decide which jar to load at runtime without having to change the code I've already written that uses the classes provided by this library. This means: 1. Solution cannot use reflection 2. (implied by 1) The class definitions need to be available at compile time. I'm gathering that the real answer here is "It can't be done"? – IgnisFatuus Apr 06 '12 at 20:28
  • It looks like the casting capabilities provided by the JCL framework only allow for casting to a known class or interface, not the actual class loaded from the library, so it doesn't seem that this would help me. Am I wrong? – IgnisFatuus Apr 06 '12 at 20:30