AkkaGuice icon indicating copy to clipboard operation
AkkaGuice copied to clipboard

java.lang.NoClassDefFoundError: org/reflections/scanners/TypesScanner

Open alexgutjahr opened this issue 11 years ago • 25 comments

Hi Chanan,

just got pointed to this project on the Play Framework mailinglist and this is exactly what I was looking for!

I started integrating AkkaGuice into my existing project and immediately bumped into the exception mentioned in the subject. I'm not quite sure what's going on but I think there is a clash between "org.reflections" % "reflections" % "0.9.9-RC1" used by AkkaGuice and the version used by Play.

I downgraded from Play 2.3.6 to 2.3.4 but the issue remains. Is this a known issue or is there any workaround available (If it helps I can provide you my full config)? Thanks!

alexgutjahr avatar Nov 14 '14 14:11 alexgutjahr

Hi Alex,

I am also using 2.3.x and haven't run into this problem. 0.9.9-RC1 is the latest version I think. There is syntax to exclude a dependency which I can show you, but it might be good to find the conflict first. Paste your build.sbt and lets see if we can find it.

chanan avatar Nov 14 '14 14:11 chanan

Chanan, thanks for the super-fast response! I just had a look into the dependencies and I think the conflict is here:

<module organisation="org.reflections" name="reflections">
  <revision name="0.9.9-RC1" status="release" pubdate="20130323145936" resolver="sbt-chain" artresolver="sbt-chain" homepage="" downloaded="false" searched="false" default="false" conf="master(*), compile, runtime(*), runtime, compile(*), master" position="86">
    <metadata-artifact status="no" details="" size="3761" time="0" location="/Users/alexhanschke/.ivy2/cache/org.reflections/reflections/ivy-0.9.9-RC1.xml" searched="false" origin-is-local="false" origin-location="http://repo1.maven.org/maven2/org/reflections/reflections/0.9.9-RC1/reflections-0.9.9-RC1.pom"/>
    <caller organisation="com.typesafe.play" name="play-java_2.11" conf="default, compile, runtime, master" rev="0.9.8" rev-constraint-default="0.9.8" rev-constraint-dynamic="0.9.8" callerrev="2.3.4"/>
    <caller organisation="akkaguice" name="akkaguice_2.11" conf="default, compile, runtime, master" rev="0.9.9-RC1" rev-constraint-default="0.9.9-RC1" rev-constraint-dynamic="0.9.9-RC1" callerrev="0.8.1"/>
    <artifacts>
      <artifact name="reflections" type="jar" ext="jar" status="no" details="" size="121013" time="0" location="/Users/alexhanschke/.ivy2/cache/org.reflections/reflections/jars/reflections-0.9.9-RC1.jar">
        <origin-location is-local="false" location="http://repo1.maven.org/maven2/org/reflections/reflections/0.9.9-RC1/reflections-0.9.9-RC1.jar"/>
      </artifact>
    </artifacts>
  </revision>
  <revision name="0.9.8" status="release" pubdate="20120524212141" resolver="sbt-chain" artresolver="sbt-chain" evicted="latest-revision" evicted-reason="" homepage="http://code.google.com/p/reflections/" downloaded="false" searched="false" default="false" conf="master(*), compile, runtime(*), runtime, compile(*), master" position="-1">
    <metadata-artifact status="no" details="" size="3678" time="0" location="/Users/alexhanschke/.ivy2/cache/org.reflections/reflections/ivy-0.9.8.xml" searched="false" origin-is-local="false" origin-location="http://repo1.maven.org/maven2/org/reflections/reflections/0.9.8/reflections-0.9.8.pom"/>
    <evicted-by rev="0.9.9-RC1"/>
    <caller organisation="com.typesafe.play" name="play-java_2.11" conf="default, compile, runtime, master" rev="0.9.8" rev-constraint-default="0.9.8" rev-constraint-dynamic="0.9.8" callerrev="2.3.4"/>
    <artifacts>
    </artifacts>
  </revision>
</module>

My build.sbt looks like this:

