JAXB: class cast exception, but class has the same name - java

I have a interesting problem.
When I started glassfish server, everythings work fine. But, I changed some code and published the server, and I run my client (SistemGirisClientKullaniciDogrula). The application throws this exception:
java.lang.ClassCastException: tr.com.app.Kullanici cannot be cast to tr.com.app.Kullanici.
Interesting part is, after the Glassfish server restart, application works fine.
I am using restlet-spring-hibernate. And I am also using JAXB (org.restlet.ext.jaxb.jar) for converting XML to Java objects. My application server is Glassfish v3.0
detail for congiguration
restlet 2.0.5
spring 3.0.5
hibernate 3.3.2
glassfish v3.0
client class(Just for test)
import java.io.IOException;
import org.restlet.Client;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Protocol;
import org.restlet.ext.jaxb.JaxbRepresentation;
public class SistemGirisClientKullaniciDogrula {
public static void main(String[] Args) throws IOException {
String url = "http://localhost:8080/Project/sistemgirisws";
Client client = new Client(Protocol.HTTP);
Kullanici kullanici = new Kullanici();
kullanici.setKodu("1");
JaxbRepresentation<Kullanici> jaxbRepresentationSendingKullanici= new JaxbRepresentation<Kullanici>(MediaType.APPLICATION_XML, kullanici);
Request request = new Request(Method.GET, url, jaxbRepresentationSendingKullanici);
Response response = client.handle(request);
JaxbRepresentation<Kullanici> kullaniciResponse = new JaxbRepresentation<Kullanici>(response.getEntity(), Kullanici.class);
kullanici = kullaniciResponse.getObject();
System.out.println("kullanici id : " + kullanici.getId());
}
}
Web Service
public class ProjectWebService {
/**
*
* #param representation
* #return
*/
#Get
public Representation getKullanici(Representation representation) {
JaxbRepresentation<Kullanici> jaxbRepresentation = new JaxbRepresentation<Kullanici>(representation, Kullanici.class);
Kullanici kullanici = new Kullanici();
try {
kullanici = jaxbRepresentation.getObject(); //THIS LINE THROW java.lang.classCastException tr.com.app.Kullanici cannot be cast to tr.com.app.Kullanici.
} catch (IOException e) {
e.printStackTrace();
}
try {
kullanici = sistemGirisBusinessManager.kullaniciDogrula(kullanici);
getResponse().setStatus(Status.SUCCESS_OK);
return new JaxbRepresentation<Kullanici>(MediaType.APPLICATION_XML, kullanici);
} catch (Exception exception) {
exception.printStackTrace();
getResponse().setStatus(Status.CLIENT_ERROR_EXPECTATION_FAILED);
return new JaxbRepresentation<MesajList>(MediaType.APPLICATION_XML, sistemGirisBusinessManager.getMesajList());
}
}
}
Does Anyone know what the problem is?

This could be a class loading issue. In Java, If two classloaders have loaded the same class, then it is treated as two different classes. In that case, your casting will fail because it seems to the JVM that you are casting one type to another which is not in an inheritance tree.
What must be happening is that when you modify your class, it gets loaded into a different classloader, where as the web service uses the original one.

Problem indeed in different class loaders. i've had it too and adding implements Serializable and serialVersionUID for those object solved the problem.

Related

Adding REST route to an existing Jetty endpoint in Camel at runtime

