Community
Participate
Working Groups
BETA_JAVA8 When using a current beta of a lambda-enabled JRE (lambda-8-b50), some tests fail due to changes in class libraries. During the first bunch of testing I found that List.remove() is now a default method, which triggers a warning re missing @Override in some tests in MethodVerifierTest.
Created attachment 220709 [details] Updates for MethodVerifierTest Here's the first bunch of updates. Please let me know, when everybody is in the position to run Java8 tests on a matching JRE, so I can release these changes into the branch.
(In reply to comment #1) > Please let me know, when everybody is in the position to run Java8 tests on > a matching JRE, so I can release these changes into the branch. I am not aware of any reasons why someone must stay locked in with an earlier JRE8. So please feel free to release the changes as long as they will not cause any failures/issues when running the tests with JRE7. Thanks!
I've pushed the changes in MethodVerifierTest via commit 4da3045d875134bb37de1ca00076288feb78d111. Now org.eclipse.jdt.core.test.compiler.regression.TestAll is green on the lambda enabled JRE, but I still need to check the rest of the test suite. I believe most tests are unaffected because those use our own jclMinX.Y.jar for compilation. Should we eventually create a jclMin1.8.jar using a few J8 features to get better test coverage? This let's me to ask: is it correct that sources for the various jclMinX.Y.jar are only persisted via the corresponding jclMinX.Ysrc.zip?
(In reply to comment #3) > Should we eventually create a jclMin1.8.jar using a few J8 features to get > better test coverage? Sure, sounds good. At the very least I would raise a [1.8] tagged defect so this is in the radar. > This let's me to ask: is it correct that sources for the various > jclMinX.Y.jar are only persisted via the corresponding jclMinX.Ysrc.zip? Not sure I understand the question - What are you proposing we do and why ?
(In reply to comment #4) > (In reply to comment #3) > > Should we eventually create a jclMin1.8.jar using a few J8 features to get > > better test coverage? > > Sure, sounds good. At the very least I would raise a [1.8] tagged defect > so this is in the radar. Bug 388936 > > This let's me to ask: is it correct that sources for the various > > jclMinX.Y.jar are only persisted via the corresponding jclMinX.Ysrc.zip? > > Not sure I understand the question - What are you proposing we do and why ? Not a proposal, I just want to learn how these files are created and maintained. If you want a "why?": - why don't I see any individual source files under version control?
There are 5 more distinct test cases failing on the new JRE: org.eclipse.jdt.core.tests.compiler.regression.JavadocTestForClass - test054 - test055 - test056 org.eclipse.jdt.core.tests.compiler.regression.VarargsTest - test066 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest - test0809 Failures in VarargsTest and GenericTypeTest are again caused by Iterator.remove() having an implementation now. (comment 0 should've said Iterator, too, List.remove() is not part of the game). Failures in JavadocTestForClass report problems like: public interface X extends Map { ^ The return types are incompatible for the inherited methods MapStream.values(), Map.values() Type MapStream is new in 1.8, it declares: Iterable<V> values(); Now Map says: public interface Map<K,V> extends MapStream<K, V> { ... Collection<V> values(); Given that Collection<E> extends Iterable<E> this should be a legal covariant override. Looks like a bug in our compiler to complain if an interface just tries to extend Map<#RAW>.
My previous judgement re Iterator.remove() was wrong: the extra errors are caused by the fact that our compiler sees this default method as a regular non-abstract method. Instead of changing the tests we should fix bug 388954.
With my current thinking regarding bug 388954 we'll end up with roughly 100 tests that cannot run on JRE 8. I hope it's all a misunderstanding on my side and someone has a more compelling compatibility story here.
(In reply to comment #8) > With my current thinking regarding bug 388954 we'll end up with roughly 100 > tests that cannot run on JRE 8. I hope it's all a misunderstanding on my > side and someone has a more compelling compatibility story here. I am sorry - this is a bit confusing due to some going back and forth as you pieced together the puzzle. If for https://bugs.eclipse.org/bugs/show_bug.cgi?id=388954, we say the right course is to force inject the AccAbstract flag on default methods while compiling for 1.7-, do we still have issues here ? Is the question of how to proceed on bug 388954 the only question or are there more ?
(In reply to comment #9) Just realized that 308 and 335 early access compilers come from different branches. This is further going to make for interesting times. We need to build in as much resilience as possible into the tests.
(In reply to comment #9) > I am sorry - this is a bit confusing due to some going back and forth as > you pieced together the puzzle. I'm sorry, indeed I was oscillating between "oh, that's easy" and "No, that can't be!". > If for > https://bugs.eclipse.org/bugs/show_bug.cgi?id=388954, we say the right course is > to force inject the AccAbstract flag > on default methods while compiling for 1.7-, do we still have issues here ? Yes. See below. > Is the question of how to proceed on bug 388954 the only question or are > there more ? - with the above strategy for bug 388954, JDT/Core tests exhibit 102 failures. - most of these relate to classes that fail to implement a method from their declared superinterface (a newly introduced default method forced to be considered as abstract in 1.7-) - some failures I haven't yet analyzed. - one issue is fundamentally new: the expected test result now depends on two versions instead of one: - the compliance level the test runs in (old) - the JRE that the test runs *on* (new) That last item is what worries me: tests that are supposed to pass, will fail when run on 1.8 JRE and we'll probably have to provide different test-*input* depending on the JRE we run on. Tests will effectively be matrix-based (JRE x compliance).
Created attachment 221447 [details] test results FYI this is the junit-export showing the 102 failures.
For easier access here's the list of unique failing test cases (multiply by compliance levels): I'll try to classify those, later. org.eclipse.jdt.core.tests.compiler.regression.AmbiguousMethodTest.test009 org.eclipse.jdt.core.tests.compiler.regression.ForeachStatementTest.test023 org.eclipse.jdt.core.tests.compiler.regression.ForeachStatementTest.test034 org.eclipse.jdt.core.tests.compiler.regression.ForeachStatementTest.test035 org.eclipse.jdt.core.tests.compiler.regression.ForeachStatementTest.test036 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0146 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0149 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0204 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0298 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0316 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0361 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0379 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0460 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0766 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0767 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0779 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0868 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0968 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0992 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test1030 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test1035 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test1137 org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test1358 org.eclipse.jdt.core.tests.compiler.regression.InnerEmulationTest.test173 org.eclipse.jdt.core.tests.compiler.regression.InnerEmulationTest.test174 org.eclipse.jdt.core.tests.compiler.regression.JavadocTestForClass.test054 org.eclipse.jdt.core.tests.compiler.regression.JavadocTestForClass.test055 org.eclipse.jdt.core.tests.compiler.regression.JavadocTestForClass.test056 org.eclipse.jdt.core.tests.compiler.regression.LookupTest.test075 org.eclipse.jdt.core.tests.compiler.regression.MethodVerifyTest.test026b org.eclipse.jdt.core.tests.compiler.regression.MethodVerifyTest.test088 org.eclipse.jdt.core.tests.compiler.regression.MethodVerifyTest.test089 org.eclipse.jdt.core.tests.compiler.regression.MethodVerifyTest.test091 org.eclipse.jdt.core.tests.compiler.regression.MethodVerifyTest.test092 org.eclipse.jdt.core.tests.compiler.regression.MethodVerifyTest.test093 org.eclipse.jdt.core.tests.compiler.regression.MethodVerifyTest.test203 org.eclipse.jdt.core.tests.compiler.regression.MethodVerifyTest.test331446 org.eclipse.jdt.core.tests.compiler.regression.MethodVerifyTest.test331446a org.eclipse.jdt.core.tests.compiler.regression.StackMapAttributeTest.test018 org.eclipse.jdt.core.tests.compiler.regression.SuperTypeTest.test013 org.eclipse.jdt.core.tests.compiler.regression.SwitchTest.testMultipleSwitches
(In reply to comment #11) > > If for > > https://bugs.eclipse.org/bugs/show_bug.cgi?id=388954, we say the right course is > > to force inject the AccAbstract flag > > on default methods while compiling for 1.7-, do we still have issues here ? > > Yes. See below. Thanks, I understand better now. > > Is the question of how to proceed on bug 388954 the only question or are > > there more ? > > - with the above strategy for bug 388954, JDT/Core tests exhibit 102 > failures. Now, is there any question that this is the most reasonable strategy ? Given this is how javac is behaving ? > - most of these relate to classes that fail to implement a method from their > declared superinterface (a newly introduced default method forced to be > considered as abstract in 1.7-) So to confirm, the code from this category of tests as is will also fail to compile with JDK8 - right ? Does this category of failures lend themselves to a resilient fix by providing an implementation ? Or does that somehow mess up the test ? > - one issue is fundamentally new: the expected test result now depends on > two versions instead of one: > - the compliance level the test runs in (old) > - the JRE that the test runs *on* (new) > That last item is what worries me: tests that are supposed to pass, will > fail when run on 1.8 JRE and we'll probably have to provide different > test-*input* depending on the JRE we run on. This is due to the same underlying cause as above ? as in the test failing to build against JRE8 due to a brand new default method showing up ? If so does providing a stub implementation work ? (same question asked earlier) I am comfortable if this is the situation with a small number of tests cases (that may gradually expand over time.) I would not codify any behavior that is not javac compliant, but otherwise it is ok.
(In reply to comment #14) Looking at the issues immediately at hand (spec, javac, tests) I can answer all your questions affirmatively. My uneasy feelings can be concretized like this: Assume a team develops code for Java X, they have their build server properly configured to compile for and with Java X, so all compatibility errors are detected. Projects properly configure the compiler for compliance Java X. Individual developers are allowed to install any Java Y for Y >= X on their machines. In this situation for Y <= 7 the worst thing that could happen is: developer writes code that calls a method introduced in Java Y, which compiles fine locally but will be detected on the build server. This is tolerable. The build server detects all problems and all code accepted on the build server also compiles on all developer machines. Starting with Y = 8 we have a new kind of issue: a developer who installed Java Y on his local machine will see new compile errors despite the compiler settings. The code may be unchanged since years and the project configuration remains unchanged. Still it cannot be compiled unless also the older JRE X is installed and bound. I'm afraid that many developers will not be happy with this situation. I expect a significant number of future bug reports along these lines.
Dani & Markus, (In reply to comment #15) > (In reply to comment #14) > > Looking at the issues immediately at hand (spec, javac, tests) I can answer > all your questions affirmatively. > > My uneasy feelings can be concretized like this: > > Assume a team develops code for Java X, they have their build server > properly configured to compile for and with Java X, so all compatibility > errors are detected. Projects properly configure the compiler for compliance > Java X. Individual developers are allowed to install any Java Y for Y >= X > on their machines. > > In this situation for Y <= 7 the worst thing that could happen is: developer > writes code that calls a method introduced in Java Y, which compiles fine > locally but will be detected on the build server. This is tolerable. The > build server detects all problems and all code accepted on the build server > also compiles on all developer machines. > > Starting with Y = 8 we have a new kind of issue: a developer who installed > Java Y on his local machine will see new compile errors despite the compiler > settings. The code may be unchanged since years and the project > configuration remains unchanged. Still it cannot be compiled unless also the > older JRE X is installed and bound. > > I'm afraid that many developers will not be happy with this situation. I > expect a significant number of future bug reports along these lines.
Dani & Markus, What is your take on this matter ? Stephan is raising alert on a situation where Java 7- code will not compile against JRE8 due to the presence of default methods that never existed in an extant interface (not just providing a default implementation for an existing abstract method.) For the time being we are converging on an approach that will be compatible with javac8 - where code that used to compile will stop compiling when built against JRE8.
Pondering more the potential solution space I fail to see a good strategy given that JRE8 introduces default methods in both these ways: a. introduce new interface methods and avoid compatibility issues by giving a default implementation (good) b. change existing interface methods into default methods This makes me wonder whether (b) is actually a good idea, it causes far more trouble than I can see benefit in it. With only (a) the compiler could much better cope with the situation. Of course we can't prevent all library vendors from doing (b) but seeing this in the JRE looks wrong to me.
(In reply to comment #14) > (In reply to comment #11) > > - most of these relate to classes that fail to implement a method from their > > declared superinterface (a newly introduced default method forced to be > > considered as abstract in 1.7-) > > So to confirm, the code from this category of tests as is will also fail > to compile with JDK8 - right ? > > Does this category of failures lend themselves to a resilient fix by providing > an implementation ? Or does that somehow mess up the test ? Yes, it works, kind-of, but while inching along I see that still the tests have to check the host JRE because those stubs will have to refer to types (mostly from java.util.functions) which are not present in 1.7-. Sigh.
(In reply to comment #18) > b. change existing interface methods into default methods I just noticed that my previous example was slightly off, here is the corrected example: Method java.util.Iterator#remove(). Java7: void remove(); Java8-lambda: void remove() default { throw new UnsupportedOperationException("remove"); } To illustrate my point in comment 18: If we could rule out this kind of introduction we *could* say: if in 1.7- mode we see - a non-abstract interface method - a class that implements the interface but does not implement this method we could classify this as an "unavoidable compatibility issue" and allow to downgrade this to warning or ignore (assuming the default method doesn't exist in the 1.7 target platform). However, due to examples like the above it would be wrong to downgrade, because on the intended target platform this interface method exists as an abstract method and not implementing it is a definite error.
Back to the task of adjusting the tests for JRE8: in bug 388954 I did most of the leg work [1] to handle all combinations of compliance and JRE, with these results currently: - all JDT/Core tests are green on JRE7 - tests are green with compliance 1.7- on JRE8-lambda - tests with compliance 1.8 on JRE8-lambda show some failures: - 16 instances of of bug 382347 comment 6 (re-opened) [1] commit dd3bff4d99a5193497eb7e3c0e1bc46a32b7c36a
Mixed setups are always problematic and will bite the user sooner or later. Filed bug 390446 to set the existing diagnostic for this problem to "warning" by default. The Java 8 spec doesn't have to care about this, since this not a setup that is supported by the spec. In Eclipse, we should support the invalid setup as good as we can, but if it's impossible or too much work, then that's also OK. > a. introduce new interface methods and avoid compatibility issues by giving a > default implementation (good) > b. change existing interface methods into default methods Since the class file will not allow to distinguish the two cases, I guess the best fallback we could have is to consider all default methods as abstract interface methods when the source level is smaller than 1.8.
(In reply to comment #22) > Since the class file will not allow to distinguish the two cases, I guess > the best fallback we could have is to consider all default methods as > abstract interface methods when the source level is smaller than 1.8. Thanks for weighing in Markus. Since this is also how javac8 behaves when invoked with -source 1.7 option, I would settle for this unless other considerations emerge.
I think this can be closed now that all tests are green with the resolution of https://bugs.eclipse.org/bugs/show_bug.cgi?id=390761. We have two separate issues: - How do manage/maintain our test suite - solved. - What should we do when we encounter this scenario in a user application build set up. I suggest we track the latter in a separate issue and per comment#22 evaluate how to "support the invalid setup as good as we can". Could you please crisply document the problem scenarios annotating each with a small snippet and also our options at https://bugs.eclipse.org/bugs/show_bug.cgi?id=390889 ? Thanks, I would place the actual work at lower priority than other default methods related issues, though discussions could be initiated right away as and when you are able to find time.
Pushed a minor tweak to a test that fails with JRE7. With this all tests are green on JRE7 also.
For good measure, I verified that the tests are all green with JRE7s of both IBM and Sun vintage. Resolving as all is well now.