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:
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">
Then it will try to make an HTTP request to http://www.example.com/myapp/META-INF/services/javax.xml.parsers.SAXParserFactory
I'd rather it not do that, specifically because my applet is signed and this additional HTTP call triggers a warning about unsigned code.
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?
Note: I know I could also deploy my own copy of JAXP-RI but that's pretty heavy-weight for an applet.
Disable the codebase lookup:
<applet ...>
<param name="codebase_lookup" value="false">
</applet>
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.
It's also documented in JavaSE - Technical Notes - Plugin Developer Guide - Special Attributes:
codebase_lookup
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.
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.
来源:https://stackoverflow.com/questions/4207297/how-to-fool-the-java-service-provider-api-jaxp