简体   繁体   中英

playframework 2.3.x (java) upgrade javassist

I got this weird exception at the end of compilation

java.lang.ClassCastException: javassist.bytecode.InterfaceMethodrefInfo cannot be cast to javassist.bytecode.MethodrefInfo
    at javassist.bytecode.ConstPool.getMethodrefNameAndType(ConstPool.java:417)
    at javassist.expr.MethodCall.getNameAndType(MethodCall.java:43)
    at javassist.expr.MethodCall.getMethodName(MethodCall.java:107)
    at javassist.expr.ExprEditor.loopBody(ExprEditor.java:217)
    at javassist.expr.ExprEditor.doit(ExprEditor.java:91)
    at javassist.CtBehavior.instrument(CtBehavior.java:712)
    at play.core.enhancers.PropertiesEnhancer.rewriteAccess(PropertiesEnhancer.java:156)
    at play.PlayCommands$$anonfun$PostCompile$1$$anonfun$9.apply(PlayCommands.scala:99)
    at play.PlayCommands$$anonfun$PostCompile$1$$anonfun$9.apply(PlayCommands.scala:99)
    at scala.collection.TraversableLike$$anonfun$filter$1.apply(TraversableLike.scala:264)
    at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:47)
    at scala.collection.TraversableLike$class.filter(TraversableLike.scala:263)
    at scala.collection.AbstractTraversable.filter(Traversable.scala:105)
    at play.PlayCommands$$anonfun$PostCompile$1.apply(PlayCommands.scala:99)
    at play.PlayCommands$$anonfun$PostCompile$1.apply(PlayCommands.scala:76)
    at scala.Function8$$anonfun$tupled$1.apply(Function8.scala:35)
    at scala.Function8$$anonfun$tupled$1.apply(Function8.scala:34)
    at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
    at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:42)
    at sbt.std.Transform$$anon$4.work(System.scala:64)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
    at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
    at sbt.Execute.work(Execute.scala:244)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
    at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:160)
    at sbt.CompletionService$$anon$2.call(CompletionService.scala:30)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Googling suggests that the issue may be fixed by upgrading javassist used by play. Can anyone shed some light on how to upgrade javassist in play 2.3.x? Or how to workaround the problem?

Thanks.

Extending Blacklight's answer, this is caused by the sbt-play-enhancer (at version 1.1.0) plugin using Javaassist version 3.18.0-GA which has the aforementioned bug with Java 8 default method implementations in interfaces.

sbt-play-enhancer has been updated to use 3.20.0-GA as seen here however this has yet to be formally released.

The solution I found was to override the version of Javaassist to the later version seen in this pull request.

Include the following line in your plugins.sbt to override the version of Javaassist specified by sbt-play-enhancer

libraryDependencies += "org.javassist" % "javassist" % "3.20.0-GA"

I just stumbled upon this problem, too, and at least I can tell you what caused it for me (Play 2.3.4).

I am utilizing Java 8 default-methods in interfaces. When I'm trying to invoke a default-method implementation provided my super interface instead of my own implementation using the new SomeInterface.super.defaultMethod() -syntax, then the exact same exception is thrown. If I don't have any SomeInterface.super -syntax everything is fine and back to normal.

Interface:

public interface SomeInterface {
    default boolean someDefaultMethod() {
        return false;
    }
}

Implementing class:

public class SomeInterfaceImpl implements SomeInterface {
    @Override
    public boolean someDefaultMethod() {
        // this is the problem
        return SomeInterface.super.someDefaultMethod();
    }
}

So yeah, like you said it's caused by Javassist, but actually actually already fixed there . I just filed a bug report nonetheless because I didn't find anything except in Google Groups.

Workaround for me: don't use Java 8 default-implementations in interfaces for now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM