`java.util.ServiceLoader` 无法加载提供程序

huangapple go评论56阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年4月6日 19:00:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/75948739.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定