我有一个需要调用JAXP的小程序,特别是SAXParserFactory。现在,您可以从Javadoc中看到,它在内部使用了Service Provider机制,如此处所述:

具体来说,如果它在我的任何应用程序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-发出HTTP请求INF / services / javax.xml.parsers.SAXParserFactory

我不愿意这样做,特别是因为我的applet已签名并且此额外的HTTP调用触发了有关未签名代码的警告。

现在,显而易见的解决方案是将META-INF / services文件放入它的应用程序JAR中,就像上面说的那样,但是我该怎么做却仍然使用用户的JRE JAXP默认实现来获得它?或者,是否有办法说服applet运行时仅在我的JAR文件中查找,而不在该文件的codebase中查找?

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

#1 楼

禁用代码库查找:
<applet ...>
 <param name="codebase_lookup" value="false">
</applet>

AppletClassLoader检查布尔属性sun.applet.AppletClassLoader.codebaseLookup,这可以通过设置上述参数来影响。方法sun.applet.AppletPanel.init()将读取参数并将其设置为AppletClassLoader。一旦禁用,AppletClassLoader将停止对代码库中的类和资源(即codebase="http://www.example.com/myapp/"给出的URL)进行远程查找,而仅查看归档文件和系统类路径。
注意:我自己并未对此进行测试,但是根据反汇编代码中的代码回顾,老实说,我相信它可以工作。
它也记录在JavaSE中-技术说明-插件开发人员指南-特殊属性:

codebase_lookup
何时applet类加载器需要加载一个类或资源(例如,META-INF / services目录下可插拔服务提供者的配置文件),它首先在applet JAR文件中搜索所需的文件,然后从applet代码库中搜索。通常,将使用存储在applet JAR文件中的所有必需的类和资源来部署applet。在这种情况下,不需要进行代码库查找。否则,必须与applet代码库建立连接以搜索类或资源,这可能会对applet运行时产生性能影响。