Eclipse Project with Scala Plugin, Maven and Spark - eclipse

I have Eclipse Kepler, I have installed the Maven and Scala plugins. I create a new Maven project and add the dependency
groupId: org.apache.spark
artifactId: spark-core_2.10
version: 1.1.0
as per current doc at http://spark.apache.org/downloads.html, all is fine, the jars for Scala 2.10 are also added to the project. I then add the "Scala Nature" to the project, this adds Scala 2.11 and I end up with the following error
More than one scala library found in the build path (C:/Eclipse/eclipse-jee-kepler-SR2-win32-x86_64/plugins/org.scala-lang.scala-library_2.11.2.v20140721-095018-73fb460c1c.jar, C:/Users/fff/.m2/repository/org/scala-lang/scala-library/2.10.4/scala-library-2.10.4.jar).
At least one has an incompatible version.
Please update the project build path so it contains only compatible scala libraries.
Is it possible to use Spark (from Maven) and Scala IDE Plugin together? Any ideas on how to fix this problem?
Thanks for your help. Regards

In short, yes, it is possible.
Spark is currently using Scala 2.10, and the latest Scala IDE is "cross published" for 2.10 and 2.11. You need to choose the 2.10-based version, which is 3.0.3.
However, the next major version, 4.0, which is in release candidate mode, has multi-version support. You can create a Scala project and select the Scala version you'd like to use (2.10 or 2.11). You could give that a try if you feel like it.

If someone stumbles here while searching for the same thing:
I recently created Maven archetype for bootstrapping a new Spark 1.3.0 with Scala 2.10.4 project.
Follow instructions here:
https://github.com/spark-in-action/scala-archetype-sparkinaction
For IntelliJ IDEA, first generate project from command line and then import into IDE.

You have installed the Scala Ide plugin, but Scala nature of a project is of use only if you include scala classes in your project.
Spark and Scala are however made to work together. Make sure you you use compatible versions. You can install scala on your computer, and then use the compatible spark maven dependency.

yes you can.. use the pom I am providing below
<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>com.spark-scala</groupId>
<artifactId>spark-scala</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>${project.artifactId}</name>
<description>Spark in Scala</description>
<inceptionYear>2010</inceptionYear>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<encoding>UTF-8</encoding>
<scala.tools.version>2.10</scala.tools.version>
<!-- Put the Scala version of the cluster -->
<scala.version>2.10.4</scala.version>
</properties>
<!-- repository to add org.apache.spark -->
<repositories>
<repository>
<id>cloudera-repo-releases</id>
<url>https://repository.cloudera.com/artifactory/repo/</url>
</repository>
</repositories>
<build>
<sourceDirectory>src/main/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<plugins>
<plugin>
<!-- see http://davidb.github.com/scala-maven-plugin -->
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.13</version>
<configuration>
<useFile>false</useFile>
<disableXmlReport>true</disableXmlReport>
<includes>
<include>**/*Test.*</include>
<include>**/*Suite.*</include>
</includes>
</configuration>
</plugin>
<!-- "package" command plugin -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
</project>

There are 2 types of Spark JAR files (just by looking at the Name):
Name includes the word "assembly" and not "core" (has Scala inside)
Name includes the word "core" and not "assembly" (no Scala inside).
You should include the "core" type in your Build Path via “Add External Jars” (the version you need) since the Scala IDE already shoves one Scala for you.
Alternatively, you can just take advantage of the SBT and add the following Dependency (again, pay attention to the versions you need):
libraryDependencies += "org.apache.spark" % "spark-core_2.11" % "2.1.0"
Then you should NOT include “forcefully” any spark JAR in the Build Path.
Happy sparking:
Zar
>

Related

Exception while building Scala-Maven project on IntelliJ

