I'm trying to create a SOAP web service using Oracle WebLogic 10.3.4 and jax-ws api.
For now, i'm trying to test a simple example:
package HelloService.hello;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
#WebService
public interface HelloWorld {
#WebMethod
public String getHelloWorld(#WebParam(name = "str") String input);
}
package HelloService.hello;
import javax.jws.WebParam;
import javax.jws.WebService;
#WebService(endpointInterface = "HelloService.hello.HelloWorld")
public class HelloWorldImpl implements HelloWorld {
public String getHelloWorld(#WebParam(name = "str") String input) {
return "Hello World message: " + input;
}
}
In my WebLogic installation, I have a cluster and a server in it, where I deploy this web service. After being deployed, I can access the wsdl file without any problem, but when I send a request to the web service i get the following exception instead of the expected response (I'm testing the web service with SoapUI plugin for Eclipse):
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>ClusterRoutingTubeUtils weblogic.wsee.jaxws.cluster.ClusterRoutingTubeUtils#782d8a2f not ready, no WseeClusterRoutingRuntimeMBean/WseeRuntimeMBean</faultstring>
<detail>
<ns2:exception class="java.lang.IllegalStateException" note="To disable this feature, set com.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace system property to false" xmlns:ns2="http://jax-ws.dev.java.net/">
<message>ClusterRoutingTubeUtils weblogic.wsee.jaxws.cluster.ClusterRoutingTubeUtils#782d8a2f not ready, no WseeClusterRoutingRuntimeMBean/WseeRuntimeMBean</message>
<ns2:stackTrace>
<ns2:frame class="weblogic.wsee.jaxws.cluster.ClusterRoutingTubeUtils" file="ClusterRoutingTubeUtils.java" line="87" method="ensureSOAPRouter"/>
<ns2:frame class="weblogic.wsee.jaxws.cluster.ClusterRoutingTubeUtils" file="ClusterRoutingTubeUtils.java" line="95" method="handleInboundMessage"/>
<ns2:frame class="weblogic.wsee.jaxws.cluster.ClusterRoutingServerTube" file="ClusterRoutingServerTube.java" line="70" method="processRequest"/>
<ns2:frame class="com.sun.xml.ws.api.pipe.Fiber" file="Fiber.java" line="866" method="__doRun"/>
<ns2:frame class="com.sun.xml.ws.api.pipe.Fiber" file="Fiber.java" line="815" method="_doRun"/>
<ns2:frame class="com.sun.xml.ws.api.pipe.Fiber" file="Fiber.java" line="778" method="doRun"/>
<ns2:frame class="com.sun.xml.ws.api.pipe.Fiber" file="Fiber.java" line="680" method="runSync"/>
<ns2:frame class="com.sun.xml.ws.server.WSEndpointImpl$2" file="WSEndpointImpl.java" line="403" method="process"/>
<ns2:frame class="com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit" file="HttpAdapter.java" line="532" method="handle"/>
<ns2:frame class="com.sun.xml.ws.transport.http.HttpAdapter" file="HttpAdapter.java" line="253" method="handle"/>
<ns2:frame class="com.sun.xml.ws.transport.http.servlet.ServletAdapter" file="ServletAdapter.java" line="140" method="handle"/>
<ns2:frame class="com.sun.xml.ws.transport.http.servlet.WSServletDelegate" file="WSServletDelegate.java" line="129" method="doGet"/>
<ns2:frame class="com.sun.xml.ws.transport.http.servlet.WSServletDelegate" file="WSServletDelegate.java" line="160" method="doPost"/>
<ns2:frame class="com.sun.xml.ws.transport.http.servlet.WSServlet" file="WSServlet.java" line="75" method="doPost"/>
<ns2:frame class="javax.servlet.http.HttpServlet" file="HttpServlet.java" line="727" method="service"/>
<ns2:frame class="javax.servlet.http.HttpServlet" file="HttpServlet.java" line="820" method="service"/>
<ns2:frame class="weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction" file="StubSecurityHelper.java" line="227" method="run"/>
<ns2:frame class="weblogic.servlet.internal.StubSecurityHelper" file="StubSecurityHelper.java" line="125" method="invokeServlet"/>
<ns2:frame class="weblogic.servlet.internal.ServletStubImpl" file="ServletStubImpl.java" line="300" method="execute"/>
<ns2:frame class="weblogic.servlet.internal.ServletStubImpl" file="ServletStubImpl.java" line="183" method="execute"/>
<ns2:frame class="weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction" file="WebAppServletContext.java" line="3717" method="wrapRun"/>
<ns2:frame class="weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction" file="WebAppServletContext.java" line="3681" method="run"/>
<ns2:frame class="weblogic.security.acl.internal.AuthenticatedSubject" file="AuthenticatedSubject.java" line="321" method="doAs"/>
<ns2:frame class="weblogic.security.service.SecurityManager" file="SecurityManager.java" line="120" method="runAs"/>
<ns2:frame class="weblogic.servlet.internal.WebAppServletContext" file="WebAppServletContext.java" line="2277" method="securedExecute"/>
<ns2:frame class="weblogic.servlet.internal.WebAppServletContext" file="WebAppServletContext.java" line="2183" method="execute"/>
<ns2:frame class="weblogic.servlet.internal.ServletRequestImpl" file="ServletRequestImpl.java" line="1454" method="run"/>
<ns2:frame class="weblogic.work.ExecuteThread" file="ExecuteThread.java" line="207" method="execute"/>
<ns2:frame class="weblogic.work.ExecuteThread" file="ExecuteThread.java" line="176" method="run"/>
</ns2:stackTrace>
</ns2:exception>
</detail>
</S:Fault>
</S:Body>
</S:Envelope>
I've searched in google that some WebLogic versions have this issue when deploying a web service in a cluster. There is a fix but i can't apply it. IS there any workaround? Is this a common situation?
What alternatives do I have to develop a SOAP web service with WebLogic?
Thks in advance
I faced a similar issue. We applied the weblogic patch to resolve this issue and things began to work. Jax ws at times fails to work in clustered env, you can try to directly point to the deployed server url to make things work.
We are still facing the problem in http server to websphere as well. We pointed directly to the webphere deployed location to make things work.
Related
We've got an application with several web services annotated with #SecurityDomain("our-ws") (I've also tried setting this in jboss-web.xml). For example:
#Stateless
#Interceptors(OurTransactionInterceptor.class)
#WebService(targetNamespace = "...", portName = "AddStuff", serviceName = "AddStuffService")
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
#WebContext(authMethod = "BASIC", contextRoot = "/service", urlPattern = "/AddStuffService")
#SecurityDomain("our-ws")
public class AddStuffService { ... }
We are upgrading to Wildfly 26, and attempting to use elytron following the example from
WildFly Elytron Security, section 4.1.3. However, on startup, I'm getting an error like:
13 Jan 2023 11:26:01,763 ERROR [management-operation Controller Boot Thread] WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "service.war")]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => ["jboss.security.security-domain.our-ws"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => ["jboss.deployment.unit.\"service.war\".component.AddStuffService.CREATE is missing [jboss.security.security-domain.our-ws]"]
}
In standalone.xml, under <subsystem xmlns="urn:wildfly:elytron:15.1"...> We've got a datasource, which I'll call 'ourDS' (not shown) used by a jdbc-realm, jdbc:
<jdbc-realm name="jdbc">
<principal-query sql="SELECT password FROM CFG_WS_USERS_T WHERE username=?" data-source="evercoreDS">
<clear-password-mapper password-index="1"/>
</principal-query>
<principal-query sql="SELECT roles from CFG_WS_ROLES_T r join CFG_WS_USERS_T u on u.WS_USERS_PK=r.WS_USERS_FK where u.username=?" data-source="ourDS">
<attribute-mapping>
<attribute to="roles" index="1"/>
</attribute-mapping>
</principal-query>
</jdbc-realm>
And a security-domain for those web services:
<security-domain name="our-ws" default-realm="jdbc" permission-mapper="default-permission-mapper">
<realm name="jdbc" role-decoder="groups-to-roles"/>
</security-domain>
So I don't get why jboss.security.security-domain.our-ws is not installed (unless, maybe, it is looking for it in the legacy security configuration.).
How, do I get the SecurityDomain annotation (or the security-domain tag in jboss-web.xml) to refer to the elytron configuration, or why would my security-domain under elytron not be installed?
EDIT: In response to #ehsavoie's comment, I'll note that, per section 4.1.3 of the doc, we also have an http-authentication-factory and application-security-domain:
<http-authentication-factory name="our-ws-http-auth" security-domain="our-ws" http-server-mechanism-factory="global">
<mechanism-configuration>
<mechanism mechanism-name="BASIC">
<mechanism-realm realm-name="our-ws"/>
</mechanism>
</mechanism-configuration>
</http-authentication-factory>
<application-security-domains>
<application-security-domain name="defaultASD" security-domain="ApplicationDomain"/>
<application-security-domain name="our-ws-appsecurity-domain" http-authentication-factory="our-ws-http-auth"/>
</application-security-domains>
(I'm a bit confused by the mechanism-realm realm-name="our-ws", since our-ws is not a security-realm, but a security-domain, but it follows the documentation - again section 4.1.3-- and I also tried using the jdbc security-realm there, with the the same error.)
server
My stock-service client:
#Autowired
RestTemplate restTemplate;
ResponseEntity<List<String>> quoteResponse =
restTemplate.exchange("http://db-service/rest/db/" + userName,
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<String>>() {}
);
Here db-service is registered service in eureka server.
Its working if i hit directly like
/* ResponseEntity<List<String>> quoteResponse =
restTemplate.exchange("http://localhost:8300/rest/db/" + userName,
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<String>>() {}
);*/
#Configuration
public class Config {
#Bean
#LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
As far as I understand that db-service is your any micro-service and you want to send there request. You need to configure ribbon because RestTemplate doesn't understand db-service like host. You should add follow config:
db-service:
ribbon:
eureka:
enabled: false
listOfServers: localhost:8090
ServerListRefreshInterval: 15000
and maven dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
or you could add Discovery service(Eureka) to your system and you don't need to describing listOfSerevers because ribbon will get all information from discovery service
Please try by using spring-cloud-starter-netflix-eureka-client.
And check the version of spring-cloud-dependencies along with spring-boot-starter-parent version.
spring-cloud-starter-netflix-eureka-client should resolve the issue
I am having trouble logging an outgoing SOAP message from the server. The handleMessage method does not overwrite the message content as expected. How would I store the outgoing SOAP to the message?
public class OutgoingSoapInterceptor extends AbstractPhaseInterceptor<Message> {
private static final Logger logger = LoggerFactory.getLogger(OutgoingSoapInterceptor.class.getName());
public OutgoingSoapInterceptor ()
{
super(Phase.PRE_STREAM);
}
#Override
public void handleMessage(Message message) throws Fault {
logger.debug("outbound soap handleMessage");
OutputStream os = message.getContent ( OutputStream.class );
CacheAndWriteOutputStream cwos = new CacheAndWriteOutputStream ( os);
message.setContent ( OutputStream.class, cwos );
cwos.registerCallback ( new LoggingOutCallBack ( ) );
}
}
There is a simpler way to log the SOAP messages using CXF LoggingInInterceptor and LoggingOutInterceptor
LogUtils.setLoggerClass(org.apache.cxf.common.logging.Log4jLogger.class);
yourService = new YourService(wsdlURL, SERVICE_NAME);
port = yourService.getServicePort();
Client client = ClientProxy.getClient(port);
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());
Or configuring interceptors in <cxf:bus> with spring
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<cxf:bus>
<cxf:features>
<cxf:logging />
</cxf:features>
</cxf:bus>
<jaxws:endpoint ... />
</beans>
See more examples in How to log Apache CXF Soap Request and Soap Response using Log4j
I tried to develop a rest service and expose the same via Apache Camel's CXFRS. I followed all the steps given in http://camel.apache.org/cxfrs.html and also referred to many samples given. I already referred to the question Can't find the the request for url Observer, but in my case it is a simple rest request. Below are the Service class, Route class, and cxf context used:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:cxf="http://camel.apache.org/schema/cxf" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
http://camel.apache.org/schema/cxf
http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<context:annotation-config />
<!-- enable Spring #Component scan -->
<context:component-scan base-package="org.camelsample.rest" />
<cxf:rsServer id="rsServer" address="/rest"
serviceClass="org.camelsample.rest.service.SampleRestService"
loggingFeatureEnabled="true" loggingSizeLimit="20">
<cxf:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
</cxf:providers>
</cxf:rsServer>
<camel:camelContext id="samplerestservice"
xmlns="http://camel.apache.org/schema/spring">
<contextScan />
<jmxAgent id="agent" createConnector="true" />
</camel:camelContext>
</beans>
The Service Class:
package org.camelsample.rest.service;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
public class SampleRestService {
#GET
#Path("/")
public String sampleService() {
return null;
}
}
The Route Class:
package org.camelsample.rest.route;
import org.apache.camel.spring.SpringRouteBuilder;
public class SampleRestRoute extends SpringRouteBuilder {
#Override
public void configure() throws Exception {
// TODO Auto-generated method stub
from("cxfrs:bean:rsServer").log("Into Sample Route").setBody(constant("Success"));
}
}
But when I try to hit and test using http://localhost:8080/rest, I always get the following error message:
2015-05-29 13:38:37.920 WARN 6744 --- [nio-8080-exec-2] o.a.c.t.servlet.ServletController : Can't find the the request for http://localhost:8080/favicon.ico's Observer
2015-05-29 13:38:40.295 WARN 6744 --- [nio-8080-exec-3] o.a.c.t.servlet.ServletController : Can't find the the request for http://localhost:8080/rest's Observer
Am using Spring boot to test the rest sample.
Does it work with this URL instead ?
http://localhost:8181/cxf/rest
If you just use address="/rest" as your address then you will probably get the default Jetty port 8181 and default CXF servlet path /cxf as the base URL.
If you specifically want to use the URL you have given then try this instead:
address="http://0.0.0.0:8080/rest"
I have a client which connects to a Web service to get some information. I have a requirement where I have to send the same information to multiple services using different ports. To solve this without modifying the client code I found MULE ESB, which is supposed to do exactly what I need.
I've found a guide where I could connect one client to one service using MULE ESB and one port, but I cant find a way to chain the services so they all listen to one port but have different themselves.
This is how it's supposed to look like:
UPDATE :
here is my current Mule Applications config :
<mule xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="CE-3.2.1" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd ">
<flow name="flows1Flow1" doc:name="flows1Flow1">
<http:inbound-endpoint exchange-pattern="request-response" address="http://localhost:4433/miniwebservice" mimeType="text/xml" doc:name="HTTP"/>
<http:outbound-endpoint exchange-pattern="request-response" address="http://localhost:4434/miniwebservice?wsdl" mimeType="text/xml" doc:name="HTTP"/>
</flow>
</mule>
Here is the WebService :
Client :
package miniwebservice;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class TestWsClient
{
public static void main( final String[] args ) throws Throwable
{
String url = ( args.length > 0 ) ? args[0] : "http://localhost:4434/miniwebservice";
Service service = Service.create(
new URL( url + "?wsdl" ),
new QName( "http://miniwebservice/", "HalloWeltImplService" ) );
HalloWelt halloWelt = service.getPort( HalloWelt.class );
System.out.println( "\n" + halloWelt.hallo( args.length > 1 ? args[1] : "" ) );
}
}
Server :
package miniwebservice;
import javax.xml.ws.Endpoint;
public class TestWsServer
{
public static void main( final String[] args )
{
String url = ( args.length > 0 ) ? args[0] : "http://localhost:4434/miniwebservice";
Endpoint.publish( url, new HalloWeltImpl() );
}
}
InterfaceImpl :
package miniwebservice;
import javax.jws.WebService;
#WebService( endpointInterface="miniwebservice.HalloWelt" )
public class HalloWeltImpl implements HalloWelt
{
public String hallo( String wer )
{
return "Hallo " + wer;
}
}
interface :
package miniwebservice;
import javax.jws.*;
#WebService
public interface HalloWelt
{
public String hallo( #WebParam( name = "wer" ) String wer );
}
If I start the Server and the Mule aplication and try to reach http://localhost:4434/miniwebservice?wsdl ower http://localhost:4433/miniwebservice I get the folowing Exception in my Browser (FireFox 8.0) :
Couldn't create SOAP message due to exception: XML reader error: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
I just started to work with Mule so I thouth that this would be enouth to get redirect mule to the Service to get the wsdl but its seems like its a bit complicatet.
Disclaimers:
This is not the final solution to the whole problem, which includes dispatching to several services and aggregating results, but a step in the right direction.
This is not representative of how web service proxying is done in Mule (which is way simpler) but a barebone approach to HTTP request routing so aggregation can be added.
Since you want to forward HTTP GET requests to the ?wsdl processor and HTTP POST SOAP request to the web service, you need to handle the target HTTP method and request URI propagation yourself:
<flow name="flows1Flow1">
<http:inbound-endpoint exchange-pattern="request-response"
address="http://localhost:4433/miniwebservice" />
<message-properties-transformer scope="outbound">
<add-message-property key="http.method" value="#[header:INBOUND:http.method]" />
</message-properties-transformer>
<logger level="INFO" category="ddo" />
<http:outbound-endpoint exchange-pattern="request-response"
address="http://localhost:4434#[header:INBOUND:http.request]" />
</flow>
(tested and validated with TestWsClient and TestWsServer)