【问题标题】:Add a .jar file in classpath with Java使用 Java 在类路径中添加 .jar 文件
【发布时间】:2012-12-24 18:53:07
【问题描述】:

我正在尝试用 Java 开发一个脚本,该脚本在指定目录中查找所有 .jar 文件,然后将它们查找到 classpath 并在某些条件下调用它们的 main() 方法。这是我的 Java 信息​​:

java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.5) (6b24-1.11.5-0ubuntu1~12.04.1)
OpenJDK Server VM (build 20.0-b12, mixed mode)

这是当前工作目录的ls

clojure.jar 
loader.class
loader.java 

我正在执行以下操作,以便将 clojure.jar 添加到 classpath 并调用其 main 方法:

import java.io.File;

import java.net.URL;
import java.net.URLClassLoader;
import java.net.MalformedURLException;

import java.lang.reflect.Method;

public final class loader {

  public static void main (String[] args) {
    try {
      printClasspathString();
      System.out.println ("**********");
      URL[] classesRepo = { new File("clojure.jar").toURI ().toURL (),
                            new File(System.getProperty("user.dir")).toURI ().toURL ()};
      ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
      URLClassLoader urlClassLoader = new URLClassLoader( classesRepo, currentThreadClassLoader);
      Thread.currentThread().setContextClassLoader(urlClassLoader);
      printClasspathString();
    } catch (Exception ex) {
      System.out.println(ex.getMessage ());
    }

    //Do I miss something here?

    String mainClassName="clojure.main";

    Class<?> mainClass = null;
    try {
      mainClass = Class.forName(mainClassName);
    }
    catch (Exception ex) {
      throw new IllegalArgumentException("class not found in your jar file " + mainClassName);
    }

    Method mainMethod = null;
    try {
      mainMethod = mainClass.getMethod("main", String[].class);
    }
    catch (Exception ex) {
      throw new IllegalArgumentException("class to launch (" + mainClassName + ") does not have a public static void main(String[]) method");
    }

    try {
      mainMethod.invoke(null, (Object) args);
    } catch (Exception ex) {
      System.out.println(ex.getMessage ());
    }

  }

  public static void printClasspathString() {
    ClassLoader applicationClassLoader = Thread.currentThread().getContextClassLoader();
    if (applicationClassLoader == null) {
      applicationClassLoader = ClassLoader.getSystemClassLoader();
    }
    URL[] urls = ((URLClassLoader)applicationClassLoader).getURLs();
    for(int i=0; i < urls.length; i++) {
      System.out.println (urls[i].getFile());
    }
  }

}

不幸的是,加载器没有按预期工作:

$ java -cp . loader
/home/proofit404/data/downloads/clojure-loader/
**********
/home/proofit404/data/downloads/clojure-loader/clojure.jar
/home/proofit404/data/downloads/clojure-loader/
Exception in thread "main" java.lang.IllegalArgumentException: class not found in your jar file clojure.main
    at loader.main(loader.java:37)

不过,如果我使用 -cp 选项,一切正常:

$ java -cp .:clojure.jar loader
/home/proofit404/data/downloads/clojure-loader/
/home/proofit404/data/downloads/clojure-loader/clojure.jar
**********
/home/proofit404/data/downloads/clojure-loader/clojure.jar
/home/proofit404/data/downloads/clojure-loader/
Clojure 1.4.0
user=> (System/exit 0)

那么 - 我需要对我的代码进行哪些更改才能使其按预期工作?

【问题讨论】:

  • 您需要一个自定义类加载器 - link

标签: java


【解决方案1】:

我认为问题在于Class.forName(String)方法没有使用线程contextclassloader,而是当前类的classloader:

public static Class<?> forName(String className)
                    throws ClassNotFoundException

Returns the Class object associated with the class or interface with the given string name. Invoking this method is equivalent to:

    Class.forName(className, true, currentLoader)

where currentLoader denotes the defining class loader of the current class.

这意味着您的 URLClassLoader 不会被使用。尝试使用 Class.forName(String,boolean, ClassLoader) 显式传递类加载器:

mainClass = Class.forName(mainClassName, true, urlClassLoader);

【讨论】:

    【解决方案2】:

    试试这个代码并遵循下面给出的 cmets:

    import java.net.URL;
    import java.io.IOException;
    import java.net.URLClassLoader;
    import java.net.MalformedURLException;
    
    public class JarLoader extends URLClassLoader {
        public JarLoader(URL[] urls) {
            super(urls);
        }
    
        public void addFile(String path) throws MalformedURLException {
            String urlPath = "jar:file://" + path + "!/";
            addURL(new URL(urlPath));
        }
    
        public static void main(String args[]) {
            try {
                System.out.println("First attempt...");
                Class.forName("org.gjt.mm.mysql.Driver");
                //specify your class name above
            } catch (Exception ex) {
                System.out.println("Failed.");
            }
    
            try {
                URL urls[] = {};
    
                JarLoader cl = new JarLoader(urls);
                cl
                        .addFile("/opt/mysql-connector-java-5.0.4/mysql-connector-java-5.0.4-bin.jar");
                // give your jar file above.
                System.out.println("Second attempt...");
                cl.loadClass("org.gjt.mm.mysql.Driver");
                //specify your class name above
                System.out.println("Success!");
            } catch (Exception ex) {
                System.out.println("Failed.");
                ex.printStackTrace();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-29
      • 1970-01-01
      • 2016-08-31
      • 2014-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多