如何欺骗 Java 服务提供者 API (jaxp) [英] How to Fool the Java Service Provider API (jaxp)

查看:31
本文介绍了如何欺骗 Java 服务提供者 API (jaxp)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an applet that needs to call JAXP, specifically SAXParserFactory. Now, as you can see from the Javadoc, this internally uses the Service Provider mechanism as documented here:

具体来说,如果它在我的任何应用程序 JAR 中都没有找到名为 META-INF/services/javax.xml.parsers.SAXParserFactory 的文件,它将尝试从我的应用程序代码库中获取它.如果我的小程序部署如下:

Specifically, if it does not find a file in any of my application JARs called META-INF/services/javax.xml.parsers.SAXParserFactory it will try to fetch it from my application codebase. If I have my applet deployed as follows:

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

然后它会尝试向 发出 HTTP 请求http://www.example.com/myapp/META-INF/services/javax.xml.parsers.SAXParserFactory

我宁愿它不这样做,特别是因为我的小程序已签名并且这个额外的 HTTP 调用触发了关于 未签名代码.

I'd rather it not do that, specifically because my applet is signed and this additional HTTP call triggers a warning about unsigned code.

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

Now, the obvious solution is to just put the META-INF/services file in my application JAR like it says, but how do I do that yet still get it to use the user's JRE default implementation of JAXP? Alternately, is there a way to convince the applet runtime to look only in my JAR files and not in the codebase for that file?

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

Note: I know I could also deploy my own copy of JAXP-RI but that's pretty heavy-weight for an applet.

推荐答案

禁用代码库查找:

<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/" 和只查看档案和系统类路径.

The AppletClassLoader checks for a boolean property sun.applet.AppletClassLoader.codebaseLookup, which can be influenced by setting the above parameter. The method sun.applet.AppletPanel.init() will read the parameter and set it into the AppletClassLoader. Once disabled, the AppletClassLoader will stop making remote lookups for classes and resources in the codebase, that is the URL given by codebase="http://www.example.com/myapp/" and only look into the archives and system class paths.

注意:我没有亲自测试过,但根据反汇编代码中的代码审查,老实说,我相信它可以工作.

Note: I did not test this myself, but according to code review in the disassembled code, i honestly believe it could work.

它也记录在 JavaSE - 技术说明- 插件开发者指南 - 特殊属性:

codebase_lookup

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

When the applet classloader needs to load a class or resource (for example, configuration files for pluggable service providers under the META-INF/services directory), it first searches for the required files in the applet JAR files and then from the applet codebase. Typically applets are deployed with all the needed classes and resources stored in the applet JAR files. In this case, the codebase lookup is unnecessary.

如果 Applet JAR 文件中的类或资源不可用,则最好让类加载器失败,而不是尝试查找代码库.否则,必须连接到小程序代码库来搜索类或资源,这可能会对小程序运行时的性能产生影响.

If the class or resource is not available from the applet JAR files, it may be better to have the classloader fail rather than attempt a codebase lookup. Otherwise, a connection has to be made to the applet codebase to search for the class or resource, and it may have performance impact on the applet runtime.

这篇关于如何欺骗 Java 服务提供者 API (jaxp)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