在包中运行 Scala 代码 (LinkedIn Norbert)
Posted
技术标签:
【中文标题】在包中运行 Scala 代码 (LinkedIn Norbert)【英文标题】:run Scala code in package (LinkedIn Norbert) 【发布时间】:2013-12-23 00:03:09 【问题描述】:我正在尝试运行一个名为 NorbertClusterClientMain 的 Scala 对象,该对象位于 com.linkedin.norbert.cluster 包中。它的源代码位于 rhavyn 的 LinkedIn Norbert 开源分支的示例/src/main/scala 文件夹中,我正在使用 Linux 命令行。
虽然有人告诉我在包中运行 Scala 代码就像在包中运行 Java,但我在 examples/src/main/scala
但不能使用此命令:
$ scala com.linkedin.norbert.cluster.NorbertClusterClientMain
我得到“类路径上没有这样的文件或类”,即使该文件存在。
我成功地编译了 Norbert
$ mvn clean -DskipTests install
如何运行 NorbertClusterClientMain?请告诉我。感谢您的帮助。
【问题讨论】:
我在下面解释了我是如何设法执行 NorbertClusterClientMain 类的。它对你有用吗? 谢谢。我最终使用 sbt 构建并创建了一个长而复杂的类路径,我在 Java 中运行它。没有一个答案能很好地说明我最终做了什么。 是的,我已经越过了这个障碍。 我实际上想要一种简单的方法来通过 sbt 获取类路径,但要做到这一点并不容易。我在这里提交了一张票 - github.com/sbt/sbt/issues/1044 。所以我也使用了 Maven。 【参考方案1】:是一样的。所以,在这种情况下,它正在寻找这个文件:
./com/linkedin/norbert/cluster/NorbertClusterClientMain.class
这就是 Java 的工作方式,因为“运行”一个 Scala 程序只是在运行 java 并在类路径中传递 Scala 库,所以它必须是相同的。
顺便问一下,你是如何编译它的?没关系,看到你的评论。在您运行mvn
的目录中,您应该可以像这样运行它:
scala -cp target com.linkedin.norbert.cluster.NorbertClusterClientMain
如果失败,请找到类文件,并将com/
所在的目录传递给类路径。
【讨论】:
我是用Maven编译的,所以target/目录下有JAR和.class文件。 .class 文件似乎不在该路径上。 尝试在多个目录中使用 -cp 目标运行它,但仍然无法正常工作。【参考方案2】:您的 mvn
脚本在目标目录中生成 JAR 和类文件:
./target/com/.../<someClassName1>.class
./target/com/.../<someClassName2>.class
... etc
./target/<someJarName1>.jar
./target/<someJarName2>.jar
... etc
太棒了!现在做你必须为java做的同样的事情;包含在您的类路径中:
目标基目录(这会“拾取”target
下的目录层次结构中的所有类文件)
每个 jar 文件(这会“拾取”每个 JAR
内目录层次结构中的所有类文件)
scala -cp target:target/<someJarName1>.jar:target/<someJarName2>.jar:... etc ./com.linkedin.norbert.cluster.NorbertClusterClientMain
这里的-cp
(或等效的CLASSPATH
环境变量)是java 类路径,因此具有与java 相同的语法和规则。
顺便说一句:“sbt”是构建 scala 项目的标准、强大、可用的方式。它使用 Ivy 从代码存储库(即 mvn++)中“拉取”依赖项。开始使用它的最佳方式是下载 sbt 示例项目,搜索“sbt 教程”博客并阅读 sbt docs。 :)
【讨论】:
OP 在 Linux 上,re: semis 在类路径中。【参考方案3】:我对代码库一无所知,但该类在示例子项目中。
这表明它可以正常加载。 (我没有配置任何东西,因为我对代码库一无所知。)
apm@mara:~/clones/norbert$ cd examples
/home/apm/clones/norbert/examples
apm@mara:~/clones/norbert/examples$ ls
pom.xml src target
apm@mara:~/clones/norbert/examples$ mvn exec:java -Dexec.mainClass=com.linkedin.norbert.cluster.NorbertClusterClientMain
[INFO] Scanning for projects...
<snip...>
[INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ norbert-examples ---
[WARNING]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
at com.linkedin.norbert.cluster.NorbertClusterClientMain$.main(NorbertClusterClientMain.scala:22)
at com.linkedin.norbert.cluster.NorbertClusterClientMain.main(NorbertClusterClientMain.scala)
... 6 more
添加参数的方法如下:
https://***.com/a/9846103/1296806
我不再使用 maven。
编辑:我也不再使用 Scala 2.7.7。
【讨论】:
【参考方案4】:试试$ scala ./com.linkedin.norbert.cluster.NorbertClusterClientMain
或-cp .
你的“当前目录”可能不在类路径中
【讨论】:
哦,我认为你完全在错误的文件夹中,你的编译文件将在bin
,你提到你在src
源码中没有bin/文件夹。虽然有几个目标/文件夹...
嗯,愚蠢的问题,但你确定你已经编译了吗?类似于 javac/java 你需要做 scalac/scala
我按照网上的说明使用 Maven $ mvn -DskipTests install 编译了【参考方案5】:
Norbert 使用 Scala 2.7,因此直接从 CLI 使用 Scala 可能不适合您。因此使用Maven找到所有依赖jar并使用它。
我就是这样做的。
首先,查看代码:
$ git clone https://github.com/rhavyn/norbert
$ cd norbert/
首先在本地仓库中构建和安装依赖项:
$ mvn clean install
设置一个类路径变量,我们稍后将用于示例/文件夹:
$ cd examples/
$ export CP=$(mvn dependency:build-classpath | grep -A1 'Dependencies classpath:' | tail -1)
从examples/文件夹运行服务器:
$ java -cp $CP:target/classes com.linkedin.norbert.network.javaapi.NorbertJavaNetworkServerMain arg0 arg1
log4j:ERROR Could not find value for key log4j.appender.R
log4j:ERROR Could not instantiate appender named "R".
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at com.linkedin.norbert.network.javaapi.NorbertJavaNetworkServerMain.main(NorbertJavaNetworkServerMain.java:33)
从examples/文件夹运行客户端:
$ java -cp $CP:target/classes com.linkedin.norbert.cluster.NorbertClusterClientMain localhost 1011
log4j:ERROR Could not find value for key log4j.appender.R
log4j:ERROR Could not instantiate appender named "R".
> h2013-12-20 13:59:44,323 - WARN [pool-1-thread-2-SendThread(0.0.3.243:2181):ClientCnxn$SendThread@1120] - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect
java.net.SocketException: Invalid argument
at sun.nio.ch.Net.connect0(Native Method)
at sun.nio.ch.Net.connect(Net.java:364)
at sun.nio.ch.Net.connect(Net.java:356)
at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:623)
at org.apache.zookeeper.ClientCnxn$SendThread.startConnect(ClientCnxn.java:1009)
at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1036)
2013-12-20 13:59:46,192 - WARN [pool-1-thread-2-SendThread(0.0.3.243:2181):ClientCnxn$SendThread@1120] - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect
java.net.SocketException: Invalid argument
at sun.nio.ch.Net.connect0(Native Method)
at sun.nio.ch.Net.connect(Net.java:364)
at sun.nio.ch.Net.connect(Net.java:356)
at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:623)
at org.apache.zookeeper.ClientCnxn$SendThread.startConnect(ClientCnxn.java:1009)
at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1036)
就是这样。现在您所要做的就是设置所需的服务,例如 Zookeper 等。
【讨论】:
以上是关于在包中运行 Scala 代码 (LinkedIn Norbert)的主要内容,如果未能解决你的问题,请参考以下文章
如果 java Hello World 程序在包中,为啥我不能运行它?