I have been inventing a way how to work around the problem of adding consumers to a jetty endpoint (it does not allow multiple consumers). The way we do it in our company is to build our own router and a broadcasting endpoint which consumes from jetty and routes requests to underlying "subscriptions". Only one of them will eventually process the request. It kind of works but it's not completely ok, since recently when updating to latest Camel we have found our custom built component to leak memory and in general I consider using built-in functionality over custom hacks.
I started investigating the Camel REST API and found it very nice and pretty much replacing our home-grown component apart from one thing - you cannot re-configure it at runtime - you have to stop the context basically for this to work. Below I include my unit test with a happy path and the path that fails. Frankly I think is a bug, but if there is a legitimate way to achieve what I want, I'd like to hear sound advice:
package com.anydoby.camel;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
/**
* Test tries to add/remove routes at runtime.
*/
public class RoutesTest {
private DefaultCamelContext ctx;
#Before
public void pre() throws Exception {
ctx = new DefaultCamelContext();
new RouteBuilder(ctx) {
#Override
public void configure() throws Exception {
restConfiguration("jetty").host("localhost").port(8080);
rest("/")
.get("/issues/{isin}").route().id("issues")
.process(e -> e.getOut().setBody("Here's your issue " + e.getIn().getHeader("isin"))).endRest()
.get("/listings").route().id("listings").process(e -> e.getOut().setBody("some listings"));
}
}.addRoutesToCamelContext(ctx);
ctx.start();
}
#Test
public void test() throws IOException {
{
InputStream stream = new URL("http://localhost:8080/issues/35").openStream();
assertEquals("Here's your issue 35", IOUtils.toString(stream));
}
{
InputStream stream = new URL("http://localhost:8080/listings").openStream();
assertEquals("some listings", IOUtils.toString(stream));
}
}
#Test
public void disableRoute() throws Exception {
ctx.stopRoute("issues");
ctx.removeRoute("issues");
try (InputStream stream = new URL("http://localhost:8080/issues/35").openStream()) {
fail();
} catch (Exception e) {
}
new RouteBuilder(ctx) {
#Override
public void configure() throws Exception {
rest().get("/issues/{isin}/{sedol}").route().id("issues")
.process(e -> e.getOut()
.setBody("Here's your issue " + e.getIn().getHeader("isin") + ":" + e.getIn().getHeader("sedol")))
.endRest();
}
}.addRoutesToCamelContext(ctx);
{
InputStream stream = new URL("http://localhost:8080/issues/35/65").openStream();
assertEquals("Here's your issue 35:65", IOUtils.toString(stream));
}
}
}
The disableRoute() test fails since I cannot add another consumer to an existing endpoint.
So my question is - "is there a way to add a new URL mapping to a restful camel-jetty endpoint"? If you do it during first configuration it works fine, but when later you want to reconfigure one of the routes the error is:
org.apache.camel.FailedToStartRouteException: Failed to start route because of Multiple consumers for the same endpoint is not allowed: jetty:http://localhost:8080/issues/%7Bisin%7D/%7Bsedol%7D?httpMethodRestrict=GET

Axis Sample AddressBook exception

