Getting compiler-errors in IDEA but not when using Maven
Anyone can explain why compiling in IDEA gives compiler-error on valid code, which maven compiles just fine?
The java-code is (in maven-module A):
public class Fisk {
public static class A {
}
public static A A = new A();
}
The following JAVA-code is example of usage:
Fisk.A a = new Fisk.A();
Fisk.A b = Fisk.A;
Then in maven-module B, which has A as dependency the following code results in compiler-error in IDEA (but works in maven):
val fisk = new Fisk.A()
val strupp: Fisk.A = Fisk.A
I posted a question regarding this here:
http://stackoverflow.com/questions/5830032/scala-java-incompatibility-referencing-static-fields-in-a-class-with-the-same-nam
And filed a ticket here: http://youtrack.jetbrains.net/issue/SCL-3146
请先登录再写评论。
You could add this to your log.xml in the IDEA installation to log out the compiler command line:
<category name="#org.jetbrains.plugins.scala.compiler">
<priority value="DEBUG"/>
<appender-ref ref="FILE"/>
</category>
Or post a zip of a minimal project that demonstrates the problem.
-jason
I will post an example. Right now I'm off for a bachelor's party so it'll be tomorrow:-)
I cooked up the attached example.
The project compiles fine using "mvn install" but making the project in IDEA (CTRL+F9) fails with:
error: A is already defined as object A
public static A A = new A();
Attachment(s):
test-fisk.tar.bz2
Can I pay JetBrains to prioritize this issue (I'm already a license-owner)? It's really getting in the way for productivity.
PS: I'm using Scala-2.8.1, not 2.9.RCx and will keep doing so until Lift is released with a version which fully supports 2.9
--
Andreas
I'm now looking into the problem...
The root of the problem is some bug in scalac Java parser / typer (and it's a good idea to report the bug to Scala's issue tracker).
To invoke the bug, you need to feed both given .java & .scala files into scalac (move Fish.java next to FishTest.scala, run "mvn compile" and you will get the same error).
When there're two separate modules, Maven compiles them sequentially: it runs javac first for the Java module, and then it runs scalac for the second, so Scala compiler uses binary .class files instead of Java sources (and thus scalac bug bypassed). However, Maven (of course) won't to compile those files within a single module.
By default, Scala plugin for IDEA compiles Scala files in the first place, but you may uncheck "Project Settings / Scala Compiler / Compile Scala files first" to switch the order, so you will be able to compile your sample files (even in a single module).
P.S. Many thanks to Jason Zaugg for clarifying the problem and fixing "Compile Scala files first" setting.
If you select 'Compile Java Files first', why do we include the .java files from other modules in the batch of files passed to Scalac? Should we just limit it to .java files from the current module?
In the sample project "test-scala" module has an explicit dependency on "test-java" one.
BTW, you don't need to include dependency on scala-compiler in scala/pom.xml (if you don't use Scalac classes directly in your code).
It's worth to point-out that it'll be impossible to compile files with Java-Scala circular dependencies when "Compile Scala files first" is turned off.
Is this really a reason to pass the java-files to scalac? It seems to me the java-files in the java-module should be compiled first (by javac) and then the scala-files in the scala-module with the already compiled classes from java-module in the classpath, or is that not the way it works?
--
Andreas
Actually I know this, but I've never gotten around to remove it:-) And copy-pasting deps around projects haunts me...
Filed ticket: https://lampsvn.epfl.ch/trac/scala/ticket/4549
I agree, I still don't see the need to ever pass .java files from downstream modules to scalac.
It seems that there's no need to pass external .java files to scalac except when there's a mutual module dependency.
Oh wow, I didn't know that was possible! Sounds simultaneously evil and convenient...
In reality, I'm unsure whether we need to pass .java files or not.
Current implementation of project compilation is, undoubtedly, based on it's own historical prerequisites, and some of them I know nothing about.
The issue needs further investigation.