2010-11-17 26 views
4

J'ai une applet qui doit appeler JAXP, en particulier SAXParserFactory. Maintenant, comme vous pouvez le voir sur la Javadoc, celui-ci utilise en interne le mécanisme du fournisseur de services tel que documenté here:Comment tromper l'API Java Service Provider (jaxp)

Plus précisément, si elle ne trouve pas un fichier dans l'un de mes JARs application appelée META-INF/services/javax.xml.parsers.SAXParserFactory il va essayer de chercher dans mon base de code d'application. Si j'ai mon applet déployée comme suit:

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

Ensuite, il va essayer de faire une requête HTTP à http://www.example.com/myapp/META-INF/services/javax.xml.parsers.SAXParserFactory

Je préfère ne pas le faire, en particulier parce que mon applet est signé et cette HTTP supplémentaire appel déclenche un avertissement à propos de unsigned code. Maintenant, la solution évidente est de simplement placer le fichier META-INF/services dans mon application JAR comme il le dit, mais comment faire pour l'obtenir tout en utilisant l'implémentation JRE par défaut de JAXP? Alternativement, y at-il un moyen de convaincre l'exécution de l'applet pour regarder seulement dans mes fichiers JAR et non dans le codebase pour ce fichier?

Note: Je sais que je pourrais également déployer ma propre copie de JAXP-RI mais c'est assez lourd pour une applet.

Répondre

11

Désactiver la recherche codebase:

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

Les AppletClassLoader vérifie une propriété booléenne sun.applet.AppletClassLoader.codebaseLookup, qui peut être influencé en définissant le paramètre ci-dessus. La méthode sun.applet.AppletPanel.init() lit le paramètre et le place dans le AppletClassLoader. Une fois désactivé, AppletClassLoader arrête de faire des recherches à distance pour les classes et les ressources dans la base de code, c'est-à-dire l'URL donnée par codebase="http://www.example.com/myapp/" et ne regarde que dans les archives et les chemins de classe système.

Note: Je ne l'ai pas testé moi-même, mais selon la révision du code dans le code démonté, je crois sincèrement que cela pourrait fonctionner.

Il est également documenté dans JavaSE - Technical Notes - Plugin Developer Guide - Special Attributes:

codebase_lookup

Lorsque le classloader applet a besoin de charger une classe ou d'une ressource (par exemple, les fichiers de configuration pour les fournisseurs de services connectables sous le META-INF/répertoire des services), il recherche d'abord les fichiers requis dans les fichiers JAR de l'applet, puis dans le code de l'applet. Généralement, les applets sont déployées avec toutes les classes et ressources nécessaires stockées dans les fichiers JAR de l'applet. Dans ce cas, la recherche de base de code est inutile.

Si la classe ou la ressource n'est pas disponible à partir des fichiers JAR de l'applet, il est préférable que le classloader échoue plutôt que de tenter une recherche de base de code. Sinon, une connexion doit être établie avec la base de code de l'applet pour rechercher la classe ou la ressource, et elle peut avoir un impact sur les performances de l'applet runtime.

+0

Cela semble prometteur. Je vais essayer ça et poster une mise à jour! – Dan

+0

Cela a fonctionné. Réponse acceptée. – Dan

+0

Ça marche aussi pour moi. Je vous remercie! –