Spring Jax-ws service with JBOSS 5.1.0 giving Introspection Exception - web-services

Hi I am developing a Spring -Jaxws web service using JBOSS 5. I am using "SimpleJaxWsServiceExporter" to deploy the service. My service endpoint is :
package com.pb.pts.spring.service;
#Component
#WebService(serviceName="ParcelTrackingService")
public class ParcelTrackingServiceEndpoint {
#Autowired
public ParcelTrackingService trackingService;
#WebMethod
public String createParcelDetails(ParcelDetails details) throws TrackingException{
return trackingService.createParcelDetails(details);
}
#WebMethod
public ParcelTrackingData getParcelTrackingDetails(ParcelTrackingRequestData requestData) throws TrackingException{
return trackingService.getParcelTrackingDetails(requestDa ta);
}
}
The TrackingException class is :
public class TrackingException extends Exception {
private TrackingError[] errors;
public TrackingException() {
super();
this.errors = null;
}
public TrackingError[] getErrors() {
return errors;
}
public void setErrors(TrackingError[] errors) {
this.errors = errors;
}
}
I get the following error while deploying on jboss :
org.jboss.ws.WSException: Property 'errors' not found in fault bean 'com.pb.pts.spring.service.jaxws.TrackingException Bean'
at org.jboss.ws.metadata.umdm.FaultMetaData.initializ eFaultBean(FaultMetaData.java:282)
at org.jboss.ws.metadata.umdm.FaultMetaData.eagerInit ialize(FaultMetaData.java:225)
at org.jboss.ws.metadata.umdm.OperationMetaData.eager Initialize(OperationMetaData.java:468)
at org.jboss.ws.metadata.umdm.EndpointMetaData.eagerI nitializeOperations(EndpointMetaData.java:559)
at org.jboss.ws.metadata.umdm.EndpointMetaData.initia lizeInternal(EndpointMetaData.java:543)
at org.jboss.ws.metadata.umdm.EndpointMetaData.eagerI nitialize(EndpointMetaData.java:533)
at org.jboss.ws.metadata.umdm.ServiceMetaData.eagerIn itialize(ServiceMetaData.java:433)
at org.jboss.ws.metadata.umdm.UnifiedMetaData.eagerIn itialize(UnifiedMetaData.java:194)
at org.jboss.wsf.stack.jbws.EagerInitializeDeployment Aspect.start(EagerInitializeDeploymentAspect.java: 48)
at org.jboss.wsf.framework.deployment.DeploymentAspec tManagerImpl.deploy(DeploymentAspectManagerImpl.ja va:129)
at org.jboss.wsf.container.jboss50.deployer.ArchiveDe ployerHook.deploy(ArchiveDeployerHook.java:76)
at org.jboss.wsf.container.jboss50.deployer.AbstractW ebServiceDeployer.internalDeploy(AbstractWebServic eDeployer.java:60)
at org.jboss.deployers.spi.deployer.helpers.AbstractR ealDeployer.deploy(AbstractRealDeployer.java:55)
at org.jboss.deployers.plugins.deployers.DeployerWrap per.deploy(DeployerWrapper.java:179)
... 29 more
Caused by: java.beans.IntrospectionException: Method not found: isErrors
at java.beans.PropertyDescriptor.<init>(PropertyDescr iptor.java:89)
at java.beans.PropertyDescriptor.<init>(PropertyDescr iptor.java:53)
at org.jboss.ws.metadata.umdm.FaultMetaData.initializ eFaultBean(FaultMetaData.java:271)
It say " Method not found: isErrors" inspite of the fact that errors is not a boolean.
Can you please provide some insight into this problem? Any help would be appreciated.

I found a solution to the problem.. This is the java doc for SimpleJaxwsServiceExporter.
"Note that this exporter will only work if the JAX-WS runtime actually
supports publishing with an address argument, i.e. if the JAX-WS runtime
ships an internal HTTP server. This is the case with the JAX-WS runtime
that's inclued in Sun's JDK 1.6 but not with the standalone JAX-WS 2.1 RI."
So a SimpleJaxwsServiceExporter web service implementation using spring will work on Tomcat but not on JBoss as JBoss has it own implementation of JAX-WS.
So I deployed a pure Jax-ws web service without spring support and that worked.

Related

