首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在java maven项目中从两个不同版本的jar中加载一个类的两个版本?

如何在java maven项目中从两个不同版本的jar中加载一个类的两个版本?
EN

Stack Overflow用户
提问于 2017-01-24 03:48:07
回答 1查看 88关注 0票数 0

我有一个maven项目,它依赖于版本为"2.0“的jar”样本“。版本为"2.0“的”示例“jar包含一个名为"SampleEnum”的枚举。2.0版本的SampleEnum如下所示

代码语言:javascript
复制
public enum SampleEnum {
    "HERBIVORES",
    "CARNIVORES",
    "OMNIVORES"
}

我想从上面提到的maven java项目的"1.0“版本的"sample”jar中加载"SampleEnum“类。"1.0“版本中的SampleEnum类如下所示。

代码语言:javascript
复制
public enum SampleEnum {
    "HERBIVORES",
    "CARNIVORES"
}

我使用下面的代码来加载这个类:

代码语言:javascript
复制
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加载了类,所以我期望得到以下输出:

食草动物肉食动物

我可以知道为什么它从依赖的jar而不是指定的jar加载类吗?

有没有办法在maven项目中从1.0版jar中加载枚举类?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-24 04:26:38

之所以从依赖jar加载类,是因为loader1类加载器将当前线程的上下文类加载器作为其父类加载器,并且该类加载器从依赖jar加载类。公共ClassLoader.loadClass(String)方法调用受保护的ClassLoader.loadClass(String, boolean)方法,文档中记录了该方法,以说明始终首先搜索父类加载器。当然,您可以通过继承URLClassLoader子类并覆盖loadClass(String, boolean)方法来覆盖此行为。

来自org.sample.SampleEnum -1.0.jar的示例

代码语言:javascript
复制
public enum SampleEnum
{
    HERBIVORES,
    CARNIVORES
}

来自org.sample.SampleEnum -2.0.jar的示例

代码语言:javascript
复制
public enum SampleEnum
{
    HERBIVORES,
    CARNIVORES,
    OMNIVORES
}

Main.java

代码语言:javascript
复制
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;
        }
    }
}

输出:

代码语言:javascript
复制
$ 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)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41814398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档