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

Creating Proxy from Interface with Setter Method with a Primative Parameter Doesn't Work #10

Closed
saden1 opened this issue Nov 26, 2014 · 2 comments
Assignees
Labels
Milestone

Comments

@saden1
Copy link

saden1 commented Nov 26, 2014

I am trying to create a proxy class that delegates all method invocation to an existing InvocationHandler implementation without success. The issue seems to stem from having a setter method that has a primitive parameter in my implemented interface (ProxyedInterface). With the bellow test case I get the following exception:

java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    test/ProxyedInterface_Proxy_T3rJCc0Y.setPrimitive(JLjava/lang/String;)V @33: aastore
  Reason:
    Type long_2nd (current frame, stack[7]) is not assignable to 'java/lang/Object'
  Current Frame:
    bci: @33
    flags: { }
    locals: { 'test/ProxyedInterface_Proxy_T3rJCc0Y', long, long_2nd, 'java/lang/String' }
    stack: { 'java/lang/reflect/InvocationHandler', 'test/ProxyedInterface_Proxy_T3rJCc0Y', 'java/lang/reflect/Method', '[Ljava/lang/Object;', '[Ljava/lang/Object;', integer, long, long_2nd }
  Bytecode:
    0x0000000: b200 102a 1206 1222 05bd 0013 5903 b200
    0x0000010: 2653 5904 1229 53b6 0019 05bd 0004 5903
    0x0000020: 1f53 5904 2d53 b900 1f04 0057 b1       
    at java.lang.Class.getDeclaredFields0(Native Method)
    at java.lang.Class.privateGetDeclaredFields(Class.java:2575)
    at java.lang.Class.getDeclaredField(Class.java:2060)
    at net.bytebuddy.instrumentation.LoadedTypeInitializer$ForStaticField.onLoad(LoadedTypeInitializer.java:119)
    at net.bytebuddy.instrumentation.LoadedTypeInitializer$Compound.onLoad(LoadedTypeInitializer.java:195)
    at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.initialize(DynamicType.java:2519)
    at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:2507)
    at saden1.issues.bytebuddy.ServiceLocatorProxyNGTest.testSomeMethod(ServiceLocatorProxyNGTest.java:37)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.NamingStrategy;
import net.bytebuddy.dynamic.ClassLoadingStrategy;
import net.bytebuddy.instrumentation.InvocationHandlerAdapter;
import static net.bytebuddy.instrumentation.method.matcher.MethodMatchers.*;
import net.bytebuddy.utility.RandomString;
import org.testng.annotations.Test;

public class ProxyNGTest {

    @Test
    public void testSomeMethod() throws InstantiationException, IllegalAccessException {
        Class<?> type = ProxyedInterface.class;
        ClassLoader classLoader = type.getClassLoader();

        Class<?> proxyType = new ByteBuddy(ClassFileVersion.JAVA_V8)
                .withNamingStrategy(new ProxyNamingStrategy(type))
                .subclass(Object.class)
                .implement(type)
                .method(isDeclaredBy(type))
                .intercept(InvocationHandlerAdapter.of(new ProxyInvocationHandler()))
                .make()
                .load(classLoader, ClassLoadingStrategy.Default.WRAPPER)
                .getLoaded();

        Object result = proxyType.newInstance();
    }

    public static interface ProxyedInterface {

        //fails on any setter that takes a primitive
        void setPrimitive(long value);

        //fails on any setter that takes a primitive
        void setPrimitive(long value, String string);

        //works
        void setObject(Long value);
    }

    public static class ProxyInvocationHandler implements InvocationHandler {

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return method.invoke(proxy, args);
        }
    }

    public static class ProxyNamingStrategy implements NamingStrategy {

        private final Class<?> type;

        public ProxyNamingStrategy(Class<?> type) {
            this.type = type;
        }

        @Override
        public String name(UnnamedType unnamedType) {
            String packageName = type.getPackage().getName();
            String simpleName = type.getSimpleName();
            return String.format("test.%s_Proxy_%s", simpleName, RandomString.make());
        }

    }

}
@raphw raphw added the bug label Nov 26, 2014
@raphw raphw self-assigned this Nov 26, 2014
@raphw raphw added this to the 0.4.1 milestone Nov 26, 2014
@raphw
Copy link
Owner

raphw commented Nov 26, 2014

This is indeed a bug. I simply forgot to apply a boxing assignment for the arguments. I just implemented a reproducing test and prepare a fix. I'll release a version 0.4.1 with this some minor bug-fixes later this day.

@raphw
Copy link
Owner

raphw commented Nov 26, 2014

The bug-fix release 0.4.1 is already available in JCenter and is currently synchronized to Maven Central. It should be available from there in a couple of hours.

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

No branches or pull requests

2 participants