我有一个新的Spark应用程序,我正在使用Scala在Maven上编写,我发现我甚至因某些原因无法运行“Hello World”。虽然编译工作正常,尝试运行jar本身最终会出错。
编辑:从依赖项中删除<scope>provided</scope>
,收到其他错误。
这是POM文件:
<modelVersion>4.0.0</modelVersion>
<groupId>com.app</groupId>
<artifactId>deviceScore</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>Device Score</name>
<properties>
<spark.version>1.6.2</spark.version>
<app.main.class>com.app.deviceScore.App</app.main.class>
</properties>
<profiles>
<profile>
<id>scala-2.10</id>
<properties>
<scala.version>2.10.6</scala.version>
<scala.binary.version>2.10</scala.binary.version>
</properties>
</profile>
<profile>
<id>scala-2.11</id>
<properties>
<scala.version>2.11.8</scala.version>
<scala.binary.version>2.11</scala.binary.version>
</properties>
</profile>
</profiles>
<repositories>
<repository>
<id>maven-repo</id>
<name>Maven Repository</name>
<url>http://repo1.maven.apache.org/maven2</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>s3.release</id>
<url>s3://clojure-deps/releases</url>
</repository>
<repository>
<id>apache-repo</id>
<name>Apache release repo</name>
<url>https://github.com/adatao/mvnrepos/tree/master/releases/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>scala-tools.org</id>
<name>Scala-Tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</pluginRepository>
<pluginRepository>
<id>protoc-plugin</id>
<url>http://sergei-ivanov.github.com/maven-protoc-plugin/repo/releases/</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-compiler</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_${scala.binary.version}</artifactId>
<version>2.2.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_${scala.binary.version}</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-hive_${scala.binary.version}</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.10.11</version>
</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.2.0</version>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-compiler</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-reflect</artifactId>
<version>${scala.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<scalaVersion>${scala.version}</scalaVersion>
<jvmArgs>
<jvmArg>-Xms256m</jvmArg>
<jvmArg>-Xmx2048m</jvmArg>
</jvmArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>${app.main.class}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
应用程序非常简单:
package com.app.deviceScore
object App {
def main(args: Array[String]) = {
println ("Hi!")
}
}
当我运行mvn clean package -P scala-2.11
时,构建运行正常,但是当我尝试运行jar时,我使用java -jar target/deviceScore-1.0.0.jar
得到:
Error: Could not find or load main class com.app.deviceScore.App
尝试scala target/deviceScore-1.0.0.jar
时,我得到了:
java.lang.ClassNotFoundException: com.app.deviceScore.App
at scala.reflect.internal.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:63)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:22)
at scala.tools.nsc.JarRunner$.run(MainGenericRunner.scala:13)
at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:29)
at scala.tools.nsc.JarRunner$.runJar(MainGenericRunner.scala:25)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:69)
at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:87)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:98)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
我错过了什么?为了简单地运行jar,应该在POM文件中包含什么?
答案 0 :(得分:2)
您已将scala-library
(以及其他Scala依赖项)定义为provided
- 这意味着它们不会打包在jar中,但很可能是提供在运行时外部,但它们不是 - 因此这些类在运行时丢失。
如果您从所有依赖项中删除<scope>provided</scope>
(可能scala-compiler
可以保留provided
),这应该可以。
修改强>:
根据你的更新 - 不确定为什么你得到那个特定的错误(应该找到主类),但似乎还有更多要修复的地方:当你使用maven的maven-jar-plugin
时,它会构建jar 而不用包括它的依赖项,这意味着你仍然不会有Scala的类。
相反,你可以使用maven的maven-assembly-plugin
来创建一个“胖罐子”,包含其依赖。通过用以下代码替换jar插件来实现:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>${app.main.class}</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>assemble-all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
然后,运行:
> mvn clean package -P scala-2.11
> java -jar target/deviceScore-1.0.0-jar-with-dependencies.jar
Hi!
答案 1 :(得分:1)
要运行打包在可运行jar文件中的Scala程序,请使用scala
命令而不是java -jar
:
scala target/deviceScore-1.0.0.jar
如果要使用java -jar
运行它,则必须确保Scala库包含在类路径中。通过将Scala库的范围设置为provided
,可以将其从运行时类路径中排除。
答案 2 :(得分:1)
让它发挥作用。在插件部分,我使用了这三个:
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>${app.main.class}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>${app.main.class}</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
第一个与前一个pom文件中使用的scala-maven-plugin
不同。第二个插件在使用scala target/deviceScore-1.0.0.jar
时使jar可执行,而Tzach Zohar提到的第三个插件创建了一个可以java -jar target/deviceScore-1.0.0-jar-with-dependencies.jar
执行的胖jar