Scala файл класса vs файл класса Java

Скажем, у меня есть этот Hello.scala.

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello, world!")
  }
}

Я могу запустить 'scalac', чтобы получить HelloWorld.class и HelloWorld $.class. Я могу запустить с помощью scala -classpath. Здравствуйте'. Но я не могу запустить java -cp. Hello".

  • Почему это? Не совместимо ли scala с Java?
  • Есть ли способ запустить класс scala с Java?
  • Почему scalac создает два файла класса?
  • Есть ли у scala что-то вроде "lein uber"? Я имею в виду, имеет ли scala несколько инструментов, которые генерируют один файл jar для целей распространения?

Плагин IntelliJ + scala

Я мог бы получить банку, содержащую все, чтобы запустить файл scala с плагином IntelliJ + scala, я думаю, что это лучший вариант, чем proguard.

настройка proguard

Благодаря Морицу я могу создать один файл jar, который будет запущен с помощью java. Это общая структура.

|-- 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, я мог бы сделать банку (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

Я загружу пример zip файла здесь. И, скалярный исходный код здесь.

Ответ 1

Вам нужно добавить Scala в путь к классам, например.

-classpath scala-library.jar:.

или добавив

-Xbootclasspath/a:scala-library.jar

для аргументов VM.

Дополнение:

Извините, не видел последний вопрос. Если вы хотите распространять отдельные файлы JAR, многие люди используют ProGuard для отправки классов, необходимых из scala -library.jar, а также ваши классы в одной банке.

Второе редактирование:

Предполагая, что у вас есть ваши .class файлы и ваша папка META-INF, содержащая MANIFEST.MF в папке с именем classes, вы можете использовать следующую конфигурацию Proguard (после настройки путей, например, вам нужно rt.jar в Linux/Windows вместо classes.jar на Mac OS), например, как your.pro:

-injar classes
-injar /opt/local/share/scala-2.8/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 your.Main { public static void main(java.lang.String[]); }

Теперь вы можете создать main.jar с помощью

java -Xmx512m -jar proguard.jar @your.pro

В конце концов вам нужно установить -Xmx немного выше. Более подробную информацию можно найти на SBT Wiki.