Hi,
I get the following error both in dev and prod modes:
14:16:01,775 INFO ~ Starting /var/workspace/server
14:16:12,119 INFO ~ Precompiling ...
14:17:03,761 ERROR ~ Cannot start in PROD mode with errors
java.lang.LinkageError: loader (instance of play/classloading/ApplicationClassloader): attempted duplicate class definition for name: "controllers/LogsCollectorController"
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at play.classloading.ApplicationClassloader.loadApplicationClass(ApplicationClassloader.java:174)
at play.classloading.ApplicationClassloader.getAllClasses(ApplicationClassloader.java:443)
at play.Play.preCompile(Play.java:631)
at play.Play.init(Play.java:324)
at play.server.Server.main(Server.java:162)
The following patch works around the problem:
Index: framework/src/play/classloading/ApplicationClassloader.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- framework/src/play/classloading/ApplicationClassloader.java (revision 04f1b9b0d024413134b5e9675dbb37a4ec0ae3c4)
+++ framework/src/play/classloading/ApplicationClassloader.java (revision )
@@ -46,6 +46,7 @@
public class ApplicationClassloader extends ClassLoader {
private final ClassStateHashCreator classStateHashCreator = new ClassStateHashCreator();
+ private final HashSet<String> definedClassesSet = new HashSet<>(5000);
/**
* A representation of the current state of the ApplicationClassloader. It gets a new value each time the state of
@@ -171,6 +172,10 @@
}
if (applicationClass.javaByteCode != null || applicationClass.compile() != null) {
applicationClass.enhance();
+ if (definedClassesSet.contains(applicationClass.name)) {
+ return null;
+ }
+ definedClassesSet.add(applicationClass.name);
applicationClass.javaClass = defineClass(applicationClass.name, applicationClass.enhancedByteCode, 0,
applicationClass.enhancedByteCode.length, protectionDomain);
BytecodeCache.cacheBytecode(applicationClass.enhancedByteCode, name, applicationClass.javaSource);
Is there a better way to avoid the LinkageError without modifying Play code?
Thanks.