问题
I have a deployment that calls javax.crypto.SecretKeyFactory.getInstance
.
The class javax.crypto.SecretKeyFactory
appears to load correctly, but when the method tries to create an instance it throws a NoClassDefFoundError
on sun/security/jca/GetInstance
Looking at the OpenJDK8 sources shows that relevant javax.crypto.SecretKeyFactory
constructor refers explicitly to a method in sun.security.jca.GetInstance
, so it's normal that it tries to load it.
What's odd is that both javax/crypto/SecretKeyFactory.class
and sun/security/jca/GetInstance.class
are present in /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.91-1.b14.el6.x86_64/jre/lib/rt.jar
but that only the former is found by the classloader.
What is the jboss module classloader playing at and how can I get it to stop it?
Thanks for suggestions.
回答1:
Not all JDK classes are exposed to a deployment by default. If your deployment uses JDK classes that are not exposed you can get access to them using jboss-deployment-structure.xml
with system dependencies:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
<deployment>
<dependencies>
<system export="true">
<paths>
<path name="sun/security/jca"/>
</paths>
</system>
</dependencies>
</deployment>
</jboss-deployment-structure>
Another alternative you can import the whole system module adding the following line to MANIFEST.MF
:
Dependencies: system
Ref: Class Loading and Modules
回答2:
In your JBoss installation, go to directory modules/sun/jdk/main
and edit the module.xml
file there. In <dependencies>/<system>/<paths>
add an element <path name="sun/security/jca"/>
. Restart your JBoss instance and retry.
回答3:
I finally fixed my problem, though not quite in the ways suggested above. I wouldn't have got there without the help though (thanks guys).
I did manage to fix the sun/security/jca access problem but it then threw up another problem of a similar type, but with a javax class. I found an ugly fix for that by removing a jar from module org/jboss/genericjms and letting the jdk version get picked up, but I felt that that was playing around too much with stuff that I couldn't predict the consequences of.
The fix I have finally settled on is to put the provided jar that references javax/crypto/SecretKeyFactory in a new module all of its own and then to pull in the classes it needs via:
<system export="true">
<paths>
<path name="java/sql"/>
<path name="javax/crypto"/>
<path name="javax/crypto/spec"/>
<path name="javax/crypto/interfaces"/>
<path name="javax/management"/>
<path name="javax/security/auth/login"/>
<path name="sun/security/jca"/>
<path name="org/ietf/jgss"/>
</paths>
</system>
in the module.xml. When I reference this new module from my code it works (I pulled it in by making it a global module in standalone.xml in fact).
Problem solved. Though I have to say that after this experience of the jboss modular class loader, give me a hierarchical one any day.
Thanks again for the help.
来源:https://stackoverflow.com/questions/43327178/jboss-eap-6-4-noclassdeffounderror-on-class-sun-security-jca-getinstance