I have 2 questions
I am trying to run a axis 2 sample. In the last part of the instruction file, there is this line which it says, should be run in the terminal(ubuntu), is not working
java -Djava.ext.dirs=%AXIS2_HOME%\lib;%JAVA_HOME%\jre\lib\ext -cp target/classes org.apache.axis2.jaxws.addressbook.AddressBookClient.class
I am not an expert in this field, and I am not familiar with ubuntu commands. I feel that this is not an ubuntu command
The error I get is, "Invalid Job"
Can someone convert this into an ubuntu command?
Since it was not working, I built the jar using,
mvn clean install
Then I copied the jar file to the servicejars directory under repository, in axis2
Then the axis server says that the jar does not contain the WebServices annotation
"No #WebService annotated service implementations found in the jar: file:/home/dodan/Programs/axis2-1.6.0/repository/servicejars/jaxws-addressbook-1.6.0-client.jar. Service deployment failed."
So I added it to the original java file which did not have that annotation(and the import too)
Yet the axis2 server still sys that there is not webservices annotation
2. Can somebody say whether I have missed anything?
here is the java file I changed
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.jws.WebService;
import java.util.Map;
/**
* Simple JAX-WS Dispatch client for the address book service implementation.
*/
#WebService
public class AddressBookClient {
private static String NAMESPACE = "http://addressbook.jaxws.axis2.apache.org";
private static QName QNAME_SERVICE = new QName(NAMESPACE, "service");
private static QName QNAME_PORT = new QName(NAMESPACE, "port");
private static String ENDPOINT_URL = "http://localhost:8080/axis2/services/AddressBookImplService.AddressBookImplPort";
private static String ADD_ENTRY_BODY_CONTENTS =
"<ns1:addEntry xmlns:ns1=\"http://addressbook.jaxws.axis2.apache.org\">" +
"<ns1:firstName xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myFirstName</ns1:firstName>" +
"<ns1:lastName xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myLastName</ns1:lastName>" +
"<ns1:phone xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myPhone</ns1:phone>" +
"<ns1:street xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myStreet</ns1:street>" +
"<ns1:city xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myCity</ns1:city>" +
"<ns1:state xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myState</ns1:state>" +
"</ns1:addEntry>";
private static String FIND_BODY_CONTENTS =
"<ns1:findByLastName xmlns:ns1=\"http://addressbook.jaxws.axis2.apache.org\">" +
"<ns1:lastName xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myLastName</ns1:lastName>" +
"</ns1:findByLastName>";
public static void main(String[] args) {
try {
System.out.println("AddressBookClient ...");
Service svc = Service.create(QNAME_SERVICE);
svc.addPort(QNAME_PORT, null, ENDPOINT_URL);
// A Dispatch<String> client sends the request and receives the response as
// Strings. Since it is PAYLOAD mode, the client will provide the SOAP body to be
// sent; the SOAP envelope and any required SOAP headers will be added by JAX-WS.
Dispatch<String> dispatch = svc.createDispatch(QNAME_PORT,
String.class, Service.Mode.PAYLOAD);
// Invoke the Dispatch
System.out.println(">> Invoking sync Dispatch for AddEntry");
String response = dispatch.invoke(ADD_ENTRY_BODY_CONTENTS);
System.out.println("Add Entry response: " + response);
System.out.println(">> Invoking Dispatch for findByLastName");
String response2 = dispatch.invoke(FIND_BODY_CONTENTS);
System.out.println("Find response: " + response2);
} catch (Exception e) {
System.out.println("Caught exception: " + e);
e.printStackTrace();
}
}
}
You're using Windows syntax for environment variables.
Instead of %AXIS_HOME%, you would use $AXIS_HOME.
That said, you do not need any version of Axis to learn about web services these days. JAX-WS implementations exist in the JDK for Java 6 and newer.
There's a lot of tutorials around for it.

How Do I write a client using axis2 to send a serialized xml object to a web service?

