This chapter continues from where Defining Java modules left us.

Using Scala in Java modules

~/iwant-tutorial $ $EDITOR "as-iwant-tutorial-developer/i-have/wsdef/src/main/java/com/example/wsdef/IwanttutorialWorkspace.java"
package com.example.wsdef;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import org.fluentjava.iwant.api.core.Concatenated;
import org.fluentjava.iwant.api.core.Concatenated.ConcatenatedBuilder;
import org.fluentjava.iwant.api.core.HelloTarget;
import org.fluentjava.iwant.api.javamodules.JavaBinModule;
import org.fluentjava.iwant.api.javamodules.JavaSrcModule;
import org.fluentjava.iwant.api.javamodules.JavaSrcModule.IwantSrcModuleSpex;
import org.fluentjava.iwant.api.javamodules.ScalaVersion;
import org.fluentjava.iwant.api.model.Path;
import org.fluentjava.iwant.api.model.SideEffect;
import org.fluentjava.iwant.api.model.Target;
import org.fluentjava.iwant.api.wsdef.SideEffectDefinitionContext;
import org.fluentjava.iwant.api.wsdef.TargetDefinitionContext;
import org.fluentjava.iwant.api.wsdef.Workspace;
import org.fluentjava.iwant.core.javamodules.JavaModules;
import org.fluentjava.iwant.eclipsesettings.EclipseSettings;
public class IwanttutorialWorkspace implements Workspace {
static class ExampleModules extends JavaModules {
private final ScalaVersion scala = ScalaVersion._2_11_7();
class ExampleModules extends JavaModules {
@Override
protected IwantSrcModuleSpex commonSettings(IwantSrcModuleSpex m) {
return super.commonSettings(m).testDeps(junit);
}
final JavaBinModule hamcrestCore = binModule("org/hamcrest",
"hamcrest-core", "1.3");
final JavaBinModule junit = binModule("junit", "junit", "4.11",
hamcrestCore);
final JavaSrcModule helloUtil = srcModule("example-helloutil")
.noMainResources().end();
final JavaSrcModule hello = srcModule("example-hello").noMainResources()
.mainDeps(helloUtil).end();
final JavaSrcModule mixedScalaAndJava = JavaSrcModule.with()
.name("example-mixedscala").scalaVersion(scala)
.mainJava("src/main/java").mainScala("src/main/scala").end();
}
private final ExampleModules modules = new ExampleModules();
@Override
public List<? extends Target> targets(TargetDefinitionContext ctx) {
return Arrays.asList(new HelloTarget("hello", "hello from iwant\n"),
classpathStringOfAll());
classpathStringOfAll(), exampleMixedscalaClasspath());
}
private Target classpathStringOfAll() {
ConcatenatedBuilder cp = Concatenated.named("all-as-cp");
cp.string(".");
for (Path jar : JavaModules
.mainArtifactJarsOf(modules.allSrcModules())) {
cp.string(File.pathSeparator).nativePathTo(jar);
}
return cp.end();
}
private Target exampleMixedscalaClasspath() {
return Concatenated.named("example-mixedscala-classpath")
.unixPathTo(modules.mixedScalaAndJava.mainArtifact())
.string(":").unixPathTo(scala.libraryJar()).end();
}
@Override
public List<? extends SideEffect> sideEffects(
SideEffectDefinitionContext ctx) {
return Arrays.asList(EclipseSettings.with().name("eclipse-settings")
.modules(ctx.wsdefdefJavaModule(), ctx.wsdefJavaModule())
.modules(modules.allSrcModules()).end());
}
}

Then we generate Eclipse settings for it so we can use Eclipse for writing the code.

~/iwant-tutorial $ as-iwant-tutorial-developer/with/bash/iwant/side-effect/eclipse-settings/effective
(0/1 S~ org.fluentjava.iwant.api.javamodules.JavaClasses iwant-tutorial-wsdef-main-classes)
(example-hello)
( .project)
( .classpath)
( .settings/org.eclipse.jdt.core.prefs)
( .settings/org.eclipse.jdt.ui.prefs)
(example-helloutil)
( .project)
( .classpath)
( .settings/org.eclipse.jdt.core.prefs)
( .settings/org.eclipse.jdt.ui.prefs)
(as-iwant-tutorial-developer/i-have/wsdef)
( .project)
( .classpath)
( .settings/org.eclipse.jdt.core.prefs)
( .settings/org.eclipse.jdt.ui.prefs)
(as-iwant-tutorial-developer/i-have/wsdefdef)
( .project)
( .classpath)
( .settings/org.eclipse.jdt.core.prefs)
( .settings/org.eclipse.jdt.ui.prefs)