I am trying to build a Scala-Maven project on IntelliJ IDEA. Right after creating the project, it says build successful. This is how my pom.xml looks like:
<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>com.dbloads.pgms</groupId>
<artifactId>Arts</artifactId>
<version>1.0-SNAPSHOT</version>
<inceptionYear>2008</inceptionYear>
<properties>
<scala.version>2.7.0</scala.version>
</properties>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.specs</groupId>
<artifactId>specs</artifactId>
<version>1.2.5</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.4.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<scalaVersion>${scala.version}</scalaVersion>
<args>
<arg>-target:jvm-1.5</arg>
</args>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<downloadSources>true</downloadSources>
<buildcommands>
<buildcommand>ch.epfl.lamp.sdt.core.scalabuilder</buildcommand>
</buildcommands>
<additionalProjectnatures>
<projectnature>ch.epfl.lamp.sdt.core.scalanature</projectnature>
</additionalProjectnatures>
<classpathContainers>
<classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER</classpathContainer>
<classpathContainer>ch.epfl.lamp.sdt.launching.SCALA_CONTAINER</classpathContainer>
</classpathContainers>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<scalaVersion>${scala.version}</scalaVersion>
</configuration>
</plugin>
</plugins>
</reporting>
</project>
Next I tried to add the compiler options in project like below:
Once added and when I click the RUN button, I get the below error message:
[ERROR] Plugin net.alchim31.maven:scala-maven-plugin:3.4.0 or one of its dependencies could not be resolved: Failed to read artifact descriptor for net.alchim31.maven:scala-maven-plugin:jar:3.4.0: Could not transfer artifact net.alchim31.maven:scala-maven-plugin:pom:3.4.0 from/to central (https://repo.maven.apache.org/maven2): PITC-Zscaler-EMEA-Amsterdam3PR.proxy.corporate.ge.com: Unknown host PITC-Zscaler-EMEA-Amsterdam3PR.proxy.corporate.ge.com -> [Help 1]
I am using the jdk version: 1.8.0_172 and I have added the Scala plugin directly from the plugins. Hence it is the latest version of the Scala.
Could anyone let me know how can I fix this problem.
It looks like you need to configure Maven and IntelliJ to use network proxy settings, since it looks like you might be behind a corporate firewall.
Maven has the ability to configure a proxy through its settings (in ~/.m2/settings.xml on Unix-like systems, or %HOME%\.m2\settings.xml on Windows), as follows:
<settings ...>
.
.
<proxies>
<!-- You can have one of these for each possible proxy. -->
<proxy>
<active>true</active>
<!-- Pick some ID for your proxy here. -->
<id>corp-proxy</id>
<!-- Choose your protocol here. E.g. "http", "socks4" or "socks5" -->
<protocol>http</protocol>
<!-- Specify the proxy server name (or IP address) and port of your proxy here. -->
<host>proxy.example.com</host>
<port>8080</port>
<!-- Identify any hosts here that you can access directly. It's unlikely that you'll
need this unless you have a proxy repository (such as Nexus, Artifactory, etc.) on
your corporate network. -->
<nonProxyHosts>www.google.com|*.example.com</nonProxyHosts>
<!-- The following fields are only necessary if required by your proxy. If you need to
enter your own username and password, make sure you do not add this file to version
control! -->
<username>proxyuser</username>
<password>somepassword</password>
</proxy>
</proxies>
.
.
</settings>
Meanwhile, IntelliJ is configured to use proxies through its settings. Refer to this answer for further details. (Note that setting proxy information via the JAVA_OPTS environment variable will work for running any Java/Scala/JVM application that needs to access the Internet via a proxy.)
Alternatively, if your proxy settings are configured correctly or are not required, it might be a temporary network connection issue, so make sure you have an Internet connection and try again. (The exception is a failure by Maven to download the plugin from the Maven central repository.)
BTW, the version of Scala you have specified—2.7.0—is ancient and almost certainly will not work with JDK 8. Either use an older JDK or a more recent version of Scala (the current release is 2.12.6).
Note that if you need to work with the current version of Apache Spark, you must currently use Scala 2.11.x - the most recent release being 2.11.12.
UPDATE:
From your comments, it seems there is some confusion about the roles played by Maven, the scala-maven-plugin, IntelliJ and the IntelliJ Scala plugin, so I'll quickly summarize them here. Please bear with me if I cover topics you're already familiar with...
Maven is a system for building and publishing software. (It actually does a lot more than just that, which is why Maven describes itself as project management software.) It allows developers to specify, in a single place, all of their software's dependencies (third-party libraries used by the software), which Maven downloads as required from the Central Maven Repository—mostly open-source—or from other, private repositories, as required. Further settings control how compilers are configured, tests are run, reports generated, etc.
Maven was developed primarily for development of Java-language projects. The scala-maven-plugin provides support for the Scala language and compiler within Maven. It is this plugin that downloads the version of the Scala compiler specified by your project and uses it to compile and build your sources.
If you look at your Maven project's pom.xml file, you will notice the following lines in the build section:
<project ...>
...
<build>
...
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.4.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<scalaVersion>${scala.version}</scalaVersion>
<args>
<arg>-target:jvm-1.5</arg>
</args>
</configuration>
</plugin>
...
</build>
...
</project>
and again in the reporting section:
<project ...>
...
<reporting>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<scalaVersion>${scala.version}</scalaVersion>
</configuration>
</plugin>
</plugins>
</reporting>
</project>
In both cases, there is a line that reads <scalaVersion>${scala.version}</scalaVersion>, which tells Maven which version of Scala you want to use. The plugin then uses this version of the Scala compiler, and has Maven download it to a cached, local repository on your machine (typically, in C:\Users\{your account}\.m2 on a Windows machine). Note that both Maven and the scala-maven-plugin will ignore any versions of Scala you have installed on your machine.
So which version of Scala is the plugin going to download for you? The value ${scala.version} states that the version number is stored as the value of a property named scala.version. Your pom.xml file also has lines, near the top, that create this property:
<project ...>
...
<properties>
<scala.version>2.7.0</scala.version>
</properties>
...
</project>
So, you can see that you will use version 2.7.0 of the Scala compiler. If you want to use the latest Scala version, you should change this to:
<project ...>
...
<properties>
<scala.version>2.12.6</scala.version>
</properties>
...
</project>
OK, so now you will be using the latest version of the Scala compiler. Now let's move on to IntelliJ...
IntelliJ IDEA is an Integrated Development Environment (IDE), primarily aimed at development with the Java language. It provides syntax highlighting, smart code completion, and other features to simplify the process of writing code. In order to provide those features for the Scala programming language, you need to install its Scala plugin.
You can configure IntelliJ to use any version of Scala that you have installed on your machine. IntelliJ will then know how to compile, build and run your software and can work without using your Maven project object model (POM) file's build definition.
However, one of the reasons for using Maven is to ensure a consistent build environment for developing a project, so that it is not at the whim of whatever each developer may or may not have installed on their machine. For this reason, if a project uses Maven, it's a good idea to tell IntelliJ. That way, IntelliJ can use Maven's pom.xml file to specify the version of the compiler, download dependencies, configure the compiler settings, etc.
So, the above information should help you to get up-and-running with your project, working with your corporation's network proxy and using the latest version of Scala, using Maven and IntelliJ.

Dynamic maven artifactId

Is it possible for a POM to declare (or at least publish) an artifactId containing system properties? I mean the artifactId of the actual project, not dependencies.
I am using maven to build a scala project and thus, to allow publishing the project for different scala versions, in the pom.xml I'd like to declare:
<artifactId>myproject_${scalaBinaryVersion}</artifactId>
however maven 3.3. complains
[WARNING] 'artifactId' contains an expression but should be a constant
Since I'd like this project to be interoperable with sbt, what would be the best way to publish an artifact suffixed with the scala binary version?
The Maven way of doing so would be to use classifiers. From official documentation an example matches exactly your case (for different Java versions, but you can replace Java with Scala):
The classifier allows to distinguish artifacts that were built from the same POM but differ in their content. It is some optional and arbitrary string that - if present - is appended to the artifact name just after the version number.
As a motivation for this element, consider for example a project that offers an artifact targeting JRE 1.5 but at the same time also an artifact that still supports JRE 1.4. The first artifact could be equipped with the classifier jdk15 and the second one with jdk14 such that clients can choose which one to use.
You can configure your POM as following:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>${scalaBinaryVersion}</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Note: we are adding an additional execution of the Maven Jar Plugin, so the project would create two jars, the normal one + an additional one with the specified (dynamic) classifier.
Then Maven will automatically publish the classified jar together with the normal jar (since it will be automatically attached to the build). You can then import it as a further Maven dependency in another project specifying its classifier as part of the Maven GAV (GAVC in this case):
<dependency>
<groupId>your.group.id</groupId>
<artifactId>your.constant.artifact.id</artifactId>
<version>your.version</version>
<classifier>your.dynamic.classifier</classifier>
</dependency>
If you want to only build the classified one and no standard (unused) jar, you can skip the creation of the normal jar as following:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-jar</id>
<phase>none</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<id>scala-version-jar</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>${scalaBinaryVersion}</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Note: we are simply overriding the default execution of the Jar Plugin and binding it to a non existing phase. Hence Maven will only generate the classified Jar. The Install Plugin will then only install the classified one.
Update: how to have dynamic artifactId installed with dynamic dependencies
If different transitive dependencies are required for different dynamic versions, then indeed classifiers are not suitable.
Dynamic artifactIds with dynamic dependencies (and hence dynamic transitive dependencies) can however be achieved. Here below is the approach I used (and successfully tested):
As preference, I isolated the dynamic behavior in a profile, but you can obviously move it back to the default build (or have the profile active by default).
First of all, let's define in our pom the dependencies requiring a dynamic version, hence via properties as following:
<properties>
<scalaBinaryVersion>scalaversion</scalaBinaryVersion>
<dependency.version>4.11</dependency.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${dependency.version}</version>
</dependency>
</dependencies>
Note: for the sake of an example, I'm using Junit as dependency in this case and not in test scope, because I want it as compile dependency (again, just for this example).
Then let's define a profile for our dynamic behavior:
<profiles>
<profile>
<id>build-scala-version</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<finalName>${project.artifactId}_${scalaBinaryVersion}-${project.version}</finalName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>copy-pom</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${scalaBinaryVersion}</outputDirectory>
<resources>
<resource>
<directory>${basedir}</directory>
<includes>
<include>pom.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.1</version>
<executions>
<execution>
<id>replace-artifactid</id>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
<configuration>
<file>target/${scalaBinaryVersion}/pom.xml</file>
<token><artifactId>${project.artifactId}</artifactId></token>
<!-- Replace to -->
<value><artifactId>${project.artifactId}_${scalaBinaryVersion}</artifactId></value>
<outputDir>target\${scalaBinaryVersion}\replacer</outputDir>
<outputFile>pom.xml</outputFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>default-install</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
<execution>
<id>install-scala-version</id>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}_${scalaBinaryVersion}</artifactId>
<version>${project.version}</version>
<packaging>${project.packaging}</packaging>
<file>${project.build.directory}/${project.artifactId}_${scalaBinaryVersion}-${project.version}.jar</file>
<pomFile>${project.build.directory}/${scalaBinaryVersion}/replacer/pom.xml</pomFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Note, the profile is customizing and providing the following:
Changing the final Jar name with a dynamic name, depending on the runtime (aka dynamic) value, to ${project.artifactId}_{scalaBinaryVersion}-${project.version}
Filtering the existing pom file via the Maven Resources Plugin and copying it to the directory target\${scalaBinaryVersion}. The copied pom will have the dependencies with the dynamic version because the Resources Plugin will replace them. However, it will not have the dynamic artifactId (yet).
Finalizing the dynamic pom file. The Replacer plugin will replace the artifactId XML element with the dynamic value (working on the target folder, hence everything on temporarely files)
Skipping the generation of the default installation
Performing a custom install-file installation with the dynamic pom file (the filtered, copied and replaced one, providing dynamic dependencies (and as such dynamic transitive dependencies) and a dynamic artifactId
Hence, performing the following maven invocation:
mvn clean install -Pbuild-scala-version -DscalaBinaryVersion=hello -Ddependency.version=4.4
Maven will effectively install a new artifact in the local cache for the dynamic artifactId, the dynamic dependency version and the dynamic pom.
Note: if the concerned dependency version(s) and the dynamic scala version is the same, then you can save up a parameter and make the invocation shorter and more consistent.
if you are using maven for that I will saggest using multi pom with maven helper plugin so the artifactId is constant in each module.
We follow the properties (via profiles) based approach as suggested here: scala-maven-plugin FAQ
<artifactId>something_${scala.compat.version}</artifactId>
<properties>
<scala.compat.version>2.12</scala.compat.version>
</properties>
maven will still issue a warning (with good reason), but with the help of the flatten-maven-plugin we build/install poms that has the variables replaced.

Require Java 8 to build Scala project using Maven

I'm using scala-maven-plugin to build a Scala project using Maven. My project depends on some libraries from Java 8. I would like to specify in my pom that the project requires Java 8 (using something akin to -target=jdk-1.8, which appears not to exist) so that it will fail a little more elegantly/informatively when someone tries to compile using Java version < 8. Currently it just fails to find the packages I'm trying to import.
I tried adding maven-compiler-plugin with source and target set to 1.8, and this didn't work, presumably because scala-maven-plugin is handling compilation instead of maven-compiler-plugin.
Is this possible?
You can use Maven Enforcer Plugin to enforce some rules to be asserted when running your Maven build.
Here you want to make sure that the Java version used is at least 8. You can achieve this by adding the following to your pom.xml file:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>enforce-java</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>[1.8,)</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

In IntelliJ Scala plugin, can I use scala-compiler.jar retrieved via <dependency> in `pom.xml`?

In IntelliJ, I created a blank Maven project, and added to pom.xml:
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-compiler</artifactId>
<version>2.11.0-M3</version>
<scope>compile</scope>
</dependency>
I then went to Project Settings -> Modules -> + -> Scala, and specified the compiler jar from the drop-down menu as Maven: org.scala-lang:scala-compiler:2.11.0-M3. I receive the error:
Compiler library: no scala-library*.jar found
Of course, scala-library-2.11.0-M3.jar is among the dependencies (transitively), but not stored in the same folder as scala-compiler-2.11.0-M3.jar, which is what seems to be confusing the Scala plugin.
Is there any way to use scala-compiler*.jar downloaded from a pom.xml dependency? Perhaps by manually specifying where to find each JAR?
Before this, I had been using scala-compiler*.jar downloaded via Project Settings -> Libraries -> + -> From Maven. This seems to work because IntelliJ sticks all the downloaded JARs in the same folder, which is what the Scala plugin assumes. Simply for aesthetic reasons I would like to know if it can be done with pom.xml.
You don't need the scala-compiler as a dependency to be able to build the scala project (neither using maven at command line nor by building from Build | Make Project in IntelliJ).
This is a very simple pom.xml that I use for scala projects where I don't have scala installed at all and just point IntelliJ to this pom and then I can compile and run any scala code directly from within IntelliJ.
<?xml version="1.0" encoding="UTF-8"?>
<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>com.stackoverflow</groupId>
<artifactId>scala-app</artifactId>
<version>1.0-SNAPSHOT</version>
<name>${project.artifactId}-${project.version}</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<scala.version>2.10.1</scala.version>
</properties>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>2.15.2</version>
<executions>
<execution>
<id>scala-compile</id>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
<configuration>
<args>
<arg>-make:transitive</arg>
<arg>-dependencyfile</arg>
<arg>${project.build.directory}/.scala_dependencies</arg>
</args>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

GWT compilation is skipped in maven when module packaging is pom

I am trying to reuse a assembled gwt compilation in another war. For this i am try to change the current maven module's packaging from war to pom. I then plan to use maven-assembly-plugin to zip up gwt's module js output and use that later on in another war module.
I tried changing the packaging tag from <packaging>war</packaging> to <packaging>pom</packaging> in pom.xml from Validation sample . gwt-maven-plugin never enters into compilation. Instead, it skips compilation!!!!!
What is happening?
Is this expected?
Is there any workaround?
To join multiple gwt compiled modules into a single .war file, it is very easy with the maven-dependency-plugin
Package all your gwt examples as habitual (.war), and install them mvn install or mvn deploy if you have a private maven repo.
Create an empty maven module of type war, with no code but with the maven folder structure, you can put any additional stuff you need here like a global src/main/webapp/index.html.
Configure the new module to use the maven-dependency-plugin like shown below, and run mvn package:
<dependency>
<groupId>my.group</groupId>
<artifactId>example1</artifactId>
<version>...</version>
<type>war</type>
</dependency>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-gwt-examples</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>my.group</includeGroupIds>
<includes>**/example1/**</includes>
<outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Finally and related with the gwt-maven-plugin, like with any other maven pluging, it would be enough to select an appropriate phase of the pom-packaging life cycle (package, install or deploy):
...
<packaging>pom</packaging>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
...
<configuration>
...
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
Unfortunately, gwt-maven-plugin specifically disallows compilation when packaging is pom, take a look to line #269 of CompileMojo.java
You can create the reusable modules (that you mention as samples in the comments) as separate GWT projects with no EntryPoint. Package them as jar and add the following as resources:
the client side source code
other resource items that will be necessary for the final compilation (images, xml files, etc.)
Something like this:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
...
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/services/**</include>
<include>**/client/**</include>
<include>**/public/**</include>
<include>**/*.gwt.xml</include>
</includes>
</resource>
</resources>
</build>
That's it, you can reuse it in any other GWT project. When you will do so, you just have to add the dependency (to the reusable module) in the pom.xml and import in the *.gwt.xml.
As for Maven's behaviour, it seems correct. pom packaging is going through package, install and deploy phases and
By default, the compile goal is configured to be executed during the ''prepare-package'' phase to run as late as possible.
You could change the phase in the plugin's execution, but I think it's risky because you can't know when exactly during the package phase will your code get compiled.