How to load all the jars from a directory dynamica

2019-05-23 00:34发布

Hi I am creating a plugin which requires loading jars dynamically and accessing the classes and methods of these jars. I tried using URLClassLoader and am able to load the classes as shown below

URL myJarFile = new URL("jar","","file:"+jarPath);
URLClassLoader sysLoader =(URLClassLoader)ClassLoader.getSystemClassLoader();
Class sysClass = URLClassLoader.class;
Method sysMethod = sysClass.getDeclaredMethod("addURL", new Class[]{URL.class});
sysMethod.setAccessible(true);
sysMethod.invoke(sysLoader, new Object[]{myJarFile});

But the issue with this is that we have to load classes into classLoader by specifying their name individually. What I want is to load all the classes from all jars in class-path and access them any point of time.

Is it possible with URLClassLoader? If not what are the other options? How much helpful is OSGI in achieving this?

Thanks in advance!

2条回答
姐就是有狂的资本
2楼-- · 2019-05-23 00:55

You need to load your jar first and then load the required class from there.

URL myJarFile = new URL("jar","","file:"+jarPath);
URLClassLoader child = new URLClassLoader (myJarFile , this.getClass().getClassLoader());
Class classToLoad = Class.forName ("com.MyClass", true, child);
Method method = classToLoad.getDeclaredMethod ("myMethod");
Object instance = classToLoad.newInstance ();
Object result = method.invoke (instance);

Then you can get a list of all the classes in the jar file first:

List<String> classNames=new ArrayList<String>();
ZipInputStream zip=new ZipInputStream(new FileInputStream("/path/to/jar/file.jar"));
for(ZipEntry entry=zip.getNextEntry();entry!=null;entry=zip.getNextEntry())
    if(entry.getName().endsWith(".class") && !entry.isDirectory()) {
        StringBuilder className=new StringBuilder();
        for(String part : entry.getName().split("/")) {
            if(className.length() != 0)
                className.append(".");
            className.append(part);
            if(part.endsWith(".class"))
                className.setLength(className.length()-".class".length());
        }
        classNames.add(className.toString());
    }

Once you have list of your classes do the following:

File file = new File("Absolute Path to your jar");  
            URL url = file.toURI().toURL();  
            URL[] urls = {url};  
            ClassLoader loader = new URLClassLoader(urls);  
            Class myClass = loader.loadClass(classNames.get(0));  
            System.out.println("Executing...");  
            Object tester = myClass.newInstance(); 
        System.out.println("Test");
查看更多
女痞
3楼-- · 2019-05-23 00:55

Apache Felix File Install may be exactly what you want. It will monitor a nominated directory and dynamically load any bundles in it. Only packages exported by the bundles will be available to other bundles on the classpath, but all classes will be loaded.

查看更多
登录 后发表回答