如何欺骗Java服务提供者API(jaxp)

时间:2010-11-17 17:29:38

标签: java applet jaxp service-provider

我有一个需要调用JAXP的applet,特别是SAXParserFactory。现在,正如您在Javadoc中看到的那样,这内部使用了文档here所述的服务提供者机制:

具体来说,如果它在我的任何名为META-INF/services/javax.xml.parsers.SAXParserFactory的应用程序JAR中找不到文件,它将尝试从我的应用程序代码库中获取它。如果我的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

发出HTTP请求

我宁愿不这样做,特别是因为我的applet已签名,而这个额外的HTTP调用会触发关于unsigned code的警告。

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

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

1 个答案:

答案 0 :(得分:11)

禁用代码库查找:

<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 - Technical Notes - Plugin Developer Guide - Special Attributes中也记录了它:

  

<强> codebase_lookup

     

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

     

如果applet JAR文件中没有类或资源,那么让类加载器失败而不是尝试进行代码库查找可能会更好。否则,必须与applet代码库建立连接以搜索类或资源,并且它可能会对applet运行时产生性能影响。