Now we can import the project to Eclipse and write some code.

~/iwant-tutorial $ $EDITOR "example-mixedscala/src/main/java/com/example/mixedscala/JavaThatDependsOnScala.java"
package com.example.mixedscala;
public class JavaThatDependsOnScala {
public static void main(String[] args) {
System.out.println(
new com.example.mixedscala.ScalaThatDependsOnJava()
.stringFromScala());
}
}
~/iwant-tutorial $ $EDITOR "example-mixedscala/src/main/scala/com/example/mixedscala/ScalaThatDependsOnJava.scala"
package com.example.mixedscala {
class ScalaThatDependsOnJava {
def stringFromScala(): String = {
var j = new com.example.mixedscala.JavaHello();
return "scala calling " + j.stringFromJava();
}
}
}
~/iwant-tutorial $ $EDITOR "example-mixedscala/src/main/java/com/example/mixedscala/JavaHello.java"
package com.example.mixedscala;
public class JavaHello {
public String stringFromJava() {
return "hello from java";
}
}

TODO remove:

~/iwant-tutorial $ $EDITOR "example-mixedscala/src/main/java/com/example/mixedscala/ScalaThatDependsOnJava.java"

Finally, we can build and run some classes.

~/iwant-tutorial $ as-iwant-tutorial-developer/with/bash/iwant/target/example-mixedscala-classpath/as-path
(0/1 D! org.fluentjava.iwant.core.download.GnvArtifact scala-compiler-2.11.7.jar)
(0/1 D! org.fluentjava.iwant.core.download.GnvArtifact scala-library-2.11.7.jar)
(0/1 D! org.fluentjava.iwant.core.download.GnvArtifact scala-reflect-2.11.7.jar)
(0/1 D! org.fluentjava.iwant.core.download.GnvArtifact ant-1.10.1.jar)
(0/1 D! org.fluentjava.iwant.core.download.GnvArtifact ant-launcher-1.10.1.jar)
(0/1 D! org.fluentjava.iwant.api.javamodules.ScalaClasses example-mixedscala-main-classes-from-scala)
Buildfile: /home/hacker/iwant-tutorial/as-iwant-tutorial-developer/.i-cached/temp/w-0/build.xml

scalac-taskdef:

scalac-classpath:

classes-from-scala:
[scalac] Compiling 0 scala and 3 java source files to /home/hacker/iwant-tutorial/as-iwant-tutorial-developer/.i-cached/target/example-mixedscala-main-classes-from-scala
[scalac] Compiling 1 source file to /home/hacker/iwant-tutorial/as-iwant-tutorial-developer/.i-cached/target/example-mixedscala-main-classes-from-scala

BUILD SUCCESSFUL
Total time: 5 seconds
(0/1 D! org.fluentjava.iwant.api.javamodules.JavaClasses example-mixedscala-main-classes)
/home/hacker/iwant-tutorial/as-iwant-tutorial-developer/.i-cached/target/example-mixedscala-main-classes-from-scala/com/example/mixedscala/ScalaThatDependsOnJava.class: warning: Cannot find annotation method 'bytes()' in type 'ScalaSignature': class file for scala.reflect.ScalaSignature not found
1 warning
(0/1 D! org.fluentjava.iwant.api.core.Concatenated example-mixedscala-classpath)
/home/hacker/iwant-tutorial/as-iwant-tutorial-developer/.i-cached/target/example-mixedscala-classpath
~/iwant-tutorial $ as-iwant-tutorial-developer/with/bash/iwant/target/example-mixedscala-classpath/as-path | xargs -r cat
~/iwant-tutorial $ java -cp "$(as-iwant-tutorial-developer/with/bash/iwant/target/example-mixedscala-classpath/as-path | xargs -r cat)" com.example.mixedscala.JavaThatDependsOnScala
scala calling hello from java
Output asserted