Community
Participate
Working Groups
I have found a situation when ejc produces wrong code which cases IncompatibleClassChangeError when run. I've create a test to reproduce it: https://bitbucket.org/M_A_K/eclipse-wrong-interface-bug/src Steps to Reproduce: 0. You should have maven 3.3.9 or higher + JDK 8. 1. Download or pull source code into a folder. 2. Run: "mvn clean package" in the folder. The test fails with stacktrace like this: Running mak.test.eclipse.MyServiceTest Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.114 sec <<< FAILURE! testMyMethod(mak.test.eclipse.MyServiceTest) Time elapsed: 0.051 sec <<< ERROR! java.lang.IncompatibleClassChangeError: Found interface mak.test.eclipse.entities.MyEntity, but class was expected at mak.test.eclipse.MyService.lambda$1(MyService.java:36) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:270) at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) at mak.test.eclipse.MyService.myMethod(MyService.java:38) at mak.test.eclipse.MyServiceTest.testMyMethod(MyServiceTest.java:17) 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:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 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.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112) 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.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189) at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165) at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75) You can check that javac produces correct code. Just run "mvn -Pjavac clean package" (This profile uses javac to compile instead of ejc.). The test runs without errors.
Workaround: don't trust the compiler, point the type yourself Replace final List<String> result = Stream.of(collection1.stream(), for final List<String> result = Stream.<Stream<? extends MyEntity>>of(collection1.stream(), Ejc produces correct code after it.
Thanks for the repro. Ecj versions up-to 3.14.0 produce working code, the problem can be reproduced starting with 3.15.0 (aka 4.9) From this line final MyInnerService<DomainObject<?>> toService = convert1(item.getTypeName()); 3.14.0 produces ... 0: aload_0 1: aload_1 2: invokeinterface #108, 1 // InterfaceMethod mak/test/eclipse/entities/MyEntity.getTypeName:()Ljava/lang/String; 7: invokevirtual #114 // Method convert1:(Ljava/lang/String;)Lmak/test/eclipse/MyService$MyInnerService; ... while 3.15.0 produces ... 0: aload_0 1: aload_1 2: invokevirtual #108 // Method mak/test/eclipse/entities/MyEntity.getTypeName:()Ljava/lang/String; 5: invokevirtual #114 // Method convert1:(Ljava/lang/String;)Lmak/test/eclipse/MyService$MyInnerService; ... While there is absolutely no reason to think that MyEntity is a class, I could imagine that we internally use some ill-formed intersection type, which pretends to be a class but produces MyEntity as its erasure?
Bulk move out of 4.11
Bulk move out of 4.13
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.