[ALF-21333] NoSuchMethodError running 5.0.d SOLR4 on JDK 7 Created: 25-Apr-15  Updated: 18-Oct-15  Resolved: 28-Aug-15

Status: Closed
Project: Alfresco
Component/s: Records Management, Search and Indexing (non-UI)
Affects Version/s: 5.0.d Community
Fix Version/s: Community Edition 201508 EA
Security Level: external (External user)

Type: Bug Priority: Unprioritized
Reporter: Axel Faust Assignee: Closed Issues
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: PNG File Optimize Now - SOLR4.png     Text File solr.log    
Date of First Response:

 Description   

Alfresco 5.0 is supposed to have a minimum requirement of Java 7 to be run. The 5.0.d actually ships Java 8 and seems to have been compiled against the Java 8 class library. As a result, there can be incompatibilities with Java 7 when a specific signature expectation has been compiled into Alfresco classes.

Step to reproduce one example NoSuchMethodError in SOLR4

1) Make sure to execute SOLR4 with JDK 7 (i.e. via setting JAVA_HOME environment variable)
2) Start Repository and SOLR4
3) Access SOLR4 admin console
4) Select one of the cores in the drop down list and load the core overview
5) Click on the "optimize now" button in the overview
6) Observe Tomcat console / solr.log

Expectation: Operation performs without an error
Observation: NoSuchMethodError is thrown because compiler has compiled a signature expectation for Java 8 class library into Alfresco class file (as a result of using implementation class instead of interface for parameter type declaration)

2015-04-25 20:23:08,223 ERROR [org.apache.solr.servlet.SolrDispatchFilter] null:java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView;
at org.alfresco.solr.tracker.TrackerStats.aggregateResults(TrackerStats.java:80)
at org.alfresco.solr.tracker.TrackerStats.getModelTimes(TrackerStats.java:69)
at org.alfresco.solr.AlfrescoCoreAdminHandler.addCoreSummary(AlfrescoCoreAdminHandler.java:1104)
at org.alfresco.solr.AlfrescoCoreAdminHandler.actionSUMMARY(AlfrescoCoreAdminHandler.java:932)
at org.alfresco.solr.AlfrescoCoreAdminHandler.handleCustomAction(AlfrescoCoreAdminHandler.java:291)
at org.apache.solr.handler.admin.CoreAdminHandler.handleRequestBody(CoreAdminHandler.java:182)
at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:135)
at org.apache.solr.servlet.SolrDispatchFilter.handleAdminRequest(SolrDispatchFilter.java:729)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:258)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:207)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:611)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)



 Comments   
Comment by Axel Faust [ 25-Apr-15 ]

Forgot to detail environment: Win 7 64-bit, Oracle JDK 1.7.0_45 64-bit

Comment by Axel Faust [ 25-Apr-15 ]

Based on stacktrace I now realize that only accessing the core overview UI would cause this issue. I hadn't actually checked the log / console before clicking on "optimize now"

Comment by Samuel Langlois [X] (Inactive) [ 28-Apr-15 ]

Yep, he's right.
The signature of ConcurrentHashMap.keySet() changed from Java 7 to 8: the return type is different.
Therefore, although we compiled with -target 1.7, the return type was baked into the resulting class file, and this code does not run on Java7.

What do we do? Declare that 5.0.d is actually Java 8 only and apologise?
CC Kevin Roast [X], Richard Esplin [X]

Comment by Richard Esplin [X] (Inactive) [ 30-Apr-15 ]

I'm good at apologizing. I can update the wiki page and make clear that it is Java 8 only. But I have a few questions:

  • Is this a bug in the Java compiler, because it was compiled with target 1.7 (can I shift the blame)?
  • Is compiling with Java 7 going to produce a functional WAR (do we have a workaround)? Does Maven make this easy?
  • Did we do anything clearly wrong that we will avoid doing next time?
