异常来了:java.util.ServiceConfigurationError

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24624719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 13:32:32  来源:igfitidea点击:

Exception coming: java.util.ServiceConfigurationError

javajakarta-eejboss5.x

提问by VJS

Getting below exception while running my application :

运行我的应用程序时出现以下异常:

I am using jboss : 5.1.1 and jdk 1.6.

我正在使用 jboss:5.1.1 和 jdk 1.6。

01:50:04,828 ERROR [[HelloWorld]] Servlet.service() for servlet HelloWorld threw exception
java.util.ServiceConfigurationError: javax.xml.ws.spi.Provider: Provider org.jboss.ws.core.jaxws.spi.ProviderImpl not a subtype
    at java.util.ServiceLoader.fail(Unknown Source)
    at java.util.ServiceLoader.access0(Unknown Source)
    at java.util.ServiceLoader$LazyIterator.next(Unknown Source)
    at java.util.ServiceLoader.next(Unknown Source)
    at javax.xml.ws.spi.Provider.getProviderUsingServiceLoader(Provider.java:146)
    at javax.xml.ws.spi.Provider.provider(Provider.java:106)
    at javax.xml.ws.Service.<init>(Service.java:57)
    at com.service_instance.ServiceInstance.<init>(ServiceInstance.java:50)
    at com.getBusinessApp(CMDB.java:239)
    at com.test.HelloWorld.doGet(HelloWorld.java:51)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
    at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
    at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Unknown Source)

Let m know. How to resolve this. It seems like some lib issue.

让我知道。如何解决这个问题。这似乎是一些lib问题。

回答by nephewtom

I had the same problem deploying a USSD gateway with Mobicents Jain Slee, that runs on top of a JBoss AS 5.1.0 GA. The gateway has to connect to a server via SOAP, so I chose JAX-WS and generated the source code from a WSDL with wsimport. By the way, I used a similar procedure to this oneto create a child Maven project and generate the java files for JAX-WS.

我在部署带有Mobicents Jain Slee的 USSD 网关时遇到了同样的问题,该网关在 JBoss AS 5.1.0 GA 之上运行。网关必须通过 SOAP 连接到服务器,因此我选择了 JAX-WS 并使用wsimport从 WSDL 生成源代码。顺便说一句,我用了一个类似的方法,这其中创建一个子Maven项目,并为JAX-WS的Java文件。



Failed deploy with dependencies embedded on .war file

依赖嵌入在 .war 文件中的部署失败

My first approach was to include all the dependencies in the .war file that is deployed in JBoss. I think this is achieved by default in Maven, and mvn installwill do it. In the long run, this approach failed, but at least I needed to know the list of jar files that were included in the .war file, to copy them later in a JBoss directory.

我的第一种方法是在 JBoss 中部署的 .war 文件中包含所有依赖项。我认为这是在 Maven 中默认实现的,并且mvn install会做到。从长远来看,这种方法失败了,但至少我需要知道 .war 文件中包含的 jar 文件列表,以便稍后将它们复制到 JBoss 目录中。

I made a lot of troubleshooting with this approach, and had many different log errors, though the main one was this:

我用这种方法做了很多故障排除,并有许多不同的日志错误,但主要是这样的:

java.util.ServiceConfigurationError: javax.xml.ws.spi.Provider: Provider org.jboss.ws.core.jaxws.spi.ProviderImpl not a subtype


Deploy without dependencies

无依赖部署

Maven tweak

Maven 调整

So insted, I added <scope>provided</scope>to the JAX-WS dependencies. Something like:

因此,我添加<scope>provided</scope>了 JAX-WS 依赖项。就像是:

<dependency>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-rt</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.sun.istack</groupId>
    <artifactId>istack-commons-runtime</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>

This produced a much lighter .war file.

这产生了一个更轻的 .war 文件。

Copy & remove jars in JBoss AS

在 JBoss AS 中复制和删除 jars

Now, after deploying the .war file, when my SOAP client tried to connect to the Web Service, and it throwed the exception:

现在,在部署 .war 文件后,当我的 SOAP 客户端尝试连接到 Web 服务时,它抛出了异常:

