Load jar dynamically at runtime?

前端 未结 2 457
闹比i
闹比i 2021-01-05 08:59

My current java project is using methods and variables from another project (same package). Right now the other project\'s jar has to be in the classpath to work correctly.

相关标签:
2条回答
  • 2021-01-05 09:30

    I needed to load a jar file at runtime for both java 8 and java 9+. Here is the method to do it (using Spring Boot 1.5.2 if it may relate).

    public static synchronized void loadLibrary(java.io.File jar) {
        try {            
            java.net.URL url = jar.toURI().toURL();
            java.lang.reflect.Method method = java.net.URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{java.net.URL.class});
            method.setAccessible(true); /*promote the method to public access*/
            method.invoke(Thread.currentThread().getContextClassLoader(), new Object[]{url});
        } catch (Exception ex) {
            throw new RuntimeException("Cannot load library from jar file '" + jar.getAbsolutePath() + "'. Reason: " + ex.getMessage());
        }
    }
    
    0 讨论(0)
  • 2021-01-05 09:32

    Indeed this is occasionally necessary. This is how I do this in production. It uses reflection to circumvent the encapsulation of addURL in the system class loader.

    /*
         * Adds the supplied Java Archive library to java.class.path. This is benign
         * if the library is already loaded.
         */
        public static synchronized void loadLibrary(java.io.File jar) throws MyException
        {
            try {
                /*We are using reflection here to circumvent encapsulation; addURL is not public*/
                java.net.URLClassLoader loader = (java.net.URLClassLoader)ClassLoader.getSystemClassLoader();
                java.net.URL url = jar.toURI().toURL();
                /*Disallow if already loaded*/
                for (java.net.URL it : java.util.Arrays.asList(loader.getURLs())){
                    if (it.equals(url)){
                        return;
                    }
                }
                java.lang.reflect.Method method = java.net.URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{java.net.URL.class});
                method.setAccessible(true); /*promote the method to public access*/
                method.invoke(loader, new Object[]{url});
            } catch (final java.lang.NoSuchMethodException | 
                java.lang.IllegalAccessException | 
                java.net.MalformedURLException | 
                java.lang.reflect.InvocationTargetException e){
                throw new MyException(e);
            }
        }
    
    0 讨论(0)
提交回复
热议问题