Comment by Samuel Langlois [X] (Inactive) [ 30-Apr-15 ]
  • It's not a bug in the compiler. The compiler does produce Java7 bytecode. But it does not prevent, for instance, that you can use a class which is only in the Java8 library, and not in the Java7 one (like the new LocalDate for instance). The Java8 compiler cannot know it's a new class, and it's only at runtime that it will fail with Java7.
    What we have here is similar, with the return value of a method that changed. I guess return types are coded somehow in the bytecode.
  • Re-compiling your own 5.0.d is a possibility. It's quite simple:
    svn checkout https://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/COMMUNITYTAGS/V5.0.d/root/
    export JAVA_HOME=/path/to/java7
    mvn clean install -pl projects/solr4 -am
    

    (which in Mavenspeak means: build solr4 and all its dependencies - because the failing class is actually in solr-client)
    The difficulty after that is to make sure you use your own solr4 war, and not the one we provide.

  • This all stems from releasing a 5.0.d instead of a 5.1.a, I think.
    Because of the numbering, people (us included!) expect it to work on Java7, since 5.0.0 and 5.0.1 so.
    But because that release actually comes from HEAD - which was already switched to Java8 - I built it with Java8 without realising the confusion. Sorry about that!

To avoid confusion in the future, we could just switch compilation to -target 1.8 now. That would prevent Java7 to run Alfresco 5.1.
After all, Java7 is end-of-lifed... tomorrow!

Comment by Martin Cosgrave (Inactive) [ 04-Jun-15 ]

This issue also surfaces when using RM, doesn't appear to have any relationship to SOLR in this case, see this issue and related pastebin: https://github.com/marsbard/puppet-alfresco/issues/82

Comment by Neil McErlean [X] (Inactive) [ 04-Jun-15 ]

Hi Martin Cosgrave. Could you tell us what version of Alfresco One and what version of the Records Management module you are using? Thanks.

Comment by Neil McErlean [X] (Inactive) [ 04-Jun-15 ]

The relevant change in Martin Cosgrave's case above is to the signature of the method java.util.concurrent.ConcurrentHashMap.keySet(), which has been in Java since 1.5. In java 7, it returns a Set<K>. In java 8 it is declared to return a specialized extension of Set<K>, a ConcurrentHashMap.KeySetView<K, V>.

It looks like you just can't build Java 7 compatible code from a Java 8 compiler.

Comment by Martin Cosgrave (Inactive) [ 04-Jun-15 ]

It's not Alfresco One, it's CE 5.0.d and the version of RM is 2.3.c as you can see here https://github.com/marsbard/puppet-alfresco/blob/master/manifests/addons/rm.pp

Comment by Richard Esplin [X] (Inactive) [ 12-Jun-15 ]

I added a note to the 5.0.d Release Notes in the wiki about the Solr problem and the RM problem. It is unfortunate, but given the current support status of Java 7, I think it is reasonable to just ask people to use Java 8 if they hit those problems. Is there anything else we can do?

Comment by Axel Faust [ 12-Jun-15 ]

Richard, you can basically put the "Java 8" stamp on the entire release. The issue in RM only surfaces there, but the code component is actually part of the Repository core. So if anyone is using that class from core in an addon/customization, he'll run into the same issue without RM.

Comment by Martin Cosgrave (Inactive) [ 12-Jun-15 ]

When java 6 went eol the package maintainers of the various Linux distributions stepped up to keep openjdk 6 alive with security updates. In that case EOL did not mean EOL and as long as package maintainers are supporting openjdk 7 then it is really not EOL in any real way. So it isn't OK to just say "java 7 is dead" as a justification to make everyone upgrade.

Comment by Richard Esplin [X] (Inactive) [ 28-Aug-15 ]

5.1.a is built with Java 7 and so should work. However, we do not test or support for Alfresco on Java 7.

Generated at Tue May 18 06:04:21 BST 2021 using Jira 7.13.15#713015-sha1:7c5ddd2c3e1709974ae9c48c17df8edd3919fe2c.