Scala 类文件与 Java 类文件
假设我有这个 Hello.scala。
object HelloWorld {
def main(args: Array[String]) {
println("Hello, world!")
}
}
我可以运行“scalac”来获取 HelloWorld.class 和 HelloWorld$.class。 我可以使用 'scala -classpath 运行。你好'。但我无法运行“java -cp”。你好'。
- 这是为什么呢? scala 不能与 Java 互操作吗?
- 有没有办法用Java运行scala的类?
- 为什么 scalac 会生成两个类文件?
- scala 有类似“lein uber”的东西吗?我的意思是,scala 是否有一些工具可以生成一个 jar 文件用于分发目的?
IntelliJ + scala 插件
我可以获得一个 jar,其中包含使用 IntelliJ + scala 插件运行 scala 文件的所有内容,我认为这是比 proguard 更好的选择。
proguard 设置
感谢 Moritz,我可以制作一个用 java 运行的 jar 文件。 这是整体结构。
|-- classes | |-- HelloWorld$.class | |-- HelloWorld.class | `-- META-INF | `-- MANIFEST.MF `-- your.pro
your.pro 有以下内容。
-injar classes -injar /Users/smcho/bin/scala/lib/scala-library.jar(!META-INF/MANIFEST.MF) -outjar main.jar -libraryjar /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Classes/classes.jar -dontwarn -dontnote -ignorewarnings -optimizationpasses 2 -optimizations !code/allocation/variable -keep,allowoptimization,allowshrinking class * { *; } -keepattributes SourceFile,LineNumberTable -keepclasseswithmembers public class HelloWorld { public static void main(java.lang.String[]); }
MANIFEST.MF 有以下设置。不要忘记包含 [CR] 或空行。
Main-Class: HelloWorld
我下载了 proguard 4.5.1 将其放在 ~/bin/proguard4.5.1 中。 运行 proguard,我可以制作 jar (main.jar),并且它工作正常。
prosseek:classes smcho$ java -Xmx512m -jar /Users/smcho/bin/proguard4.5.1/lib/proguard.jar @your.pro ProGuard, version 4.5.1 Reading program directory [/Users/smcho/Desktop/scala/proguard/classes/classes] Reading program jar [/Users/smcho/bin/scala/lib/scala-library.jar] (filtered) Reading library jar [/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Classes/classes.jar] Preparing output jar [/Users/smcho/Desktop/scala/proguard/classes/main.jar] Copying resources from program directory [/Users/smcho/Desktop/scala/proguard/classes/classes] Copying resources from program jar [/Users/smcho/bin/scala/lib/scala-library.jar] (filtered)
prosseek:classes smcho$ java -jar main.jar hello
或
java -cp main.jar HelloWorld
Let's say I have this Hello.scala.
object HelloWorld {
def main(args: Array[String]) {
println("Hello, world!")
}
}
I could run 'scalac' to get HelloWorld.class and HelloWorld$.class.
I can run using 'scala -classpath . Hello'. But I can't run 'java -cp . Hello'.
- Why is this? Isn't scala interoperable with Java?
- Is there any way to run scala's class with Java?
- Why the scalac produces two class files?
- Does scala have something like 'lein uber'? I mean, does scala have some tools that generates one jar file for distribution purposes?
IntelliJ + scala plugin
I could get a jar that contains everything to run scala file file with IntelliJ + scala plugin, I think this is the better option than proguard.
proguard setup
Thanks to Moritz, I could make one jar file that be run with java.
This is the overall structure.
|-- classes | |-- HelloWorld$.class | |-- HelloWorld.class | `-- META-INF | `-- MANIFEST.MF `-- your.pro
your.pro has the following contents.
-injar classes -injar /Users/smcho/bin/scala/lib/scala-library.jar(!META-INF/MANIFEST.MF) -outjar main.jar -libraryjar /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Classes/classes.jar -dontwarn -dontnote -ignorewarnings -optimizationpasses 2 -optimizations !code/allocation/variable -keep,allowoptimization,allowshrinking class * { *; } -keepattributes SourceFile,LineNumberTable -keepclasseswithmembers public class HelloWorld { public static void main(java.lang.String[]); }
MANIFEST.MF has following setup. Don't forget to include [CR] or blank line.
Main-Class: HelloWorld
I download the proguard 4.5.1 to put it in ~/bin/proguard4.5.1.
Running proguard, I could make the jar (main.jar), and it works fine.
prosseek:classes smcho$ java -Xmx512m -jar /Users/smcho/bin/proguard4.5.1/lib/proguard.jar @your.pro ProGuard, version 4.5.1 Reading program directory [/Users/smcho/Desktop/scala/proguard/classes/classes] Reading program jar [/Users/smcho/bin/scala/lib/scala-library.jar] (filtered) Reading library jar [/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Classes/classes.jar] Preparing output jar [/Users/smcho/Desktop/scala/proguard/classes/main.jar] Copying resources from program directory [/Users/smcho/Desktop/scala/proguard/classes/classes] Copying resources from program jar [/Users/smcho/bin/scala/lib/scala-library.jar] (filtered)
prosseek:classes smcho$ java -jar main.jar hello
or
java -cp main.jar HelloWorld
I upload the example zip file here. And, scalar source code here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要将 Scala 添加到类路径,例如
或通过添加
到 VM 参数。
补充:
抱歉,没有看到最后一个问题。如果您想分发单个 JAR 文件,许多人使用 ProGuard 从 scala 库传送所需的类。将您的课程与您的课程一起放在一个罐子中。
第二次编辑:
假设您有 .class 文件和
META-INF
文件夹,其中包含MANIFEST.MF
,位于名为 classes 的文件夹中,您可以使用以下 Proguard 配置(调整路径后,例如,在 Linux/Windows 上您需要rt.jar
,而不是 Mac OS 上的classes.jar
),例如保存为your.pro
:现在您可以创建
main.jar
,最终您必须将
-Xmx
设置得更高一些。如需了解更多信息,请访问 SBT Wiki。You need to add Scala to the classpath, e.g.
or by adding
to the VM arguments.
Addition:
Sorry, did not see that last question. If you want do distribute single JAR files many people use ProGuard to ship the classes needed from the scala-library.jar along with your classes in one jar.
Second Edit:
Assuming you have your .class-files and your
META-INF
folder containing theMANIFEST.MF
in a folder called classes you can use the following Proguard configuration (after adjusting the paths, e.g. you needrt.jar
on Linux/Windows instead ofclasses.jar
on Mac OS) saved e.g. asyour.pro
:Now you can create
main.jar
withEventually you have to set the
-Xmx
a bit higher. Some more info can be found on the SBT Wiki.