Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala class file vs Java class file

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.

like image 469
prosseek Avatar asked Jul 29 '10 20:07

prosseek


People also ask

What is the difference between Java file and class file?

A . java file contains your Java source code while a . class file contains the Java bytecode produced by the Java compiler.

How do I read a class file in Scala?

Scala does not provide class to write a file but it provide a class to read the files. This is the class Source. We use its companion object to read files. To read the contents of this file, we call the fromFile() method of class Source for reading the contents of the file which includes filename as argument.

What is the difference between Scala object and class?

Difference Between Scala Classes and Objects Definition: A class is defined with the class keyword while an object is defined using the object keyword. Also, whereas a class can take parameters, an object can't take any parameter. Instantiation: To instantiate a regular class, we use the new keyword.

What is difference between jar file and class file?

You can use JAR files to store class files. The class file does not target a specific hardware platform, but instead targets the Java virtual machine architecture. You can use JAR as a general archiving tool and also to distribute Java programs of all types, including applets.


1 Answers

You need to add Scala to the classpath, e.g.

-classpath scala-library.jar:.

or by adding

-Xbootclasspath/a:scala-library.jar

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 the MANIFEST.MF in a folder called classes you can use the following Proguard configuration (after adjusting the paths, e.g. you need rt.jar on Linux/Windows instead of classes.jar on Mac OS) saved e.g. as 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[]); }

Now you can create main.jar with

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

Eventually you have to set the -Xmx a bit higher. Some more info can be found on the SBT Wiki.

like image 156
Moritz Avatar answered Oct 01 '22 01:10

Moritz