web client for web service - java

I've a web-service that works fine when I access them from a J2SE (desktop) application. To access this service I do follow:
generate stub classes by wsdl link using java wsimport tool
then I create service using generated classes and run one of wsdl operations.It looks like this:
MyWebServiceService webService = new MyWebServiceService();
MyWebService port = webService.getMyWebServicePort();
webService.run("XYZ");
As I sad it work fine when I use it in a standalone application.
But...when I try to access web-service in the same way but from servlet-client, using generated stubs I get following error:
java.lang.ClassCastException: com.sun.xml.bind.v2.runtime.JAXBContextImpl cannot be cast to com.sun.xml.bind.api.JAXBRIContext
org.jboss.ws.metadata.umdm.EndpointMetaData.eagerInitializeAccessors(EndpointMetaData.java:686)
org.jboss.ws.metadata.umdm.EndpointMetaData.initializeInternal(EndpointMetaData.java:567)
org.jboss.ws.metadata.umdm.EndpointMetaData.eagerInitialize(EndpointMetaData.java:553)
org.jboss.ws.metadata.builder.jaxws.JAXWSClientMetaDataBuilder.rebuildEndpointMetaData(JAXWSClientMetaDataBuilder.java:314)
org.jboss.ws.core.jaxws.spi.ServiceDelegateImpl.getPortInternal(ServiceDelegateImpl.java:271)
org.jboss.ws.core.jaxws.spi.ServiceDelegateImpl.getPort(ServiceDelegateImpl.java:202)
javax.xml.ws.Service.getPort(Service.java:143...
I've searched google long time but found nothing helpful topics. Some topics show examples accessing web-services from servlet, but unfortunately I can't do this...( And don't know what is cause of trouble.
Application server: jboss 4.2.3GA
Is it possible to connect web-service from servlet? How?
I've tried use #WebServiceRef annotation, but it seem web-container can't inject web-service stub. And I think that container must not do this itself, because stub classes have already been generated by wsimport tool, and its enouph to use this classes for accessing of web-service.
Stub classes were generated using the following command:
wsimport -keep -p com.myhost.ws http://www.myhost.com/services/MyWebService?wsdl

Did you make sure your classpath does not contain multiple JAX-B Jars with differing versions ? The exception looks like a version conflict to me. Application servers usually have some kind of "endorsed" lib directory that holds JARS that are always added in front of web application classpaths. Maybe your app server has a conflicting JAX-B implementation there ?
If you use Maven to package your application, make sure transitive dependencies don't pull in unwanted JAX-B Jars (use 'mvn dependency:tree' to check this).

This definitely sounds like a JAXB conflict to me. Check out the jaxb versions that you have in your war and make sure that they are not conflicting with a jaxb jar that Jboss may have in its lib directory.

Addytionally if jbossws-native library was installed correctly the following packages should be deleted from jboss_home/lib/endorsed directory:
jboss-jaxrpc.jar
jboss-jaxws-ext.jar
jboss-jaxws.jar
jboss-saaj.jar
Otherwise you don't have ability to connect to web service through EJB or servlet.

Related

Using SpringExtension with Tomcat and Hibernate web app

We are trying to use spring-test's SpringExtension to write integration tests for our Spring and Hibernate-based Tomcat web application. Our sessionFactory bean configuration has the property configured mappingJarLocations with a sample value as /WEB-INF/lib/company-common*.jar which contains hibernate mapping files. In both actual deployment and Eclipse dev deployment, this works fine as the docBasePath (in Servlet environment) is appended to this pattern and the files are getting resolved. But this is not the case while running JUnit test cases either in a local or a CI environment.
We tried our best to use the provided support by having few overridden implementations of WebTestContextBootstraper, GenricXmlWebContextLoader, XmlWebApplicationContext, and WebDelegatingSmartContextLoader but had to finally give up as we cannot override the final method org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(MergedContextConfiguration) to provide the custom implementation of XmlWebApplicationContext. Our current approach is to manually create the application context and use it in the tests.
Here is the project structure:
Project_WebApp
|--src/**
|--WebContent/**
|--pom.xml
When the app is packaged as Project_WebApp.war, the dependencies are inside WEB-INF/lib from the root of extracted war. When deployed as a webapp in Tomcat using Eclipse, the dependencies are copied to <Eclipse_Workspace_Dir>/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/Project_WebApp/WEB-INF/lib. In both cases, the dependencies are available at <Resource_Base_Path>/WEB-INF/lib and Resource_Base_Path has no relation to Project_WebApp base directory.
Questions:
Did any one use SpringExtension in a scenario similar to above? If so can you suggest any alternative approaches?
Instead of /WEB-INF/lib/company-common*.jar, we tried a classpath-based pattern but didn't work as the obtained class path resources don't match the pattern. Is there anything else to try here?

Weblogic Preprosessor in Maven

I have some Java code that is currently packaged in the BEA Workshop for WebLogic Platform.
My task is to migrate the structure of the project (without actually touching the code) to a maven structure to be packaged from command line (or from eclipse m2e).
Problem is, the code has some annotations like this:
#WebService(serviceName = "Cancelacion", targetNamespace =
"http://www.banamex.com.mx/OtorgamientoPension/cancelacion")
#WLHttpTransport(contextPath = "OtorgamientoPension", serviceUri =
"cancelacion", portName = "cancelacionSOAP")
#Policies({
#Policy(uri="policy:Wssp1.2-Wss1.0-X509-Basic256.xml", direction = Policy.Direction.inbound),
})
public class CancelacionPortImpl implements CancelacionPort {
...
}
That create some configuration inside the war (a mysterious meta-inf inside the web-inf and plenty of xml).
Please notice the #Policies which is from a WebLogic library. It creates some security-related config and that's (alongside the ws stuff) is what i want to generate.
Is there a way to process this from maven?
EDIT
So far I have tried with the weblogic-maven-plugin. It didn't work (also, due to internal policies, the not-so-straightforward way of installing this plugin is not an option).
I'm trying to find a vague reference a co-worker gave me about certain "jtools" compiler... but can't find anything that comes with that name and have some relation with WebLogic.
So the #Policies annotation is still a problem.
Right now I'm looking for a eclipse-plugin that does this, based on the premise that was the IDE who process that annotations.
For the wsdl issue, I find out that the namespace definition whas wrong. I corrected it and now it's working. I used the jaxb2-maven-plugin because I have no knowledge of jaxws-maven-plugin and I already had the config of the former.
Looks like you might need some Weblogic classes on your classpath. Short of uploading these to your own private Maven repository, you might consider checking out the Oracle Maven repository to find the Weblogic artifacts you need. Since these are likely container-provided jars (i.e. you don't need to package them in your war), you'll want to define them with a scope of "provided" in your dependencies, e.g. <scope>provided</scope>.

Package JBoss AOP interceptors with business dependencies as a standalone application

Here is my needs :
I have a WebService application running on a JBoss 5.1 (with a jboss-classloading configuration export-all=NON_EMPTY and import-all=true).
I want to add some interceptors on it but I can't change the legacy WS WAR.
What is my problems :
I managed to get working a simple interceptor packaged in a JAR that basically log every calls on legacy WebService.
But to achieve my goal, I need to use JAR dependencies like XML parsers, business objects, etc...
How can I package my AOP interceptors and its dependencies in one file ?
What I've tried :
In a WAR package, I have to use a similar jboss-classloading strategy to avoid conflicts, but in this context, I can't intercept anything else than classes in the WAR itself, so I can't intercept legacy WS calls.
PS : I have made all the basics to get JBoss AOP working properly :
pluggable-instrument.jar in bin folder
run.conf with -javaagent:pluggable-instrumentor.jar
aop.xml with loadTimeWeaving enabled and include package defined
jboss-aop.xml with valid pointcuts configurations (which I want in my package)
For now I found a solution by building a SAR package (JBoss Service Archive).
The SAR file look like this :
aop-interceptors.sar
META-INF/jboss-service.xml
aop-interceptors.jar
META-INF/jboss-aop.xml
com.mypackage.aop.interceptors...
com.mypackage.aop.handlers...
com.mypackage.aop.business.logic...
xml-parsers.jar
business-objects.jar
...
The SAR file is deployed in folder : jboss-5.1/server/default/deployers/jboss-aop-jboss5.deployer/
I don't know what SAR package is supposed to do ... is there a better way to do it ?

Using Coda Hale Yammer Metrics library in Websphere Application Server 7

I am trying to add metrics library to existing webservice on WAS 7. I am getting below error
Error 404: javax.servlet.UnavailableException: SRVE0203E: Servlet [AdminServlet]: com.yammer.metrics.reporting.AdminServlet was found, but is missing another required class. SRVE0206E: This error typically implies that the servlet was originally compiled with classes which cannot be located by the server. SRVE0187E: Check your class path to ensure that all classes required by the servlet are present.SRVE0210I: This problem can be debugged by recompiling the servlet using only the classes in the application's runtime class path SRVE0234I
What are the other run-time dependencies required for metrics-servlet-2.2.0?
I have metrics-core-2.2.0.jar and metrics-servlet-2.2.0.jar in my WEB-INF\lib folder.
Threads, ping and healthcheck servlets work fine.
I think your missing some more required jars, are you not using maven or gradle for dependency management
Please refer here to know all required jars that metrics-servlet-2.2.0.jar depends on. http://mvnrepository.com/artifact/com.yammer.metrics/metrics-servlets/3.0.0-BETA1
My suggestion is, it is always difficult to maintain dependencies without Maven/Gradle or any other build tools :).

REST client inside of OSGi application

I need to integrate a REST client into an existing OSGi application implemented using Apache Felix. The REST service is based on RESTeasy implementation (version 2.3.2.Final) of JAX-RS. I created a separate bundle with clients' dependencies, exporting required RESTeasy packages and importing them in the bundle where the client is used, but unfortunately I cannot get it working inside of the OSGi context.
I tried two different approaches. First one using the generic ClientRequest:
ClientRequest request = new ClientRequest(MyService.URL_TEST+"/stats");
request.body(javax.ws.rs.core.MediaType.APPLICATION_XML, stats);
ClientResponse<String> response = request.post(String.class);
The error that I get in this case is pretty weird:
[java] java.lang.RuntimeException: java.lang.ClassCastException:
org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor cannot be cast to
org.jboss.resteasy.client.ClientExecutor
where I it is known for sure that ApacheHttpClient4Executor implements the ClientExecutor interface.
When I try to use my own REST client wrapper around RESTeasy like this:
MyService myService = MyServiceClient.getInstance();
myService.saveStatistics(stats);
I get a different exception:
[java] java.lang.LinkageError: ClassCastException: attempting to
castjar:file:/D:/Development/Eclipses/eclipse_4.2_j2ee_x64/lib/jaxrs-api-2.3.2.Final.jar
!/javax/ws/rs/ext/RuntimeDelegate.classtobundle:
//78.0:1/javax/ws/rs/ext/RuntimeDelegate.class
As far as I understand, the LinkageError most probably has to do with the way RESTeasy initializes the RuntimeDelegate using some classloader tricks, which probably fall under the restrictions of OSGi framework. I get the suspicion that the java.lang.ClassCastException mentioned first has the same source.
Is there any way to get RESTeasy working inside of OSGi?
PS: discussion about a similar issue with RESTeasy, but outside of OSGi: java.lang.LinkageError: ClassCastException
Update:
these are the libraries included into restclient bundle:
activation-1.1.jar commons-codec-1.2.jar commons-httpclient-3.1.jar commons-io-2.1.jar commons-logging-1.0.4.jar flexjson-2.1.jar httpclient-4.1.2.jar httpcore-4.1.2.jar javassist-3.12.1.GA.jar jaxb-api-2.2.3.jar jaxb-impl-2.2.4.jar jaxrs-api-2.3.2.Final.jar jcip-annotations-1.0.jar jettison-1.3.1.jar jsr250-api-1.0.jar junit-4.10.jar log4j-1.2.14.jar resteasy-jaxb-provider-2.3.2.Final.jar resteasy-jaxrs-2.3.2.Final.jar resteasy-jettison-provider-2.3.2.Final.jar scannotation-1.0.3.jar slf4j-api-1.6.4.jar slf4j-log4j12-1.6.4.jar myservice-common-0.1.0.3.jar my-service-client-0.1.0.3-SNAPSHOT.jar stax-api-1.0-2.jar xmlpull-1.1.3.1.jar xpp3_min-1.1.4c.jar xstream-1.4.2.jar
These are the exports from the restclient bundle: javax.ws.rs, javax.ws.rs.ext, javax.ws.rs.core, org.jboss.resteasy.client, org.jboss.resteasy.client.cache, org.jboss.resteasy.client.extractors, org.jboss.resteasy.client.marshallers, org.jboss.resteasy.client.core.executors, javax.xml.bind.annotation, org.jboss.resteasy.plugins.providers, org.jboss.resteasy.plugins.providers.jaxb, org.jboss.resteasy.spi
Have a look at the SpringSource Bundle Repo, it's got some very useful pre-built bundles of common libraries including the Apache HTTP Client which we are using (in conjunction with gson) to do our RESTful comms.
(unfortunately a legacy module of my project still uses OSGi, but using RESTeasy 3.0.16 now)
When I need to OSGify a dependency my preferred solution now is to wrap it using the excellent Apache Ops4j Pax Tipi project.
The project provides a preconfigured Maven setup (parent POM handles the bundling) and you just have to adapt the GAV coordinates of the original project in a Tipi sub module with a org.apache.ops4j.pax.tipi prefix and build the new bundle project which draws in the original dependency, unpacks and wraps it as OSGi bundle.
You can start from an existing Tipi sub project that best matches your project setup (dependencies, etc.) and adapt any OSGi imports/exports missing (most often, these are created automatically by the maven-bundle-plugin anyway).
This worked quite well for me as long as the original project did not contain too many exotic or malformed dependencies.
However you may run into snags like transitive dependencies using the root package, as I currently experience, which can be a real show stopper (finding out which library is a real nightmare).
Unfortunately, RESTeasy seems to be affected by this, as I get exactly the same error (default package , even after declaring non-test and non-provided dependencies as optional:
The default package '.' is not permitted by the Import-Package syntax.
Upgrading the maven-bundle-plugin to the latest release 3.0.1 yields a different error (even less helpful):
[ERROR] Bundle org.ops4j.pax.tipi:org.ops4j.pax.tipi.resteasy-jaxrs:bundle:3.0.16.Final.1 : Can not parse name from bundle native code header:
[ERROR] Error(s) found in bundle configuration
Update seems to be solved by upping Tipi version in POM to 1.4.0, testing...
Is RESTEasy mandatory ?
I personally use jersey in OSGi and it is working perfectly, both as client and server.
This problem isn't limited to RESTeasy. It also occurs with Jersey.
It is occurring because you have two copies of the JAX-RS classes on the classpath.
You can see this in the LinkageError:
[java] java.lang.LinkageError: ClassCastException: attempting to cast jar:file:/D:/Development/Eclipses/eclipse_4.2_j2ee_x64/lib/jaxrs-api-2.3.2.Final.jar!/javax/ws/rs/ext/RuntimeDelegate.class to bundle://78.0:1/javax/ws/rs/ext/RuntimeDelegate.class
i.e. one copy is coming from:
D:/Development/Eclipses/eclipse_4.2_j2ee_x64/lib/jaxrs-api-2.3.2.Final.jar
and the other from the OSGI bundle.
This causes problems for the RuntimeDelegate class, which by default uses the system class loader to create the RuntimeDelegate implementation (see javax.ws.rs.ext.FactoryFinder).
The problem can also occur if the same jar is loaded via two different class loaders.
There are a couple of workarounds:
remove the jaxrs-api-2.3.2.Final.jar from the system class path
set the thread context class loader to that of your bundle, prior to making any JAX-RS calls.
The FactoryFinder will use this to load the RuntimeDelegate.
To avoid polluting your code with calls to Thread.currentThread().setContextClassLoader(myBundleClassLoader), you can wrap your JAX-RS client using a Proxy. e.g. see the Thread context classloader section of https://puredanger.github.io/tech.puredanger.com/2007/06/15/classloaders/

Categories

Resources