代码之家  ›  专栏  ›  技术社区  ›  Dan

如何愚弄Java服务提供者API(jaxp)

  •  4
  • Dan  · 技术社区  · 14 年前

    我有一个applet需要调用JAXP,特别是 SAXParserFactory . 现在,正如您从Javadoc中看到的,它在内部使用服务提供者机制 here :

    特别是,如果在我的应用程序jar中没有找到一个名为 META-INF/services/javax.xml.parsers.SAXParserFactory 它将尝试从我的应用程序代码库中获取它。如果我的applet部署如下:

    <applet code="com.example.applets.MyApplet" 
     codebase="http://www.example.com/myapp/" archive="myapp.jar, dom4j.jar">
    

    然后它将尝试向 http://www.example.com/myapp/META-INF/services/javax.xml.parsers.SAXParserFactory

    我不希望这样做,特别是因为我的applet已经签名,并且这个额外的HTTP调用触发了一个关于 unsigned code .

    现在,最明显的解决方案是像它所说的那样将META-INF/services文件放在我的应用程序JAR中,但是我如何做到这一点,同时仍然让它使用用户的JRE默认JAXP实现?或者,是否有方法说服applet运行时查看 只有 在我的JAR文件里而不是在 codebase 为了那个文件?

    注意:我知道我也可以部署自己的JAXP-RI副本,但对于applet来说,这是相当沉重的负担。

    1 回复  |  直到 12 年前
        1
  •  11
  •   mhaller    14 年前

    禁用代码库查找:

    <applet ...>
     <param name="codebase_lookup" value="false">
    </applet>
    

    这个 AppletClassLoader 检查布尔属性 sun.applet.AppletClassLoader.codebaseLookup ,可通过设置上述参数来影响。方法 sun.applet.AppletPanel.init() 将读取参数并将其设置为 AppletClassLoader程序 . 一旦禁用,AppletClassLoader将停止在codebase(即由 codebase="http://www.example.com/myapp/" 只查看档案和系统类路径。

    注意:我没有亲自测试这个,但是根据反汇编代码中的代码检查,我真的相信它可以工作。

    它也记录在 JavaSE - Technical Notes - Plugin Developer Guide - Special Attributes :

    代码库查找

    当applet类加载器需要加载类或资源(例如,META-INF/services目录下可插入服务提供者的配置文件)时,它首先在applet JAR文件中搜索所需的文件,然后从applet代码库中搜索。通常,applet与所有需要的类和资源一起部署在applet JAR文件中。在这种情况下,不需要代码基查找。

    如果applet JAR文件中没有可用的类或资源,最好让类加载器失败,而不是尝试进行代码基查找。否则,必须连接到applet代码库才能搜索类或资源,并且可能会对applet运行时产生性能影响。