Description
Scala-xml module is on the bootclasspath of the compiler because it's needed by scaladoc. However, Scala compiler will pick up all jars from bootclasspath (unless -nobootclasspath
is passed). That's the reason Scala 2.11 compiles code containing xml literals even if we do not put scala-xml on the classpath explicitly:
$ cat XMLHelloWorld.scala
object XMLHelloWorld {
def main(args: Array[String]): Unit = {
val xml = <hello>world</hello>
println(xml)
}
}
$ ./build/pack/bin/scalac -d sandbox/ XMLHelloWorld.scala
For command line scalac
that's the behavior we probably want to have. However, we get the same behavior in Maven. Consider project with the following pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sample</groupId>
<artifactId>scala-module-dependency-sample</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.11.0-RC1</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/scala</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.1.6</version>
</plugin>
</plugins>
</build>
</project>
If you try to compile (mvn scala:compile
) the same code as above with Maven Scala plugin, it will succeed. However, there's no dependency on xml declared so if you try to run your code you get:
mvn scala:run -DmainClass=XMLHelloWorld
[...]
[INFO] --- scala-maven-plugin:3.1.6:run (default-cli) @ scala-module-dependency-sample ---
Exception in thread "main" java.lang.NoClassDefFoundError: scala/xml/NamespaceBinding
at XMLHelloWorld.main(XMLHelloWorld.scala)
Caused by: java.lang.ClassNotFoundException: scala.xml.NamespaceBinding
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 1 more
{code}
Also, if you don't try to run from Maven but just compile and then publish you won't notice any problem and you end up with broken published library due to undeclared dependencies.