Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error utilizing dependencies with scalac_plugin #4594

Closed
bhmiller opened this issue May 15, 2017 · 17 comments
Closed

Error utilizing dependencies with scalac_plugin #4594

bhmiller opened this issue May 15, 2017 · 17 comments
Labels
Milestone

Comments

@bhmiller
Copy link

bhmiller commented May 15, 2017

Tried 1.3.0.dev13 (first release I see allowing this syntax) and 1.3.0rc1 (and a few more in between):

Repro

Have all these in the same directory:

pants.ini:

[GLOBAL]
pants_version: 1.3.0rc1

BUILD:

scala_library(
    name='MyLibrary',
    sources=['MyClass.scala'],
    dependencies=[':MyPlugin'],
    scalac_plugins=['myPlugin'],
)

scalac_plugin(
    name='MyPlugin',
    sources=['MyPlugin.scala'],
    dependencies=[':MyJavaLibrary'],
#    java_sources=[':MyJavaLibrary'],
    classname='foo.MyPlugin',
    plugin='myPlugin',
)

java_library(
    name='MyJavaLibrary',
    sources=['MyJavaEnum.java'],
)

MyClass.scala:

package bar

object MyClass {
  val foo: String = "hello world"
}

MyJavaEnum.java:

package foo;

public enum MyJavaEnum {
    One, Two
}

MyPlugin.scala:

package foo

import tools.nsc.plugins.{Plugin, PluginComponent}
import tools.nsc.Global

class MyPlugin(val global: Global) extends Plugin {
  val name = "myPlugin"
  val description = "Test garbage plugin"
  val components = List[PluginComponent]()
  val enum = MyJavaEnum.One
}

If you run ./pants compile :: and you'll get:

17:30:32 00:02   [compile]
...
17:30:32 00:02     [compile]
17:30:32 00:02     [zinc]
17:30:32 00:02       [cache]   
                   No cached artifacts for 3 targets.
                   Invalidated 3 targets.
