日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本文介紹了如何在Java 9+中安全地訪問類路徑中所有資源文件的URL?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!

問題描述

我們從Java 9的發(fā)行說明中了解到

應(yīng)用程序類加載器不再是java.net.URLClassLoader的實例(這是以前版本中從未指定的實現(xiàn)細(xì)節(jié))。假定ClassLoader::getSytemClassLoader返回URLClassLoader對象的代碼將需要更新。

這打破了舊代碼,舊代碼按如下方式掃描類路徑:

Java<=8

URL[] ressources = ((URLClassLoader) classLoader).getURLs();

它遇到一個

java.lang.ClassCastException: 
java.base/jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to 
java.base/java.net.URLClassLoader

因此,對于Java 9+,提出了以下解決方法作為PR at the Apache Ignite Project,在給定JVM運行時選項中的調(diào)整后,該方法可以按預(yù)期工作:--add-opens java.base/jdk.internal.loader=ALL-UNNAMED。但是,正如下面的評論中所提到的,此PR從未合并到他們的主分支。

/*
 * Java 9 + Bridge to obtain URLs from classpath...
 */
private static URL[] getURLs(ClassLoader classLoader) {
    URL[] urls = new URL[0];

    try {
        //see https://github.com/apache/ignite/pull/2970
        Class builtinClazzLoader = Class.forName("jdk.internal.loader.BuiltinClassLoader");

        if (builtinClazzLoader != null) {
            Field ucpField = builtinClazzLoader.getDeclaredField("ucp");
            ucpField.setAccessible(true);

            Object ucpObject = ucpField.get(classLoader);
            Class clazz = Class.forName("jdk.internal.loader.URLClassPath");

            if (clazz != null && ucpObject != null) {
                Method getURLs = clazz.getMethod("getURLs");

                if (getURLs != null) {
                    urls = (URL[]) getURLs.invoke(ucpObject);
                }
            }
        }

    } catch (NoSuchMethodException | InvocationTargetException | NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) {
        logger.error("Could not obtain classpath URLs in Java 9+ - Exception was:");
        logger.error(e.getLocalizedMessage(), e);
    }
    return urls;
}

但是,由于在這里使用Reflection,這會導(dǎo)致一些嚴(yán)重的頭痛。這是一種反模式,受到了forbidden-apis maven plugin:

的嚴(yán)厲批評

禁止的方法調(diào)用:java.lang.reflect.AccessibleObject#setAccessible(boolean)[使用反射來解決訪問標(biāo)志在SecurityManager中失敗,并且可能不再適用于JAVA 9中的運行時類]

問題

在OpenJDK 9/10中,是否有安全訪問類/模塊路徑中所有資源的URLs列表的方法,而無需使用sun.misc.*導(dǎo)入(例如,使用Unsafe)?

更新(與評論相關(guān))

我知道,我能做到

 String[] pathElements = System.getProperty("java.class.path").split(System.getProperty("path.separator"));

獲取類路徑中的元素,然后將它們解析為URL。然而,據(jù)我所知,此屬性僅返回應(yīng)用程序啟動時給定的類路徑。然而,在容器環(huán)境中,這將是應(yīng)用程序服務(wù)器的一個,并且可能是不夠的,例如,然后使用EAR包。

更新2

感謝您的所有評論。我將測試System.getProperty("java.class.path")是否可用于我們的目的,如果這能滿足我們的需要,我將更新問題。

然而,似乎其他項目(可能是因為其他原因,例如ApacheTomee 8)遭受了與URLClassLoader相同的痛苦-因此,我認(rèn)為這是一個有價值的問題。

更新3

最后,我們確實切換到classgraph,并將代碼遷移到該庫以解決我們的用例,以便從類路徑加載捆綁為JAR的ML資源。

推薦答案

我認(rèn)為這是an XY problem。訪問類路徑上所有資源的URL在Java中是不受支持的操作,嘗試這樣做也不是一件好事。正如您在這個問題中已經(jīng)看到的,如果您試圖這樣做,您將一直與框架作斗爭。將會有一百萬個邊緣案例破壞您的解決方案(定制類加載器、EE容器等)。

請詳細(xì)說明您為什么要這樣做?

如果您有某種插件系統(tǒng),并且正在尋找可能在運行時提供的與您的代碼交互的模塊,那么您應(yīng)該使用the ServiceLoader API,即:

通過在資源目錄META-INF/services中放置一個提供者配置文件來標(biāo)識打包為類路徑的JAR文件的服務(wù)提供者。提供程序配置文件的名稱是服務(wù)的完全限定二進(jìn)制名稱。提供者配置文件包含服務(wù)提供者的完全限定二進(jìn)制名稱的列表,每行一個。
例如,假設(shè)服務(wù)提供者com.example.impl.StandardCodecs打包在類路徑的JAR文件中。JAR文件將包含一個名為

的提供程序配置文件

META-INF/services/com.example.CodecFactory

包含行:

com.example.impl.StandardCodecs # Standard codecs

這篇關(guān)于如何在Java 9+中安全地訪問類路徑中所有資源文件的URL?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,

分享到:
標(biāo)簽:Java URL 如何在 所有資源 文件 訪問 路徑
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達(dá)人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定