在包中运行 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 程序在包中,为啥我不能运行它?

在包中运行模块没有模块错误[重复]

在包中找不到属性“layout_behavior”的资源标识符

在包中覆盖“defun”

在包中定义类