Best API / lib to unit test Jersey Restful Web Services?

What is the best library / API to unit test Jersey based Restful Web Services? Some APIs like JerseyTest seem outdated (had conflicts when using them in my pom) and also seem to be depending on a particular container, such as Glassfish or Grizzly... I am deploying my Jersey based Restful Web Services as a war file into Tomcat 7. Is there a way to use a testing framework which has an embedded web server or in-memory solution? Thanks again.
There are couple of frameworks that I am aware of atleast :
REST-EASY : http://www.hascode.com/2011/09/rest-assured-vs-jersey-test-framework-testing-your-restful-web-services/
Jersey Test Framework : https://jersey.java.net/documentation/1.17/test-framework.html
Jersey test Framework is easier to use.
I'm using rest-assured for many of my projects as it offers a highly specialized dsl to write your tests and once you've grown custom to the notation, writing tests is done really quick.
A variety of examples can be found on the project website but for a quick preview - a sample test could look like this snippet:
expect()
.statusCode(200)
.body("user.id", equalTo(1))
.when()
.given()
.contentType(ContentType.JSON)
.get("http://test/rest");
As my blog was quoted by Balaji, I'd like to add that there is this article of mine with more examples for the rest-assured framework and also a downloadable REST-server for testing the examples.
A test example with jersey-test could look like this example taken from the project's documentation:
public class SimpleTest extends JerseyTest {
#Path("hello")
public static class HelloResource {
#GET
public String getHello() {
return "Hello World!";
}
}
#Override
protected Application configure() {
return new ResourceConfig(HelloResource.class);
}
#Test
public void test() {
final String hello = target("hello").request().get(String.class);
assertEquals("Hello World!", hello);
}
}

EJB Web Service ClassNotFoundException

Server: JBoss 7.1.1
EJB 3.0
Eclipse Juno
I am working through my first webservice project using ejb 3.0 and am running into a problem on my client. For my client, I made up a servlet. The problem is when I attempt:
CalculatorOps calculator = (CalculatorOps)context.lookup("java:global/EJBCalculatorWS/CalculatorImp!math.CalculatorOps");
I am getting ClassNotFoundException on the lookup. I got this jndi from my JBoss server.log
[org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-3) JNDI bindings for session bean named CalculatorImp in deployment unit deployment "EJBCalculatorWS.war" are as follows:
java:global/EJBCalculatorWS/CalculatorImp!math.CalculatorOps
java:app/EJBCalculatorWS/CalculatorImp!math.CalculatorOps
java:module/CalculatorImp!math.CalculatorOps
I have 2 web projects, WS and Client, both added to the server and WS is in the build path of Client.
-------------CODE------------
Interface
package math;
#Local
public interface CalculatorOps {
public int add(int a, int b);
public int subtract(int a, int b);
}
Class
package math;
#Stateless(mappedName="TheCalc")
#WebService
public class CalculatorImp implements CalculatorOps{
#Override
public int add(int a, int b) {
return a+b;
}
#Override
public int subtract(int a, int b) {
return a-b;
}
}
Servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
CalculatorOps calculator = (CalculatorOps)context.lookup("java:global/EJBCalculatorWS/CalculatorImp!math.CalculatorOps");
}
Fixed: I ended up fixing this problem by placing the client and the ejb packages together in one project, then using the new jndi. I would still like to know tho why across multiple projects, I cant add to build path and then use the jndi to reference the ejbs without a ClassNotFoundException thrown.
If you are using eclipse, you need to add the EJB project to the deployment assembly of your web project to get it working, Build path will only exist for compilation but you get the error during run time if I am right.
RightClick on your web project->Properties->Deployment Assembly->Add

Runtime exception with jersey - java.lang.AbstractMethodError