I'm having a conceptual problem preventing me from solving a trivial problem. I need to send an object to a web service. I have an endpoint, and I have code that can serialize the object, so I can create an org.jdom.Document or a byte[] object containing the serialized object.
I can also create a client snippet that uses axis2 to invoke the web service.
Finally I have tried sending a manually created message to the web service (it has no WSDL ;( )
AND I have used Charles to see what is going out (the request).
What I don't know how to do is convert the byte[] or org.jdom.Document object to an OMElement object. Evidently the serviceClient.sendReceive(elem) takes an OMElement parameter.
Here is what I tried so far (I removed the OMElement that I sent out once I was convinced it was going out):
package testAxis2Client01;
import java.util.Map;
import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.transport.http.HTTPConstants;
public class testAxis2Client01 {
private static final int MXMOCONNECTIONTIMEOUT = 2;//don't really know what this should be.
/**
* #param args
*/
public static void main(String[] args) {
try {
callAxisWS();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void callAxisWS() throws XMLStreamException, Exception {
//Axis2 client code to call a WS
OMElement response=null;
try{
OMFactory factory = OMAbstractFactory.getSOAP11Factory();
SOAPEnvelope theEnvelope = OMAbstractFactory.getSOAP12Factory().getDefaultEnvelope();
theEnvelope.declareNamespace("http://www.w3.org/2001/XMLSchema","xsd");
theEnvelope.declareNamespace("http://www.w3.org/2001/XMLSchema-instance","xsi");
ServiceClient serviceClient = new ServiceClient();
Options options = serviceClient.getOptions();
options.setProperty(HTTPConstants.AUTO_RELEASE_CONNECTION, true); // Another API to release connection.
options.setTimeOutInMilliSeconds(10000); // Setting the connection timeout.
EndpointReference targetEPR = new EndpointReference(theUrl);
options.setTo(targetEPR);
options.setAction("processDocument");
serviceClient.setOptions(options);
//response = serviceClient.sendReceive(myOMElement);
response = serviceClient.sendReceive(elem)
if (response != null) {
System.out.println("SUCCESS!!");
System.out.println(response.toStringWithConsume());
}
}catch(Exception af){
af.printStackTrace();
System.out.println(af.getMessage());
}
}
}
The point of using axis2 is that it takes care of everything. You only have to provide a wsdl file and it will generate client stubs.
If you do not have an original wsdl, you can still make one yourself.
The best way for you is to create the wsdl file manually, generate the client stub and call the stub directly.

NoSuchMethodError showing for Jira when Java running as Web application, But gets output when running in main

I am creating a Java web application. I added Jira API jars for connecting to Jira to get Issues created in Jira.
And this is my Java program to get the issues
import java.net.URI;
import java.net.URISyntaxException;
import com.atlassian.jira.rest.client.JiraRestClient;
import com.atlassian.jira.rest.client.NullProgressMonitor;
import com.atlassian.jira.rest.client.domain.Issue;
import com.atlassian.jira.rest.client.internal.jersey.JerseyJiraRestClientFactory;
public class AppJIRADataCollector {
final static JerseyJiraRestClientFactory factory = new JerseyJiraRestClientFactory();
public static void main(String args[])
{
AppJIRADataCollector appJira=new AppJIRADataCollector();
appJira.getIssues("http://localhost:8080/", "AP-1", "admin", "admin");
}
public void getIssues(String issueURI,String issueKey,String username, String password) {
try {
final URI jiraServerUri = new URI(issueURI);
final JiraRestClient restClient = factory.createWithBasicHttpAuthentication(jiraServerUri,username, password);
System.out.println(restClient);
final NullProgressMonitor pm = new NullProgressMonitor();
final Issue issue = restClient.getIssueClient()
.getIssue(issueKey, pm);
System.out.println(issue);
} catch (URISyntaxException e) {
System.out.println("URI not found");
e.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
When I run this program, I am getting the output correctly as it prints the issues.
But when I run this as web application, and calling the getIssues() method from servlet, tomcat showing NoSuchMethodError
Here is the stack trace
java.lang.NoSuchMethodError: com.google.common.collect.Iterables.contains(Ljava/lang/Iterable;Ljava/lang/Object;)Z
com.atlassian.jira.rest.client.internal.json.IssueJsonParser.parse(IssueJsonParser.java:216)
com.atlassian.jira.rest.client.internal.json.IssueJsonParser.parse(IssueJsonParser.java:59)
com.atlassian.jira.rest.client.internal.jersey.AbstractJerseyRestClient$1.call(AbstractJerseyRestClient.java:85)
com.atlassian.jira.rest.client.internal.jersey.AbstractJerseyRestClient.invoke(AbstractJerseyRestClient.java:54)
com.atlassian.jira.rest.client.internal.jersey.AbstractJerseyRestClient.getAndParse(AbstractJerseyRestClient.java:80)
com.atlassian.jira.rest.client.internal.jersey.JerseyIssueRestClient.getIssue(JerseyIssueRestClient.java:131)
com.atlassian.jira.rest.client.internal.jersey.JerseyIssueRestClient.getIssue(JerseyIssueRestClient.java:123)
com.domain.jirademo.adapters.AppJIRADataCollector.getIssues(AppJIRADataCollector.java:22)
com.domain.jirademo.controllers.ProjectDefectsServlet.doPost(ProjectDefectsServlet.java:50)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
Why this is happening? Any problem with JARs? I am using maven. If want I will post the pom also.
EDIT
I added the main method later only. So in the stack trace, line 22 refers to
final Issue issue = restClient.getIssueClient()
.getIssue(issueKey, pm);
NoSuchMethodError it's caused by a version mismatch, you should check your version of guava library.

How to browse the file system of a server machine when connecting with a client (java)

I'm in the process of making a proof of concept to dissociate the business code from the gui for the ps3 media server (http://www.ps3mediaserver.org/). For this I've got a project hosted at source forge (http://sourceforge.net/projects/pms-remote/). The client should be a simple front end to configure the server from any location within a network having the rights to connect to the server.
On the server side, all service have been exposed using javax.jws and the client proxy has been generated using wsimport.
One of the features of the current features (actually, the only blocking one), is to define the folders that will be shared by the server. As the client and server are now running as a single application on the same machine, it's trivial to browse its file system.
Problem: I'd like to expose the file system of the server machine through web services. This will allow any client (the one I'm currently working on is the same as the original using java swing) to show available folders and to select the ones that will be shown by the media server. In the end the only thing I'm interested in is an absolute folder path (string).
I thought I'd find a library giving me this functionality but couldn't find any.
Browsing the files using a UNC path and accessing a distant machine doesn't seem feasible, as it wouldn't be transparent for the user.
For now I don't want to worry about security issues, I'll figure these out once the rest seems feasible.
I'd be grateful for any input.
Thanks, Philippe
I've ended up creating a pretty simple web service letting either list all root folders or all child folders for a given path.
It's now up to the client to have a (GUI) browser to access this service.
package net.pms.plugin.webservice.filesystem;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import net.pms.plugin.webservice.ServiceBase;
#WebService(serviceName = "FileSystem", targetNamespace = "http://ps3mediaserver.org/filesystem")
public class FileSystemWebService extends ServiceBase {
#WebMethod()
public List<String> getRoots() {
List<String> roots = new ArrayList<String>();
for(File child : File.listRoots()) {
roots.add(child.getAbsolutePath());
}
return roots;
}
#WebMethod()
public List<String> getChildFolders(#WebParam(name="folderPath") String folderPath) throws FileNotFoundException {
List<String> children = new ArrayList<String>();
File d = new File(folderPath);
if(d.isDirectory()) {
for(File child : d.listFiles()) {
if(child.isDirectory() && !child.isHidden()) {
children.add(child.getAbsolutePath());
}
}
} else {
throw new FileNotFoundException();
}
return children;
}
}
For people wanting to use this, here's the ServiceBase class as well
package net.pms.plugin.webservice;
import javax.xml.ws.Endpoint;
import org.apache.log4j.Logger;
public abstract class ServiceBase {
private static final Logger log = Logger.getLogger(ServiceBase.class);
protected boolean isInitialized;
/**
* the published endpoint
*/
private Endpoint endpoint = null;
/**
*
* Start to listen for remote requests
*
* #param host ip or host name
* #param port port to use
* #param path name of the web service
*/
public void bind(String host, int port, String path) {
String endpointURL = "http://" + host + ":" + port + "/" + path;
try {
endpoint = Endpoint.publish(endpointURL, this);
isInitialized = true;
log.info("Sucessfully bound enpoint: " + endpointURL);
} catch (Exception e) {
log.error("Failed to bind enpoint: " + endpointURL, e);
}
}
/**
* Stop the webservice
*/
public void shutdown() {
log.info("Shut down " + getClass().getName());
if (endpoint != null)
endpoint.stop();
endpoint = null;
}
}
From the client, you might be able to leverage the output of smbclient -L. On the server, a suitable servlet might do.

Categories

Resources