lucene-dev mailing list archives

[jira] [Commented] (LUCENE-4808) Add workaround for a JDK 8 "class library bug" which is still under discussion and may *not* be fixed

Date

Fri, 01 Mar 2013 13:25:13 GMT

[ https://issues.apache.org/jira/browse/LUCENE-4808?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13590510#comment-13590510
]
Commit Tag Bot commented on LUCENE-4808:
----------------------------------------
[trunk commit] Uwe Schindler
http://svn.apache.org/viewvc?view=revision&revision=1451584
LUCENE-4808: Add workaround for a JDK 8 "class library bug" which is still under discussion
and may *not* be fixed
> Add workaround for a JDK 8 "class library bug" which is still under discussion and may
*not* be fixed
> -----------------------------------------------------------------------------------------------------
>
> Key: LUCENE-4808
> URL: https://issues.apache.org/jira/browse/LUCENE-4808
> Project: Lucene - Core
> Issue Type: Bug
> Components: general/build
> Affects Versions: 4.1, 5.0
> Reporter: Uwe Schindler
> Assignee: Uwe Schindler
> Attachments: LUCENE-4808.patch, LUCENE-4808.patch
>
>
> With JDK8 build 78 there was introduced a backwards compatibility regression which may
not be fixed until release, because Oracle is possibly accepting this backwards break regarding
cross-compilation to JDK6.
> The full thread on the OpenJDK mailing list: [http://mail.openjdk.java.net/pipermail/compiler-dev/2013-February/005737.html]
(continues in next month: http://mail.openjdk.java.net/pipermail/compiler-dev/2013-March/005748.html)
> *In short:* JDK 8 adds so called default implementations on interfaces (means you can
add a new method to an interface and provide a "default" implementation, so code implementing
this interface is not required to implement the new method. This is really cool and would
also help Lucene to make use of Interfaces instead of abstract classes which don't allow polymorphism).
> In Lucene we are still compatible with Java 7 and Java 6. So like millions of other open
source projects, we use "-source 1.6 -target 1.6" to produce class files which are Java 1.6
conform, although you use a newer JDK to compile. Of course this approach has problem (e.g.
if you use older new methods, not available in earliert JDKs). Because of this we must at
least compile Lucene with a JDK 1.6 legacy JDK and also release the class files with this
version. For 3.6, the RM has to also install JDK 1.5 (which makes it impossible to do this
on Mac). So -source/-target is a alternative to at least produce 1.6/1.5 compliant classes.
According to Oracle, this is *not* the correct way to do this: Oracle says, you have to use:
-source, -target and -Xbootclasspath to really crosscompile -> and the last thing is what
breaks here. To correctly set the bootclasspath, you need to have an older JDK installed or
you should be able to at least download it from maven (which is not available to my knowledge).
> The problem with JDK8 is now: If you compile with -source/-target but not the bootclasspath,
it happens that the compiler does no longer understand new JDK8 class file structures in the
new rt.jar, so producing compile failures. In the case of this bug: AnnotatedElement#isAnnotationPresent()
exists since Java 1.5 in the interface, but all implementing classes have almost the same
implementation: "return getAnnotation(..) != null;". So the designers of the class library
decided to move that method as so called default method into the interface itsself, removing
code duplication. If you then compile code with "-source 1.6 -target 1.6" using that method,
the javac compier does not know about the new default method feature and simply says: "Method
not found in java.lang.Class":
> {noformat}
> [javac] Compiling 113 source files to C:\Users\Uwe Schindler\Projects\lucene\trunk-lusolr3\lucene\build\test-framework\classes\java
> [javac] C:\Users\Uwe Schindler\Projects\lucene\trunk-lusolr3\lucene\test-framework\src\java\org\apache\lucene\util\TestRuleSetupAndRestoreClassEnv.java:134:
error: cannot find symbol
> [javac] if (targetClass.isAnnotationPresent(SuppressCodecs.class)) {
> [javac] ^
> [javac] symbol: method isAnnotationPresent(Class<SuppressCodecs>)
> [javac] location: variable targetClass of type Class<?>
> [javac] Note: Some input files use or override a deprecated API.
> [javac] Note: Recompile with -Xlint:deprecation for details.
> [javac] 1 error
> {noformat}
> But until the Oracle people have a good workaround (I suggested to still implement the
method on the implementation classes like Class/Method/... but delegate to the interface's
default impl), we can quickly commit a replacement of this broken method call by (getAnnotation(..)
!= null). I want to do this, so we can enable jenkins builds with recent JDK 8 again.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lucene.apache.org
For additional commands, e-mail: dev-help@lucene.apache.org