cxf-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Romain Manni-Bucau (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (CXF-7229) ClassHelper usages not replacable by ClassUnwrapper
Date Fri, 27 Jan 2017 14:24:24 GMT

    [ https://issues.apache.org/jira/browse/CXF-7229?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15842913#comment-15842913
] 

Romain Manni-Bucau commented on CXF-7229:
-----------------------------------------

Seems the code changed since I checked, org.apache.cxf.jaxrs.provider.ProviderFactory#handleMapper
takes care of that. Here is a test (passing) using cglib (which drops annotations from the
proxy class itself):

{code}

import net.sf.cglib.proxy.Dispatcher;
import net.sf.cglib.proxy.Enhancer;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.transport.local.LocalConduit;
import org.junit.Test;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.junit.Assert.assertEquals;

public class ViciousServiceTest {
    @Test
    public void run() {
        final JAXRSServerFactoryBean serverFactoryBean = new JAXRSServerFactoryBean();
        serverFactoryBean.setProvider(new PlainSerializer());
        serverFactoryBean.setResourceClasses(ViciousService.class);
        serverFactoryBean.setAddress("local://road");
        final Server server = serverFactoryBean.create();
        try {
            final Client client = ClientBuilder.newClient();
            try {
                final Invocation.Builder builder = client.target("local://road")
                        .request(APPLICATION_JSON_TYPE);
                WebClient.getConfig(builder).getRequestContext().put(LocalConduit.DIRECT_DISPATCH,
Boolean.TRUE);
                final String response = builder.get(String.class);
                assertEquals("{\"worked\":true}", response);
            } finally {
                client.close();
            }
        } finally {
            server.destroy();
        }
    }

    @Target(TYPE)
    @Retention(RUNTIME)
    public @interface Plain {
    }

    @Provider
    @Produces(MediaType.APPLICATION_JSON)
    public static class PlainSerializer implements MessageBodyWriter<PleaseDontProxyMe>
{
        @Override
        public boolean isWriteable(final Class<?> aClass, final Type type, final Annotation[]
annotations, final MediaType mediaType) {
            return aClass.isAnnotationPresent(Plain.class);
        }

        @Override
        public long getSize(final PleaseDontProxyMe PleaseDontProxyMe, final Class<?>
aClass, final Type type, final Annotation[] annotations, final MediaType mediaType) {
            return 0;
        }

        @Override
        public void writeTo(final PleaseDontProxyMe PleaseDontProxyMe, final Class<?>
aClass, final Type type, final Annotation[] annotations,
                            final MediaType mediaType, final MultivaluedMap<String, Object>
multivaluedMap, final OutputStream outputStream) throws IOException, WebApplicationException
{
            outputStream.write("{\"worked\":true}".getBytes(StandardCharsets.UTF_8));
        }
    }

    @Plain
    public static class PleaseDontProxyMe {
    }

    @Path("/")
    public static class ViciousService {
        @GET
        @Produces(MediaType.APPLICATION_JSON)
        public PleaseDontProxyMe get() {
            final PleaseDontProxyMe willBeProxied = new PleaseDontProxyMe(); // in real code
it is a service.findById(1) or whatever
            // replace a big stack like JPA/spring/cdi/... creating a proxy. Using cglib

            final Enhancer enhancer = new Enhancer();
            enhancer.setClassLoader(Thread.currentThread().getContextClassLoader());
            enhancer.setSuperclass(PleaseDontProxyMe.class);
            enhancer.setCallback(new Dispatcher() {
                @Override
                public Object loadObject() throws Exception {
                    return willBeProxied;
                }
            });
            final Object o = enhancer.create();
            return PleaseDontProxyMe.class.cast(o);
        }
    }
}

/* pom.xml dependencies

  <dependencies>
    <dependency>
      <groupId>org.apache.geronimo.specs</groupId>
      <artifactId>geronimo-servlet_3.0_spec</artifactId>
      <version>1.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
      <version>3.1.9</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-rs-client</artifactId>
      <version>3.1.9</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-local</artifactId>
      <version>3.1.9</version>
    </dependency>
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>3.2.0</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
  </dependencies>
 */
{code}

> ClassHelper usages not replacable by ClassUnwrapper
> ---------------------------------------------------
>
>                 Key: CXF-7229
>                 URL: https://issues.apache.org/jira/browse/CXF-7229
>             Project: CXF
>          Issue Type: Bug
>            Reporter: Romain Manni-Bucau
>            Assignee: Andriy Redko
>         Attachments: proxy-test-case.txt
>
>
> ClassUnwrapper and ClassHelper are pretty close and for an app setting a single one should
be enough (in particular cause ClassHelper overriding is hacky)
> Spotted org.apache.cxf.jaxrs.utils.InjectionUtils#getRawResponseClass for instance



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message