I am trying to execute a RESTful web service deployed on tomcat using Jersey implementation.
Following is the resource class
#Path("/rest")
public class PatientResource {
PatientService patientService;
#GET
#Path("/patient/{patientId}")
#Produces(MediaType.APPLICATION_JSON)
public Patient getPatientDetails(#PathParam("patientId") String patientId) {
//return patientService.getPatientDetails(patientId);
return new PatientService().getPatientDetails(patientId);
}
#GET
#Path("/patients")
#Produces(MediaType.APPLICATION_JSON)
public PatientData<Patient> getAllPatients() {
//return patientService.getAllPatients();
return new PatientService().getAllPatients();
}
}
I have made necessary entries in web.xml and all necessary jars are available in classpath, however when application is started on tomcat and I enter the URL in browser, I get following exception
[Servlet execution threw an exception] with root cause
java.lang.AbstractMethodError
at org.codehaus.jackson.map.AnnotationIntrospector$Pair.findSerializer(AnnotationIntrospector.java:1148)
at org.codehaus.jackson.map.ser.BasicSerializerFactory.findSerializerFromAnnotation(BasicSerializerFactory.java:367)
at org.codehaus.jackson.map.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:252)
at org.codehaus.jackson.map.ser.StdSerializerProvider._createUntypedSerializer(StdSerializerProvider.java:782)
Any idea how to resolve it ?
Probably an inconsistency in the versions of Jersey and Jackson you are using at runtime .
What are your libs versions ?

CXF and Spring #Configurable issue

I am currently fronting issues mixing a CXF web service with Spring #Configurable annotation.
From one side I have my CXF web service fully working and configured like this :
<import resource="classpath:some-other-context.xml" />
<jaxws:server id="Init"
serviceClass="package.to.my.ServiceInterface"
address="/">
<jaxws:serviceBean>
<bean class="package.to.my.BADematInitImpl">
</bean>
</jaxws:serviceBean>
</jaxws:server>
<context:spring-configured />
And in my some-other-context.xml is my Spring configuration containing the following Bean's :
#Configurable(autowire = Autowire.BY_TYPE)
public class MyConfigurable {
#Autowired(required=true)
private A a;
#Autowired(required=true)
private B b;
#Autowired(required=true)
private C c;
...
}
But when I try to create a new instance of MyConfigurable bean into my service, I get a NullPointerException due to the null valued supposed-autowired A,B and C objects.
Any idea ?
#Configurable is a marker used by the AOP load-time-weaving stuff. I assume you are not using any AOP, because there is nothing mentioned about it in your question. Second thing: you don't have to use required=true in your #Autowired annotation as true is the default value of required. I would suggest you to change your code like this:
Add these to elements in your spring configuration file:
<context:component-scan base-package="your.pckg.toscan"/>
Documentation says:
Scans the classpath for annotated components that will be
auto-registered as Spring beans. By default, the Spring-provided
#Component, #Repository, #Service, and #Controller stereotypes will
be detected.
<context:annotation-config/>
Documentation says:
Activates various annotations to be detected in bean classes: Spring's
#Required and #Autowired, as well as JSR 250's #PostConstruct,
#PreDestroy and #Resource (if available), JAX-WS's #WebServiceRef (if
available), EJB3's #EJB (if available), and JPA's #PersistenceContext
and #PersistenceUnit (if available). Alternatively, you may choose to
activate the individual BeanPostProcessors for those annotations.
So changing your code to:
#Component
public class MyConfigurable {
#Autowired
private A a;
#Autowired
private B b;
#Autowired
private C c;
...
}
Everything should work just fine.
I finally found out the problem.
I needed to add this configuration into my third-part application XML files :
<context:load-time-weaver/>
... and add this argument to my jvm launch command line :
-javaagent:"path\to\my\spring-agent.jar"
And it just works like a charm.
I understand that this is because Spring needs at some point to have an entity managing its AOP part so that the dependencies are well injected. It would be interesting if someone had further explanations.

Passing Objects to a Web Service's method

I have recently started working on (Java)Web Services.
I have certain web methods that accept different arguments - primitives,Maps,HttpServletRequest,FlowJob(Spring) etc.
I got numerous issues while attempting this - from a failed web service deployment saying 'interfaces not supported by JAX-WS' to runtime exceptions 'java.lang.Object cannot be cast to org.w3c.dom.Element' !
I have not put the steps deliberately;all I need to know is that is it possible to pass the above arguments to a Java Web Service method? In short,is something like this possible :
#WebService(serviceName = "WS")
public class WS {
#WebMethod
public Object processJob(MapargsMap){
}
#WebMethod
public String processJob(SomeCustomObject object){
}
}
}
Are there any work-arounds to make JAXB marshal and unmarshal custom objects,Maps etc.?If yes,what are they?
Thanks & regards !