org.jboss.ws.metadata.wsdl.WSDLException: Invalid default namespace: null
at org.jboss.ws.tools.wsdl.WSDLDefinitionsFactory.parse(WSDLDefinitionsFactory.java:134)
at org.jboss.ws.metadata.umdm.ServiceMetaData.getWsdlDefinitions(ServiceMetaData.java:293)
at org.jboss.ws.metadata.builder.jaxws.JAXWSClientMetaDataBuilder.buildMetaData(JAXWSClientMetaDataBuilder.java:84)
at org.jboss.ws.core.jaxws.spi.ServiceDelegateImpl.<init>(ServiceDelegateImpl.java:138)
at org.jboss.ws.core.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:63)
at javax.xml.ws.Service.<init>(Service.java:79)
at org.ortelius.UssdServiceImplementation.<init>(UssdServiceImplementation.java:42)
at org.ortelius.OrteliusClient.sendUssdRequestToWs(OrteliusClient.java:28)

It seems that javax.xml.ws.Servicecalls org.jboss.ws.core.jaxws.spi.ProviderImpl, but it should be calling com.sun.xml.ws.spi.ProviderImpl, so it seems there is a conflict with jar dependencies.

好像是javax.xml.ws.Service调用了org.jboss.ws.core.jaxws.spi.ProviderImpl,但是应该是调用了com.sun.xml.ws.spi.ProviderImpl,所以好像和jar依赖有冲突。

To avoid this problem, it was necessary to:

为了避免这个问题,有必要:

  1. Move or delete all JBoss jar files found in $JBOSS_HOME/lib/endorsed/directory.
  2. Copy the jars bundled in my initial .war file (the one of the failed deploy) to $JBOSS_HOME/lib/endorsed/directory. all the jars bundled in my .war file.
  1. 移动或删除在$JBOSS_HOME/lib/endorsed/目录中找到的所有 JBoss jar 文件。
  2. 将捆绑在我的初始 .war 文件(部署失败之一)中的 jars 复制到$JBOSS_HOME/lib/endorsed/目录。捆绑在我的 .war 文件中的所有 jars。

That basically made it.

基本上做到了。



Final notes

最后的笔记

I have to confess that to find this out was a real pain, and it took me about four days to get this up & running. I made a lot of troubleshooting with the jar dependencies, checking JBoss logs, remote debugging, comparing Java packages & classes versions, searching for jars online and reading many articles from JBoss manuals, blogs, StackOverflow, JavaRanch, etc...

我必须承认,发现这一点真的很痛苦,我花了大约四天的时间才能启动并运行。我对 jar 依赖做了很多故障排除,检查 JBoss 日志,远程调试,比较 Java 包和类版本,在线搜索 jar 并阅读 JBoss 手册、博客、StackOverflow、JavaRanch 等中的许多文章......

The SOAP client was really simple, but the deployment in JBoss was pretty problematic. My solution is not very orthodox, since it depends greatly on the jar files dependencies. So I'm not sure if it will work for everyone.

SOAP 客户端非常简单,但在 JBoss 中部署却有很大的问题。我的解决方案不是很正统,因为它很大程度上取决于 jar 文件的依赖关系。所以我不确定它是否对每个人都有效。

Regards.

问候。

回答by Splioo

Try to switch class loaders.

尝试切换类加载器。

Grab classloader from your Service class and reset after the call.

从您的服务类中获取类加载器并在调用后重置。

    final ClassLoader targetClassLoader = ServiceXY.class.getClassLoader();
    final Thread currentThread = Thread.currentThread();
    final ClassLoader contextClassLoader = currentThread.getContextClassLoader();
    try {
           currentThread.setContextClassLoader(targetClassLoader);
           //here call your Service 
    } finally {
           currentThread.setContextClassLoader(contextClassLoader);
    }

JEE libs have been removed with Java 9, JEE-specific libs / implementations must now be made available by the application via thirdparty libraries - e.g. jaxws-api.jar and jaxws-rt.jar. This code of JEE libs often still expects to be part of the jre system library and with that of the application classloader - but it isn't anymore. So if service classloader ServiceXY.class.getClassLoader()and your application classloader Thread.currentThread().getContextClassLoader()are different you need to switch for the request.

Java 9 中删除了 JEE 库,应用程序现在必须通过第三方库(例如 jaxws-api.jar 和 jaxws-rt.jar)使特定于 JEE 的库/实现可用。这段 JEE 库的代码通常仍然希望成为 jre 系统库的一部分,并与应用程序类加载器一起成为一部分——但它不再是了。因此,如果服务类加载器ServiceXY.class.getClassLoader()和您的应用程序类加载器Thread.currentThread().getContextClassLoader()不同,您需要针对请求进行切换。