英文:
java.util.ServiceLoader not able to load provider
问题
尝试升级 Java 版本时遇到了 SAAJ 异常,已尝试多种解决方案但未成功。两个应用升级到 Java 17 后出现了 Provider 未找到的错误,本地运行正常,但在容器中出现异常。通过比较日志,发现本地成功加载 provider,而容器中未成功加载。建议检查线程相关的配置和依赖,可能与线程加载 provider 有关。
英文:
I've been trying to resolve my problems for several days without success and need help.
We've been upgrading our java version from 8 to 17 in our application (more than 20) and with only 2 of them we have met this error:
Caused by: jakarta.xml.soap.SOAPException: Unable to create SAAJ meta-factory: Provider com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl not found
We've already tried every solutions as the one mentioned here unable to create metafactory
Even importing all these dependencies in our pom or setting System properties seems to have no effect, but the strangest things of all is that those 2 applications work locally in our computers while have the error when being in a container.
Looking at the logs, the only difference I can see is that locally, the java.util.ServiceLoader is able to load the provider:
23-04-06 Thu 11:43:14.999 INFO 10832 --- [onPool-worker-2] SaajSoapMessageFactory : Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol
23-04-06 Thu 11:43:15.004 DEBUG 10832 --- [onPool-worker-2] soap : Checking system property jakarta.xml.soap.SAAJMetaFactory
23-04-06 Thu 11:43:15.006 DEBUG 10832 --- [onPool-worker-2] soap : not found
23-04-06 Thu 11:43:15.006 DEBUG 10832 --- [onPool-worker-2] soap : Using java.util.ServiceLoader to find jakarta.xml.soap.SAAJMetaFactory
23-04-06 Thu 11:43:15.008 DEBUG 10832 --- [onPool-worker-2] soap : ServiceProvider loading Facility used; returning object [com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl]
23-04-06 Thu 11:43:15.014 DEBUG 10832 --- [onPool-worker-2] SaajSoapMessageFactory : Using MessageFactory class [com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl]
23-04-06 Thu 11:43:15.158 DEBUG 10832 --- [onPool-worker-2] bind : Resolved classes from context path: [class pippo.ObjectFactory]
while in the container it fails but without any message:
23-04-06 Thu 12:48:25.974 DEBUG 1 --- [onPool-worker-1] soap : Checking system property jakarta.xml.soap.SAAJMetaFactory
23-04-06 Thu 12:48:25.977 DEBUG 1 --- [onPool-worker-1] soap : not found
23-04-06 Thu 12:48:25.978 DEBUG 1 --- [onPool-worker-1] soap : Using java.util.ServiceLoader to find jakarta.xml.soap.SAAJMetaFactory
23-04-06 Thu 12:48:26.066 DEBUG 1 --- [onPool-worker-1] soap : Class org.glassfish.hk2.osgiresourcelocator.ServiceLoader cannot be loaded
java.lang.ClassNotFoundException: org.glassfish.hk2.osgiresourcelocator.ServiceLoader
In fact, it tries to load the provider with glassfish but this to fail even adding the right dependency that as you can see in this error is missing (osgiresourcelocator.ServiceLoader).
I've tried to compare this 2 applications with the other working but there is no difference in the pom nor in the SoapClient used, that is exactly the same for all, and quite simople since we use WebserviceTemplate.marshalSendAndReceive.
Another weird behaviour I've seen in 1 of those 2 applications is that after 1 day that has been up, the application responded correctly and the error was misteriouve sly vanished.
Not only that, but in this application there is a scheduler configured and while this succeded in loading the provider and making soap calls, calling the applications on a specific enpoint that calls the same soap service fails at it, generating the error mentioned above. The only thing that change beetween those 2 calls is the thread.
So it seems like some threads have problems loading the provider in this one, but I think there is something related.
Do you have any suggestions/tests that can be done to understand and solve this?
答案1
得分: 1
我遇到了同样的问题。在我们的情况下,我们使用了分叉加入线程池,而实例化的线程类加载器没有正确的上下文。
我通过保存当前的类加载器上下文来解决了这个问题:
ClassLoader oldCcl = Thread.currentThread().getContextClassLoader();
然后在另一个线程中使用它:
Thread.currentThread().setContextClassLoader(oldCcl);
更多详细信息请参考 https://stackoverflow.com/questions/66393004/jaxb-class-not-found-with-forkjoinpool-java
英文:
I faced the same problem. In our case, we use fork join thread pool and instantiated thread's classloader did not have the correct context.
I solved this by saving current classloader context:
ClassLoader oldCcl = Thread.currentThread().getContextClassLoader();
And using it in another thread:
Thread.currentThread().setContextClassLoader(oldCcl);
For more details, see https://stackoverflow.com/questions/66393004/jaxb-class-not-found-with-forkjoinpool-java
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论