google / google/guice

Incorrect runtime detection of injected delegate with circular dependency

Open
#1,228 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
12.7k
Forks
1.7k
Avg merge
11m
Merged PRs (30d)
2

Description

Simple test for reproducing behaviour with which we faced. It nether detects a circular dependency, nor makes them work correctly.
```
public class TestUnusualBehaviour {

@Test
public void test() {
Injector injector = Guice.createInjector();
IA a = injector.getInstance(IA.class);
Assert.assertEquals("A", a.getDelegate().getDelegate().letter());
}

interface C {
String letter();
C getDelegate();
}

@ImplementedBy(A.class)
interface IA extends C { }

static class A implements IA {
private final IB b;

@Inject
A(IB b) {this.b = b;}

@Override
public String letter() {
return "A";
}

@Override
public C getDelegate() {
return b;
}
}

@ImplementedBy(B.class)
interface IB extends C { }

static class B implements IB {
private final IA a;

@Inject
B(IA a) {this.a = a;}

@Override
public String letter() {
return "B";
}

@Override
public C getDelegate() {
return a;
}
}
}
```

console output is:
```
java.lang.RuntimeException: java.lang.IllegalAccessException: Class com.google.inject.internal.DelegatingInvocationHandler can not access a member of class benchmark.Main$C with modifiers "public abstract"

at com.google.inject.internal.DelegatingInvocationHandler.invoke(DelegatingInvocationHandler.java:52)
at benchmark.$Proxy8.letter(Unknown Source)
at benchmark.Main.test(Main.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.IllegalAccessException: Class com.google.inject.internal.DelegatingInvocationHandler can not access a member of class benchmark.Main$C with modifiers "public abstract"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.google.inject.internal.DelegatingInvocationHandler.invoke(DelegatingInvocationHandler.java:50)
... 24 more
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.