2017-07-20 18 views
2

我创建了一个maven项目L并编写了一个Java extension (i.e. an optional package)实现(即扩展)实现(即扩展)LocaleServiceProvider的(抽象)服务提供者,以支持通常不支持的方言(我们称之为xy) JRE。 (我做希望使用与Java 8传来CLDR扩展,即使我运行8.141)。为什么Java扩展机制不检查实现LocaleServiceProvider的可选包的类路径?

该项目编译,并产生一个jar与包含provider-一个META-INF/services文件夹UTF-8中的配置文件与合格的提供程序类名称位于以换行符结尾的行上(\n)。

我也随后宣布在我的语言环境项目L项目P一个maven的依赖,我认为,将工作,因为教程states

扩展架构利用了类加载代表团 机制。当运行时环境需要加载新的类 的应用程序,它看起来为在以下位置的类,在 顺序:

[...]

  • 类路径:类,包括JAR文件中的类,由系统属性java.class.path指定的路径上的 。如果类路径中的JAR 文件具有带Class-Path属性的清单,则还将搜索由Class-Path属性指定的 JAR文件。 默认情况下,java.class.path属性的值是,当前的 目录。您可以使用-classpath或-cp 命令行选项或设置CLASSPATH环境变量来更改该值。 命令行选项将覆盖环境变量CLASSPATH 的设置。
  • 的Maven把在类路径中的所有依赖,我相信。

    然而,当我在P运行我的单元测试(在的IntelliJ; L是在classpath),它失败:

    @Test 
    public void xyLocalePresent() { 
        Locale xy = new Locale("xy"); 
        assertEquals("P not on classpath", xy, com.example.l.Locales.XY); // access constant in my Locale project L; should be equals to locale defined here 
        SimpleDateFormat df = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, xy); 
        assertEquals("dd/MM/yy", df.toPattern()); // fails; L specifies the short date pattern as dd/MM/yy 
    } 
    

    我必须与-Djava.locale.providers=SPI,JRE -Djava.ext.dirs=/path/to/project/L/target启动它。如果我这样做,它就可以工作,表明L的服务提供商已成功加载(表明jar的结构可以)。

    注意:Java 8 technotes表示命令SPI,JRE是默认值。

    为什么哦,为什么当我只把L放在类路径上时不起作用?为什么我必须明确地指出它?

    更新:通过的JavaDoc再次去后,我刚看到这个(重点煤矿):

    这些

    实现语言环境敏感的服务使用 Java扩展机制为安装扩展包装。

    这可以解释的事情。 :(

    有什么办法通过只把L在classpath时P运行,即无需安装L(或不必使用-D系统属性)?(P使用Maven来完成这项工作, Struts2的春季,如果这能帮助...)

    回答

    1

    在更复杂的应用,如Web服务器(例如Tomcat)的,有多个类加载器,所以每个Web应用程序由Web服务器提供可以保持独立。

    扩展我chanism用于扩展核心Java功能,即在运行的JVM(Web服务器)内全局可用的功能。因此,它们必须由System ClassLoader加载。

    的标准方法的扩展添加到代码的Java运行时,是要么

    • 的Jar文件添加到JRE_HOME/lib/ext文件夹
    • 添加额外的文件夹通过指定java.ext.dirs系统属性
    • 搜索

    你也只是把它添加到引导类路径自己,但如果安全管理器被激活,可能会引发问题。不确定那部分。所以最好以官方的方式来做。

    请注意,由CLASSPATH环境变量或-cp命令行选项定义的类路径未定义引导类路径。

    要了解更多信息,请阅读Java文档 “How Classes are Found”。

    +1

    警告:我得到的印象的扩展类加载器已经在Java中9被删除,这将在9月发布。参见[JEP 220](http://openjdk.java.net/jeps/220),https://bugs.openjdk.java.net/browse/JDK-8065702和http://marxsoftware.blogspot.com/2017 /01/jdk-9-is-end-of-road-for-some-features.html。 – VGR

    +0

    当我看到在技术说明中[通知](http://docs.oracle.com/javase/8/docs/technotes/guides/extensions/extensions.html),称该机制被废弃我认为之多;还考虑到applet的移除以及下载的扩展机制如何实现以支持它们。我也认为他们可能没有看过LocaleServiceProvider。我假设'CLDR'将被广告为替代品,但其èn_GB'格式短日期为'dd/MM/yyyy',而'JRE'只使用'dd/MM/yy' - 这样的不一致会导致有线和精彩解析时的副作用。 ;-) – Christian

    +0

    我会回来;看起来像我想要的[Java 9]将成为可能(http://download.java.net/java/jdk9/docs/api/java/util/spi/LocaleServiceProvider.html):“这些语言环境敏感服务的实现可以通过将它们添加到应用程序的类路径来使其可用。“好极了! :d – Christian

    相关问题