2017-01-23 77 views
1

我有一个maven项目,它依赖于版本为“2.0”的jar“sample”。 版本“2.0”的“样本”jar包含一个名为“SampleEnum”的Enum。 的SampleEnum在“2.0”版本看起来如下如何在java maven项目中从两个不同版本的jar中加载两个版本的类?

public enum SampleEnum { 
    "HERBIVORES", 
    "CARNIVORES", 
    "OMNIVORES" 
} 

我想从在上面提到的行家java项目的版本“1.0”“样品”罐子加载“SampleEnum”级。 “1.0”版本的SampleEnum类看起来如下所示。

public enum SampleEnum { 
    "HERBIVORES", 
    "CARNIVORES" 
} 

我用下面的代码加载类:

public class Test 
{ 
    public static void main(String args[]) { 
     try { 
      URLClassLoader loader1 = new URLClassLoader(new URL[] {new File("sample-1.0.jar").toURL()}, Thread.currentThread().getContextClassLoader()); 

      Class<?> c1 = loader1.loadClass("SampleEnum"); 

      for (Object o : c1.getEnumConstants()) { 
       System.out.println(o); 
      } 
     } 
     catch(Exception ex) 
     { 
      System.err.println(ex.getMessage()); 
     } 
    } 
} 

上述程序的实际输出是:

食草动物 食肉动物 杂食性

正如我已加载来自“sample-1.0”jar的类我期望以下输出:

HERBIVORES CARNIVORES

我可以知道它为什么从相关jar而不是指定jar加载类的原因吗?

是否有任何方式来加载maven项目中的版本1.0 jar中的枚举类?

回答

1

它从从属jar加载类的原因是因为loader1类加载器获取当前Thread的上下文类加载器作为其父类加载器,并且该类加载器从相关jar加载类。公共ClassLoader.loadClass(String)方法调用受保护的ClassLoader.loadClass(String, boolean)方法,并记录该方法以解释父类加载器始终首先被搜索。当然,您可以通过继承URLClassLoader并覆盖loadClass(String, boolean)方法来覆盖此行为。

从样品-1.0.jar org.sample.SampleEnum

public enum SampleEnum 
{ 
    HERBIVORES, 
    CARNIVORES 
} 

org.sample.SampleEnum从样品-2.0.jar

public enum SampleEnum 
{ 
    HERBIVORES, 
    CARNIVORES, 
    OMNIVORES 
} 

Main.java

package com.example.app; 

import org.sample.SampleEnum; 
import java.io.File; 
import java.net.URL; 
import java.net.URLClassLoader; 

import static java.util.Arrays.asList; 

public class Main 
{ 
    public static void main(String[] args) 
    { 
     System.out.println("v2.0: " + asList(SampleEnum.values())); 
     try { 
      URLClassLoader loader1 = new CustomURLClassLoader(
        new URL[] { new File("../sample-1.0/target/sample-1.0.jar").toURL() }); 

      Class<?> c1 = loader1.loadClass("org.sample.SampleEnum"); 

      System.out.println("v1.0: " + asList(c1.getEnumConstants())); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 
} 

class CustomURLClassLoader extends URLClassLoader 
{ 
    public CustomURLClassLoader(URL[] urls) 
    { 
     super(urls); 
    } 

    protected Class<?> loadClass(String name, boolean resolve) 
      throws ClassNotFoundException 
    { 
     synchronized (getClassLoadingLock(name)) { 
      // First, check if the class has already been loaded 
      Class<?> c = findLoadedClass(name); 
      if (c == null) { 
       long t0 = System.nanoTime(); 

       // First, look in the current ClassLoader 
       long t1 = System.nanoTime(); 
       try { 
        c = findClass(name); 
       } catch (ClassNotFoundException ex) { 
        // ClassNotFoundException thrown if class not found 
       } 

       // this is the defining class loader; record the stats 
       sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); 
       sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); 
       sun.misc.PerfCounter.getFindClasses().increment(); 

       // Lastly, look in the parent ClassLoader 
       try { 
        if (getParent() != null) { 
         c = super.loadClass(name, resolve); 
        } 
       } catch (ClassNotFoundException e) { 
        // ClassNotFoundException thrown if class not found 
        // from the non-null parent class loader 
       } 

      } 
      if (resolve) { 
       resolveClass(c); 
      } 
      return c; 
     } 
    } 
} 

输出:

$ java -cp sample-app-2.0.jar:sample-2.0.jar com.example.app.Main 
v2.0: [HERBIVORES, CARNIVORES, OMNIVORES] 
v1.0: [HERBIVORES, CARNIVORES] 

欲了解更多信息,请参阅https://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#loadClass(java.lang.String,%20boolean)

+0

使用上面的代码,我得到了以下异常。线程“main”中的异常java.lang.NoClassDefFoundError:java/lang/Object – user3351074

+0

引起来自:java.lang.ClassNotFoundException:java.lang.Object \t at java.net.URLClassLoader.findClass(URLClassLoader.java:381) \t at CustomURLClassLoader.loadClass(CustomURLClassLoader.java:22) \t at java.lang.ClassLoader.loadClass(ClassLoader。java:357) – user3351074

+0

我在代码中看不到那个错误。我已更新我的示例,以显示我正在运行的内容。 –

相关问题