Closed buritos closed 4 years ago
ActorEnvironmentTest#testSecuredEnvironment
fails with:
java.lang.LinkageError: loader (instance of io/vlingo/common/compiler/DynaClassLoader): attempted duplicate class definition for name: "io/vlingo/actors/ActorEnvironmentTestEnvironmentProvider__Proxy"
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at java.lang.ClassLoader.defineClass(ClassLoader.java:635)
at io.vlingo.common.compiler.DynaClassLoader.addDynaClass(DynaClassLoader.java:18)
at io.vlingo.common.compiler.DynaCompiler.compile(DynaCompiler.java:70)
at io.vlingo.actors.ActorProxy.tryGenerateCreate(ActorProxy.java:103)
at io.vlingo.actors.ActorProxy.tryGenerateCreate(ActorProxy.java:86)
at io.vlingo.actors.ActorProxy.createFor(ActorProxy.java:34)
at io.vlingo.actors.Stage.actorProxyFor(Stage.java:514)
at io.vlingo.actors.Stage.actorProtocolFor(Stage.java:466)
at io.vlingo.actors.Stage.testActorFor(Stage.java:285)
at io.vlingo.actors.testkit.TestWorld.actorFor(TestWorld.java:75)
at io.vlingo.actors.ActorEnvironmentTest.testSecuredEnvironment(ActorEnvironmentTest.java:54)
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:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
@buritos The class io.vlingo.actors.ActorEnvironmentTestEnvironmentProvider__Proxy
is already in the ClassLoader
that is evidently not being cleared between tests.
Inside ActorProxy
you can see that the specific World
's ClassLoader
is being used, so maybe the World
is being reused across tests. Or it could be that there is a race and the io.vlingo.actors.ActorEnvironmentTestEnvironmentProvider__Proxy
is not yet in the ClassLoader
but will be there before a second thread completes its generation, compile, and put into the ClassLoader
.
This unfortunate code is supposed to protect against that, but maybe it's not:
synchronized (protocol) {
WDYT?
Possibly the fix is to catch the exception and try to get the class again out of the ClassLoader
as now it is there but it wasn't on first try to fetch it.
@VaughnVernon
maybe the World is being reused across tests
The test creates a new World
instance for every test method execution.
Or it could be that there is a race and the io.vlingo.actors.ActorEnvironmentTestEnvironmentProvider__Proxy is not yet in the ClassLoader
That's a good theory. But why hasn't this been the case before the last commit here? I would love to understand how this works :)
synchronized (protocol)
I guess we either fix this or catch
and retry as you suggested.
@VaughnVernon
createFor
on LinkageError
stack overflows@buritos I am pretty sure I haven't made any changes to vlingo-actors that could make this behavior newly appear. The ActorProxy
has been working for 2+ years. I can't think of how the synchronized (protocol) { ... }
could be a problem. The actor
instance will not receive messages until after the protocol exists for it, so I don't see how there could be a race from the actor
itself. The smart money says back out your changes for grid and re-add them one at a time until the problem reappears.
@buritos I am concerned that this is not building on Travis. I think it is due to running a test that should have been marked @Ignore
[ERROR] ActorEnvironmentTest.testSecuredEnvironment:55 » Linkage loader (instance of ...
AddressFactory
fromStage
instead ofWorld