簡體   English   中英

從以字節數組表示的jar文件中加載類的問題

[英]Issue with loading class from jar file represented as byte array

我正在嘗試從加載在字節數組上的jar文件創建類的實例。

我收到兩個參數:
1. byte []代表具有所需類的jar文件
2.合格的班級名稱

當我在本地對其進行測試時,它可以按預期工作,但是當我遠程上載具有相同合格類名的完全相同的jar文件時(使用在Tomcat服務器中部署的Spring MVC實現的Web應用程序(用於后端)和AngularJS實現的前端)找不到所需的課程:

拋出java.lang.ClassNotFoundException

事實證明,當我進行調試時,該類加載器已正確調用,但沒有從jar加載任何類。

如果有人能說出造成這種差異的原因是什么,或者我如何以其他方式實現此功能,我將不勝感激。


一種加載類並返回其實例的方法:

public static <T> T getInstanceOfLoadedClass(byte[] jarFileBytes, String qualifiedClassName) throws ClassFromJarInstantiationException {
    LOGGER.info("Getting instance of class from loaded jar file. Class name: " + qualifiedClassName);
    try {
        return (T) Class.forName(qualifiedClassName, true, new ByteClassLoader(jarFileBytes)).newInstance();
    } catch (InstantiationException | IllegalAccessException | IOException | ClassNotFoundException | NoSuchFieldException e) {
        LOGGER.error("Exception was thrown while reading jar file for " + qualifiedClassName + "class.", e);
        throw new ClassFromJarInstantiationException(e);
    }
}

自定義ByteClassLoader:

public class ByteClassLoader extends ClassLoader {
    private static final Logger LOGGER = Logger.getLogger(ByteClassLoader.class);
    private final byte[] jarBytes;
    private final Set<String> names;

    public ByteClassLoader(byte[] jarBytes) throws IOException {
        this.jarBytes = jarBytes;
        this.names = loadNames(jarBytes);
    }

    private Set<String> loadNames(byte[] jarBytes) throws IOException {
        Set<String> set = new HashSet<>();
        try (ZipInputStream jis = new ZipInputStream(new ByteArrayInputStream(jarBytes))) {
            ZipEntry entry;
            while ((entry = jis.getNextEntry()) != null) {
                set.add(entry.getName());
            }
        }
        return Collections.unmodifiableSet(set);
    }

    @Override
    public InputStream getResourceAsStream(String resourceName) {
        if (!names.contains(resourceName)) {
            return null;
        }
        boolean found = false;
        ZipInputStream zipInputStream = null;
        try {
            zipInputStream = new ZipInputStream(new ByteArrayInputStream(jarBytes));
            ZipEntry entry;
            while ((entry = zipInputStream.getNextEntry()) != null) {
                if (entry.getName().equals(resourceName)) {
                    found = true;
                    return zipInputStream;
                }
            }
        } catch (IOException e) {
            LOGGER.error("ByteClassLoader threw exception while reading jar byte stream for resource: "+resourceName, e);
            e.printStackTrace();
        } finally {
            if (zipInputStream != null && !found) {
                try {
                    zipInputStream.close();
                } catch (IOException e) {
                    LOGGER.error("ByteClassLoader threw exception while closing jar byte stream for resource: "+resourceName, e);
                    e.printStackTrace();
                }
            }
        }
        return null;
    } }

問題在於,在測試該類時,需要加載的類在一個類加載器中。
希望它可以幫助某人解決此問題,因為它很容易遺漏。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM