Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClassCastException is thrown if Jersey is used. #14

Open
lordofthejars opened this issue Jan 8, 2014 · 19 comments
Open

ClassCastException is thrown if Jersey is used. #14

lordofthejars opened this issue Jan 8, 2014 · 19 comments

Comments

@lordofthejars
Copy link
Member

I am using Arquillian-Rest-Extension to test REST services. The server part is implemented using Jersey (not RestEasy). The problem is that when query params are set a classcastexception is thrown.

java.lang.ClassCastException: org.glassfish.jersey.uri.internal.JerseyUriBuilder cannot be cast to org.jboss.resteasy.specimpl.ResteasyUriBuilder
    at org.jboss.resteasy.client.jaxrs.internal.ClientWebTarget.queryParamNoTemplate(ClientWebTarget.java:287)
    at org.jboss.resteasy.client.jaxrs.internal.proxy.processors.webtarget.QueryParamProcessor.apply(QueryParamProcessor.java:23)
    at org.jboss.resteasy.client.jaxrs.internal.proxy.processors.webtarget.QueryParamProcessor.apply(QueryParamProcessor.java:12)

The problem is at line 287 where there are a clone and a cast:

ResteasyUriBuilder copy = (ResteasyUriBuilder)uriBuilder.clone();
for (String obj : stringValues)
{
    copy.clientQueryParam(name, obj);
}

copy should be casted not to the interface UriBuilder but to ResteasyUriBuilder because clientQueryParam is a method from that class. Of course it can be very solutions to that problem:

  • implement an ArquillianJerseyResource annotation
  • ?¿maybe exclude Jersey dependency from test?¿ But then server won't receive it and I need it because it is a Tomcat.
  • maybe calling replaceQueryParam which is a method from UriBuilder interface.

WDYT?

@blabno
Copy link
Member

blabno commented Jan 8, 2014

@lordofthejars This code should be run only in @RunAsClient mode because rest client is rest created only using RestEasy. Although John Ament has created pure JAX-RS impl of the extension. But allow me to look at it later today.

@lordofthejars
Copy link
Member Author

Take your time don't worry. BTW The test is already run with @RunAsClient annotation. If you need I will push the code to github, there is no problem about that.

@blabno
Copy link
Member

blabno commented Jan 8, 2014

@lordofthejars such testcase would be very welcome.

@lordofthejars
Copy link
Member Author

This afternoon (20:00 CET) I will push the code and send you the link.
Thank you so much.

2014/1/8 Bernard Labno [email protected]

@lordofthejars https://github.com/lordofthejars such testcase would be
very welcome.


Reply to this email directly or view it on GitHubhttps://github.com//issues/14#issuecomment-31812825
.

+----------------------------------------------------------+
Alex Soto Bueno - Computer Engineer
www.lordofthejars.com
+----------------------------------------------------------+

@juancasta
Copy link

Hello.

I am facing same problem. I want to user arquillian persistence extension with webservices deployed in glassfish, so the implementation is Jersey.

Did you solve it? I am checking the code in te repo.

Thanks.

@lordofthejars
Copy link
Member Author

I have git a running example with apache TomEE which used apache cxf and I remember doing some hacking let me find the example and I send you the link

Enviat des del meu iPhone

El 16/05/2014, a les 11.33, juancasta [email protected] va escriure:

Hello.

I am facing same problem. I want to user arquillian persistence extension with webservices deployed in glassfish, so the implementation is Jersey.

Did you solve it? I am checking the code in te repo.

Thanks.


Reply to this email directly or view it on GitHub.

@juancasta
Copy link

Thanks!

@blabno
Copy link
Member

blabno commented May 17, 2014

maybe exclude Jersey dependency from test?¿ But then server won't receive it and I need it because it is a Tomcat.

I think that the problem is embedded mode for Tomcat. As I understand it, Tomcat uses same classpath as tests, so in order for Tomcat to run with Jersey, it needs to be on classpath, but this way, dependencies of RestEasy Client (used by our extension) get substituted by jersey.

Solution 1 (not perfect): avoid embedded mode and run in managed mode.
Solution 2: implement Jersey impl for the extension.

@blabno
Copy link
Member

blabno commented May 17, 2014

I've created prototype of jersey impl of our extension:

package org.jboss.arquillian.extension.rest.client;

import org.glassfish.jersey.client.JerseyClientBuilder;
import org.glassfish.jersey.client.JerseyWebTarget;
import org.glassfish.jersey.client.proxy.WebResourceFactory;
import org.jboss.arquillian.test.spi.TestEnricher;

import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.WebTarget;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class RestEnricher extends BaseRestEnricher implements TestEnricher {

    @Override
    protected boolean isSupportedParameter(Class<?> clazz) {
        return true; // it's proxy based, exception will be thrown when proxying.
    }

    @Override
    protected Object enrichByType(Class<?> clazz, Method method,
                                  ArquillianResteasyResource annotation, Consumes consumes, Produces produces) {
        Object value = null;
        Client client = JerseyClientBuilder.newClient();
        WebTarget webTarget = client.target(getBaseURL() + ((ArquillianResteasyResource) annotation).value());
        JerseyWebTarget jerseyWebTarget = (JerseyWebTarget) webTarget;
        if (JerseyWebTarget.class.isAssignableFrom(clazz)) {
            value = jerseyWebTarget;
        } else {
            final Class<?> parameterType;
            try {
                final Annotation[] methodDeclaredAnnotations = method.getDeclaredAnnotations();
//                                This is test method so if it only contains @Test annotation then we don't need to hassel with substitutions
                parameterType = methodDeclaredAnnotations.length <= 1 ? clazz : ClassModifier.getModifiedClass(clazz, methodDeclaredAnnotations);
            } catch (Exception e) {
                throw new RuntimeException("Cannot substitute annotations for method " + method.getName(), e);
            }
            value = WebResourceFactory.newResource(clazz, jerseyWebTarget);
        }
        return value;
    }

}

blabno pushed a commit to blabno/arquillian-extension-rest that referenced this issue May 19, 2014
@blabno
Copy link
Member

blabno commented May 19, 2014

@lordofthejars Could you have a look at getCustomerById test? blabno@03a6959#diff-c84ee3844f0ecbbefcbecf1202a011f3R113

If I run it in tomcat-embedded profile (Jersey on server side). I'm getting 404.

@lordofthejars
Copy link
Member Author

In remote it works right?

Enviat des del meu iPhone

El 19/05/2014, a les 14.45, Bernard Labno [email protected] va escriure:

@lordofthejars Could you have a look at getCustomerById test? blabno/arquillian-extension-rest@03a6959#diff-c84ee3844f0ecbbefcbecf1202a011f3R113

If I run it in tomcat-embedded profile (Jersey on server side). I'm getting 404.


Reply to this email directly or view it on GitHub.

@blabno
Copy link
Member

blabno commented May 19, 2014

I haven't tested it with remote tomcat just managed as7 and embedded tomcat.
19 maj 2014 15:10 "Alex Soto" [email protected] napisał(a):

In remote it works right?

Enviat des del meu iPhone

El 19/05/2014, a les 14.45, Bernard Labno [email protected] va
escriure:

@lordofthejars Could you have a look at getCustomerById test?
blabno/arquillian-extension-rest@03a6959#diff-c84ee3844f0ecbbefcbecf1202a011f3R113

If I run it in tomcat-embedded profile (Jersey on server side). I'm
getting 404.


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHubhttps://github.com//issues/14#issuecomment-43499929
.

@lordofthejars
Copy link
Member Author

If you Can try with managed/remote tomcat if it works it is a dependencies
problem if not I will take a look this night

El dilluns, 19 maig de 2014, Bernard Labno [email protected] va
escriure:

I haven't tested it with remote tomcat just managed as7 and embedded
tomcat.
19 maj 2014 15:10 "Alex Soto" <[email protected]javascript:_e(%7B%7D,'cvml','[email protected]');>
napisał(a):

In remote it works right?

Enviat des del meu iPhone

El 19/05/2014, a les 14.45, Bernard Labno <[email protected]javascript:_e(%7B%7D,'cvml','[email protected]');>
va
escriure:

@lordofthejars Could you have a look at getCustomerById test?
blabno/arquillian-extension-rest@03a6959#diff-c84ee3844f0ecbbefcbecf1202a011f3R113

If I run it in tomcat-embedded profile (Jersey on server side). I'm
getting 404.


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub<
https://github.com/arquillian/arquillian-extension-rest/issues/14#issuecomment-43499929>

.


Reply to this email directly or view it on GitHubhttps://github.com//issues/14#issuecomment-43500099
.

Enviat amb Gmail Mobile

@blabno
Copy link
Member

blabno commented May 20, 2014

It works with managed Tomcat, so I'll try to check the dependencies again.

Well, actually it does not work.

@lordofthejars
Copy link
Member Author

Ok then try to do next:

https://github.com/lordofthejars/bjugbank/blob/master/pom.xml#L173

I have used for TomEE embedded but probably something similar to Tomcat
should be done but changing the dependency to Jersey. If it works then I
explain why it happens :)

2014-05-20 9:03 GMT+02:00 Bernard Labno [email protected]:

It works with managed Tomcat, so I'll try to check the dependencies again.


Reply to this email directly or view it on GitHubhttps://github.com//issues/14#issuecomment-43592527
.

+----------------------------------------------------------+
Alex Soto Bueno - Computer Engineer
www.lordofthejars.com
+----------------------------------------------------------+

@blabno
Copy link
Member

blabno commented May 20, 2014

@lordofthejars I have commited Tomcat managed profile, but the problem with getCustomerById remains.

@blabno
Copy link
Member

blabno commented May 20, 2014

What a stupid issue!
I've just noticed that CustomerResourceImpl.getCustomerById has JAX-RS annotation. If I remove it and leave annotations only on CustomerResource interface then everything woks.

public Customer getCustomerById(@PathParam("id") long id)

@lordofthejars
Copy link
Member Author

Ou yes sorry, I remembered now that annotations should go into interface
not in the class itself. I found the same problem in my example and I fix
it, but now I was not aware that it could happens the same to you :S.

Cool!!!

2014-05-20 10:51 GMT+02:00 Bernard Labno [email protected]:

What a stupid issue!
I've just noticed that CustomerResourceImpl.getCustomerById has JAX-RS
annotation. If I remove it and leave annotations only on CustomerResourceinterface then everything woks.

public Customer getCustomerById(@PathParam("id") long id)


Reply to this email directly or view it on GitHubhttps://github.com//issues/14#issuecomment-43600923
.

+----------------------------------------------------------+
Alex Soto Bueno - Computer Engineer
www.lordofthejars.com
+----------------------------------------------------------+

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants