AndyT
AndyT

Reputation: 1453

Compile test source files with scala fsc and maven

Using the maven scala plugin, I'm managing to use the fsc daemon to compile my main classes, thanks to this previous answer Fastest way to compile scala with maven

However, this doesn't work for test source files. I can add a maven execution for the test-compile phase, but if I specify the cc goal it compiles the src/main classes (fast, but wrong classes). If I specify the compileTest goal, it compiles the src/test classes using the standard compiler (right classes, but slow).

What am I missing?

... some progress has been made, reported in the answer I've posted below.

However.. this has revealed that the Compile server is not starting up. It appears that the scala.tools.nsc.MainGenericRunner class is failing to find scala.tools.nsc.CompileServer on the classpath. Now I know that it's in the java classpath as it's in the same jar file that provides MainGenericRunner, but do I need to specify a 'user' classpath somehow?

The command being run to start the CompileServer by the maven plugin looks like this:

cmd.exe /C C:\Progra~1\Java\jdk1.7.0\jre\bin\java -classpath  
C:\projects\m2\repository\org\scala-lang\scala-library\2.9.0-1\scala-library-2.9.0-1.jar;C:\projects\m2\repository\org\scala-lang\scala-compiler\2.9.0-1\scala-compiler-2.9.0-1.jar 
-Xbootclasspath/a:C:\projects\m2\repository\org\scala-lang\scala-library\2.9.0-1\scala-library-2.9.0-1.jar 
scala.tools.nsc.MainGenericRunner 
scala.tools.nsc.CompileServer 
-target:jvm-1.5 -unchecked 
>C:\Users\...\AppData\Local\Temp\scala.tools.nsc.MainGenericRunner.out     
2>C:\Users\...\AppData\Local\Temp\scala.tools.nsc.MainGenericRunner.err  

And running it gets this error in the MainGenericRunner.err file

Exception in thread "main" java.lang.RuntimeException: Cannot figure out how to run target: scala.tools.nsc.CompileServer
at scala.sys.package$.error(package.scala:27)
at scala.tools.nsc.GenericRunnerCommand.scala$tools$nsc$GenericRunnerCommand$$guessHowToRun(GenericRunnerCommand.scala:38)
at scala.tools.nsc.GenericRunnerCommand$$anonfun$2.apply(GenericRunnerCommand.scala:48)
at scala.tools.nsc.GenericRunnerCommand$$anonfun$2.apply(GenericRunnerCommand.scala:48)
at scala.Option.getOrElse(Option.scala:109)
at scala.tools.nsc.GenericRunnerCommand.<init>(GenericRunnerCommand.scala:48)
at scala.tools.nsc.GenericRunnerCommand.<init>(GenericRunnerCommand.scala:17)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:33)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

Suggestions welcome..!

Upvotes: 0

Views: 1509

Answers (3)

Niel Drummond
Niel Drummond

Reputation: 11

I had the same problem, the other solutions did not solve the problem correctly, or were not appropriate, what worked was to use a snapshot version of the maven-scala-plugin:

        <plugin>
            <groupId>org.scala-tools</groupId>
            <artifactId>maven-scala-plugin</artifactId>
            <version>2.15.3-SNAPSHOT</version>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>testCompile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <args>
                    <arg>-unchecked</arg>
                    <arg>-deprecation</arg>
                    <arg>-explaintypes</arg>
                </args>
            </configuration>
        </plugin>

Upvotes: 1

Kevin Wright
Kevin Wright

Reputation: 49705

You may want to consider using SBT.

It has all the advantages of FSC (i.e. keeping a "warm" compiler around to speed things up)

Unlike maven, you don't need tricky manual configuration to enable support for dependency tracking (only recompiling what you really need to).

Unlike fsc, it also doesn't tie you to the version of scala installed on your path, and doesn't break in the face of a misconfigured hostname (and other similar problems)

Upvotes: 4

AndyT
AndyT

Reputation: 1453

Further investigation has produced this solution: Add a new execution with a cc goal and a fixed up main source path:

    <execution>
    <id>cc-compiletest</id>
    <phase>test-compile</phase>
        <goals>
          <goal>cc</goal>
          </goals>
      <configuration>
    <mainSourceDir>${project.build.sourceDirectory}/../../test/scala</mainSourceDir>
        <useFsc>true</useFsc>
        <once>true</once>
    <displayCmd>true</displayCmd>
    </configuration>
    </execution>

Which runs the cc 'fast' compile goal against the /test/scala directory rather than the (default) /main/scala

Is this the best/only way to do this?

Upvotes: 0

Related Questions