name := """akka-guice-sample"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayJava)

scalaVersion := "2.11.1"

resolvers += "release repository" at "http://chanan.github.io/maven-repo/releases/"

libraryDependencies ++= Seq(
  javaJdbc,
  javaEbean,
  cache,
  javaWs,
  "net.sourceforge.htmlunit" % "htmlunit" % "2.15",
  "akkaguice" %% "akkaguice" % "0.8.1"
)

Thanks!

alexgutjahr avatar Nov 14 '14 15:11 alexgutjahr

That seems to indicate that both Play and AkkaGuice are using 0.9.9-RC1. So that might not be the problem. Is your project on Github? If so, I can grab it and try it

chanan avatar Nov 14 '14 15:11 chanan

Agreed, both seem to use 0.9.9-RC1. However, looking at the org.reflections source there is no org.reflections.scanners.TypesScanner in the latest version and this seems to be the root for the exception Play is raising (it has been removed in this revision).

My project is not online right now but I can create a new sample and publish it.

alexgutjahr avatar Nov 14 '14 15:11 alexgutjahr

That's weird, let me check into it and see if AkkaGuice still compiles.

chanan avatar Nov 14 '14 15:11 chanan

I was able to reproduce this issue by changing to 0.9.9 which seems to be published now.

https://github.com/ronmamo/reflections#intro

Let me see what I need to change to make this work and I will publish a new version as soon as I can fix it.

chanan avatar Nov 14 '14 15:11 chanan

Awesome! Let me know if I can be of any help.

alexgutjahr avatar Nov 14 '14 15:11 alexgutjahr

Hi Alex, Would you mind testing the fix? use "akkaguice" %% "akkaguice" % "0.8.2-SNAPSHOT" and let me know the results.

chanan avatar Nov 14 '14 15:11 chanan

Hey Chanan, I just gave it a spin but now the stracktrace looks as follows:

java.lang.NoSuchMethodError: org.reflections.util.ClasspathHelper.forPackage(Ljava/lang/String;[Ljava/lang/ClassLoader;)Ljava/util/Set;
 play.libs.Classpath.getReflections(Classpath.java:51)
 play.libs.Classpath.getTypes(Classpath.java:28)
 play.db.ebean.EbeanPlugin.onStart(EbeanPlugin.java:72)
 play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
 play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
 scala.collection.immutable.List.foreach(List.scala:383)
 play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:91)
 play.api.Play$$anonfun$start$1.apply(Play.scala:91)
 play.api.Play$$anonfun$start$1.apply(Play.scala:91)
 play.utils.Threads$.withContextClassLoader(Threads.scala:21)
 play.api.Play$.start(Play.scala:90)
 play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:157)
 play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:130)
 scala.Option.map(Option.scala:145)
 play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:130)
 play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:128)
 scala.util.Success.flatMap(Try.scala:230)
 play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:128)
 play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:120)
 scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
 scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
 scala.concurrent.forkjoin.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1361)
 scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
 scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
 scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
 scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

So I really think the issue here is that Play depends on the previous version 0.9.8 but ends up using 0.9.9 where some types are missing or have changed. So either Play migrates to 0.9.9 itself or AkkaGuice would have to be built against 0.9.8. Or do you think there is some other way?

alexgutjahr avatar Nov 14 '14 15:11 alexgutjahr

Hi Alex,

Trying to reproduce this one. But, I did notice you are missing google guice from your build.sbt, you will need that as well in your dependencies.

I am going to post a sample project to github - lets see if we can get it to work and maybe you can clone it and get to break too.

chanan avatar Nov 14 '14 15:11 chanan

Sure, let me know one once it's available. I also just added "com.google.inject" % "guice" % "3.0" to my dependencies and tried again, but the problem remains the same.

alexgutjahr avatar Nov 14 '14 16:11 alexgutjahr

I created a new project here https://github.com/alexhanschke/akka-guice-sample and it works without any issues. So I try to isolate the issue in my existing project..

alexgutjahr avatar Nov 14 '14 16:11 alexgutjahr

You beat me to it, mine is here: https://github.com/chanan/AkkaGuiceSample

Did you have anything else in build.sbt other than htmlunit?

chanan avatar Nov 14 '14 16:11 chanan

Alright, I think I got it - it seems to be an issue with Ebean. Try this: https://github.com/alexhanschke/akka-guice-sample/commit/cc4e62b9b638f40c79407811b02128491c03fc52

alexgutjahr avatar Nov 14 '14 16:11 alexgutjahr

Thanks Alex! You are right, I don't use ebean/jdbc so I never hit on this error. Give me a bit to look at it and see if I can work around it.

chanan avatar Nov 14 '14 16:11 chanan

I posted the question here: https://groups.google.com/forum/#!topic/play-framework/_lRk3f2JOFM

In the meantime I will try to figure out a workaround.

chanan avatar Nov 14 '14 17:11 chanan

Thanks Chanan, I will keep an eye on it.

alexgutjahr avatar Nov 14 '14 17:11 alexgutjahr

Hi Alex,

I have a workaround in place in the snapshot build if you don't mind testing. I downgraded to 0.9.8, but I did need to make a couple of changes though - which happens to be better anyway.

You will need to make these two changes:

  1. Create or edit the file: conf/play.plugins and add: 10000:akkaGuice.AkkaGuicePlugin

(The number above can be bigger if you already have plugins loaded)

  1. Change your global like so:

public class Global extends GlobalSettings { private Injector injector;

@Override
public <A> A getControllerInstance(Class<A> aClass) throws Exception {
    return injector.getInstance(aClass);
}

@Override
public void onStart(Application application) {
    injector = Guice.createInjector(new AkkaGuiceModule(), new GuiceModule());
    AkkaGuice.InitializeInjector(injector);
}

}

Note: You no longer need to specify which packge AkkaGuice will scan, it will scan all your packages.

The sample: https://github.com/chanan/AkkaGuiceSample is updated to reflect this as well if you need help. Let me know if it works and I will publish to release.

chanan avatar Nov 14 '14 20:11 chanan

I just updated my sample here https://github.com/alexhanschke/akka-guice-sample and it works without any issues. So I will now integrate it into my other project and let you know about the results.

alexgutjahr avatar Nov 15 '14 09:11 alexgutjahr

Hi Chanan, looks solid! I just tested everything within my other application and I didn't run in any issue - thanks for the quick fix!

alexgutjahr avatar Nov 15 '14 13:11 alexgutjahr

Awesome, I published 0.8.2 to release.

chanan avatar Nov 15 '14 13:11 chanan

It turns out that Reflections 0.9.8 is much slower than 0.9.9. Need to look for a better work around.

chanan avatar Nov 19 '14 16:11 chanan

I will getting rid of reflections and see if this works since guava is already included with Play anyway:

http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/reflect/ClassPath.html#getAllClasses()

chanan avatar Nov 19 '14 17:11 chanan

Let me know if you need someone to checkout a snapshot.

alexgutjahr avatar Nov 19 '14 19:11 alexgutjahr

I opened an issue in the play repo: https://github.com/playframework/playframework/issues/3755

chanan avatar Dec 22 '14 13:12 chanan