17:30:32 00:02       [isolation-zinc-pool-bootstrap] 
                   [1/3] Compiling 1 zinc source in 1 target (//:MyJavaLibrary).
17:30:32 00:02       [compile]
...
17:31:32 01:02         [zinc]
                       [info] Compiling 1 Java source to /<dir>/.pants.d/compile/zinc/c95338cea9cc/.MyJavaLibrary/current/classes...
                       [info] Compile success at May 15, 2017 5:31:33 PM [1.391s]

                   [2/3] Compiling 1 zinc source in 1 target (//:MyPlugin).
17:31:33 01:03       [compile]
                     
17:31:33 01:03         [zinc]
                       [info] Compiling 1 Scala source to /<dir>/.pants.d/compile/zinc/c95338cea9cc/.MyPlugin/current/classes...
                       [info] Compile success at May 15, 2017 5:31:39 PM [6.151s]
                        
                   [3/3] Compiling 1 zinc source in 1 target (//:MyLibrary).
17:31:39 01:09       [compile]
                     
17:31:40 01:10         [zinc]
                       [info] Compiling 1 Scala source to /<dir>/.pants.d/compile/zinc/c95338cea9cc/.MyLibrary/current/classes...
                       [error] ## Exception when compiling /<dir>/MyClass.scala and others...
                       [error] null
                       [error] sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                       [error] sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
                       [error] sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                       [error] java.lang.reflect.Method.invoke(Method.java:498)
                       [error] xsbt.CachedCompiler0$Compiler.superCall(CompilerInterface.scala:233)
                       [error] xsbt.CachedCompiler0$Compiler.superComputePhaseDescriptors(CompilerInterface.scala:226)
                       [error] xsbt.CachedCompiler0$Compiler.phaseDescriptors$lzycompute(CompilerInterface.scala:223)
                       [error] xsbt.CachedCompiler0$Compiler.phaseDescriptors(CompilerInterface.scala:218)
                       [error] scala.tools.nsc.Global$Run.<init>(Global.scala:1171)
                       [error] xsbt.CachedCompiler0$$anon$2.<init>(CompilerInterface.scala:119)
                       [error] xsbt.CachedCompiler0.run(CompilerInterface.scala:119)
                       [error] xsbt.CachedCompiler0.run(CompilerInterface.scala:108)
                       [error] xsbt.CompilerInterface.run(CompilerInterface.scala:26)
                       [error] sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                       [error] sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
                       [error] sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                       [error] java.lang.reflect.Method.invoke(Method.java:498)
                       [error] __shaded_by_pants__.sbt.internal.inc.AnalyzingCompiler.call(AnalyzingCompiler.scala:107)
                       [error] __shaded_by_pants__.sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:42)
                       [error] __shaded_by_pants__.sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:35)
                       [error] __shaded_by_pants__.sbt.internal.inc.MixedAnalyzingCompiler$$anonfun$compileScala$1$1.apply$mcV$sp(MixedAnalyzingCompiler.scala:50)
                       [error] __shaded_by_pants__.sbt.internal.inc.MixedAnalyzingCompiler$$anonfun$compileScala$1$1.apply(MixedAnalyzingCompiler.scala:50)
                       [error] __shaded_by_pants__.sbt.internal.inc.MixedAnalyzingCompiler$$anonfun$compileScala$1$1.apply(MixedAnalyzingCompiler.scala:50)
                       [error] __shaded_by_pants__.sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:74)
                       [error] __shaded_by_pants__.sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:49)
                       [error] __shaded_by_pants__.sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:64)
                       [error] __shaded_by_pants__.sbt.internal.inc.IncrementalCompilerImpl$$anonfun$compileInternal$1.apply(IncrementalCompilerImpl.scala:132)
                       [error] __shaded_by_pants__.sbt.internal.inc.IncrementalCompilerImpl$$anonfun$compileInternal$1.apply(IncrementalCompilerImpl.scala:132)
                       [error] __shaded_by_pants__.sbt.internal.inc.Incremental$.doCompile(Incremental.scala:95)
                       [error] __shaded_by_pants__.sbt.internal.inc.Incremental$$anonfun$1$$anonfun$apply$1.apply(Incremental.scala:79)
                       [error] __shaded_by_pants__.sbt.internal.inc.Incremental$$anonfun$1$$anonfun$apply$1.apply(Incremental.scala:79)
                       [error] __shaded_by_pants__.sbt.internal.inc.IncrementalCommon.recompileClasses(IncrementalCommon.scala:70)
                       [error] __shaded_by_pants__.sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:39)
                       [error] __shaded_by_pants__.sbt.internal.inc.Incremental$$anonfun$1.apply(Incremental.scala:78)
                       [error] __shaded_by_pants__.sbt.internal.inc.Incremental$$anonfun$1.apply(Incremental.scala:77)
                       [error] __shaded_by_pants__.sbt.internal.inc.Incremental$.manageClassfiles(Incremental.scala:122)
                       [error] __shaded_by_pants__.sbt.internal.inc.Incremental$.compile(Incremental.scala:77)
                       [error] __shaded_by_pants__.sbt.internal.inc.IncrementalCompile$.apply(Compile.scala:60)
                       [error] __shaded_by_pants__.sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:132)
                       [error] __shaded_by_pants__.sbt.internal.inc.IncrementalCompilerImpl.incrementalCompile(IncrementalCompilerImpl.scala:87)
                       [error] org.pantsbuild.zinc.Compiler.compile(Compiler.scala:203)
                       [error] org.pantsbuild.zinc.Main$.run(Main.scala:97)
                       [error] org.pantsbuild.zinc.Main$.main(Main.scala:16)
                       [error] org.pantsbuild.zinc.Main.main(Main.scala)
                       [error] sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                       [error] sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
                       [error] sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                       [error] java.lang.reflect.Method.invoke(Method.java:498)
                       [error] com.martiansoftware.nailgun.NGSession.run(NGSession.java:280)
                       [error]          
                       
                   compile(//:MyLibrary) failed: Zinc compile failed.
FAILURE: Compilation failure: Failed jobs: compile(//:MyLibrary)


               Waiting for background workers to finish.
17:31:40 01:10   [complete]

If I change the BUILD file to use java_sources instead of dependencies, then everything is hunky dory.

Also FYI in case it matters, for my actual error vs. the repro above, I get a slightly different error: java.lang.NoClassDefFoundError: foo/MyJavaEnum. If you think it's worth it, I can try and improve the repro to get that error, but the work around is the same for both the simplified repro and my actual use case.

@stuhood
Copy link
Sponsor Member

stuhood commented May 15, 2017

Thanks for the report!

It sounds like the dependencies of the plugin are not being included on the classpath when it is used as a plugin. The reason java_sources would work around this is that it has the effect of merging the two targets it links (from a compilation perspective).

@bhmiller
Copy link
Author

Yeah, work around means less urgent for me to get the fix. Getting through a couple things I've been meaning to try and repro before I completely miss the boat on 1.3.0.

@stuhood
Copy link
Sponsor Member

stuhood commented May 18, 2017

Since this is not a regression, but a missing bit in a new feature, I'm going to drop it from the 1.3.0 milestone. Should be straightforward to fix for 1.3.1.

@stuhood stuhood removed this from the 1.3.0 milestone May 18, 2017
@bhmiller
Copy link
Author

bhmiller commented Jun 7, 2017

thoughts on tagging this to the 1.3.1 milestone now that 1.3.0 is done? thanks.

@stuhood stuhood added this to the 1.3.1 milestone Jun 7, 2017
@stuhood
Copy link
Sponsor Member

stuhood commented Jun 7, 2017

Yep.

@stuhood
Copy link
Sponsor Member

stuhood commented Jun 7, 2017

@bhmiller : If you have time to tackle this one (possibly with @benjyw 's assistance), it would be much appreciated.

@bhmiller
Copy link
Author

bhmiller commented Jun 8, 2017

Sure can give a whirl. What turn around timeline are you looking for? Caveat emptor, I don't do much python, so might not be the quickest turn around.

@benjyw
Copy link
Sponsor Contributor

benjyw commented Oct 3, 2017

Doing some inbox cleaning and found this, so checking in on status. Still an issue?

@stuhood
Copy link
Sponsor Member

stuhood commented Oct 3, 2017

@benjyw : AFAIK, yes.

@benjyw
Copy link
Sponsor Contributor

benjyw commented Oct 17, 2017

So far I've determined that generally the dependencies of a plugin are on the classpath when it's used as a plugin. Just not when the plugin is scala and the dep is java. Still figuring out why.

@benjyw
Copy link
Sponsor Contributor

benjyw commented Oct 17, 2017

Huh. The Java classes are on the classpath when the error occurs, so something else is going on.

@benjyw
Copy link
Sponsor Contributor

benjyw commented Oct 17, 2017

OK, so the zinc command lines in the java_sources case vs. the dependencies case are identical, except that the java_sources case has the java classes in the same /classes dir as the scala classes, and does not have the java /classes dir on the classpath. The dependencies case has those two in separate dirs, but both are on the classpath.

@benjyw
Copy link
Sponsor Contributor

benjyw commented Oct 17, 2017

Hmm, so this has nothing to do with the dep being Java. It reproduces even with a Scala dep. Oddly enough, the java_sources workaround still works when the "java sources" are actually a scala_library with .scala sources...

So it boils down to zinc not loading plugin deps from outside the main plugin class's classpath element.

@benjyw
Copy link
Sponsor Contributor

benjyw commented Oct 17, 2017

Sure enough, this is a limitation of scalac: https://groups.google.com/forum/#!topic/sbt-dev/ztKxUpxM5pE

@benjyw
Copy link
Sponsor Contributor

benjyw commented Oct 17, 2017

The solution is to modify ZincCompile to add the dependency classpath elements to the -Xplugin flag: -S-Xplugin:<classpath element containing plugin metadata>:<classpath element for dep1>:...

My experiments show that scalac will load the plugin from the first element (and not from any subsequent elements, if they happen to also be plugins, which is good) but will load deps from any element.

@benjyw
Copy link
Sponsor Contributor

benjyw commented Oct 17, 2017

Addressed in #4987

@benjyw benjyw closed this as completed Oct 18, 2017
@bhmiller
Copy link
Author

awesome. thanks for sorting through this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants