9

I'm developing an application on Eclipse with Scala and a would like to create a .jar. I have found tuto to do that, but it use the package scala.tools.nsc and I don't know where I can found this thing.
I have tried too, to generate the .class and then with the command jar cmf .... to generate the .jar but when I launch the .jar an error occur. (NoClassFound)
With sbt I have tried too, but when I compile my project that work with eclipse a lot of error appear.

Somebody can me explain how I can simply create a .jar with Eclipse or another tools.

user unknown
  • 35,537
  • 11
  • 75
  • 121
Snoopy
  • 99
  • 1
  • 1
  • 2
  • I corrected 'java cmf' to 'jar cmf', please review if this is ok. And look out at faq and meta and sidebar, how to edit your post. Layout and so on. In general, when asking because of an error: What did you exactly? Command? Cut'n'paste it, to avoid transfer errors. Copy and paste the exact error message. In which directory did you start the command, what is your file structure, what project name did you choose, did the file hierarchy correspond to the directories? Did you use `jar` before, for example with `Java` and with how much success? Thanks. – user unknown Jul 21 '11 at 21:04

5 Answers5

11

Eclipse has a build-in option to generate runnable jars, but it is well hidden. Also it does not recognize Scala's main() signatures, so you will have to create a Java class with a main() method.

  1. Create a Java class with a main() method which simply forwards the call to your Scala code.

  2. Then right click on your newly created Java class and select: Run As -> Java Application. This will create a runnable configuration which will later be used as a part of your runnable jar.

  3. Now you are ready to dig out the runnable jar option from the Eclipse's menu: File -> Export -> Java -> Runnable JAR file

  4. In the presented dialog select the Launch Configuration you have created earlier (in step2), name your jar (myapp.jar), select your dependency export options and click finish.

  5. The jar will be created in the Eclipse's workspace by default.

  6. Run the jar using the line: scala myapp.jar

Your question about missing images: Eclipse requires a manual refresh when files are added or removed. Right click on your project and select Refresh.

This concludes the tutorial on the highly intuitive Eclipse interface.

Note: Instructions for Eclipse version 3.6.2.

Lex
  • 1,184
  • 5
  • 11
  • Thanks, but it doesn't work.... I have created a java class with a main(). Then created the .jar and when I want to launch the jar the name of my app appears on the menu and on the terminal I have this error : "lang.ClassNotFoundException: scala.ScalaObject" and "java.lang.reflect.InvocationTargetException" and when I want to launch with the line : scala myapp.jar I have this error "Permission denied" – Snoopy Jul 22 '11 at 11:48
  • I have installed a new version on Scala, it's for that that I have the error "Permission denied" but now I have with the line : scala myapp.jar this error : error: IO error while decoding /Users/danymorard/Documents/workspace/myAppl1.jar with UTF-8 – Snoopy Jul 22 '11 at 12:13
  • Launching jars using "scala myapp.jar" is supported since Scala 2.9.0. Looks like you have an older version installed which tries to load the jar as a script file. Try launching the jar with "java -cp $SCALA_HOME/lib/scala-library.jar:myapp.jar mypackage.Mymain" – Lex Jul 23 '11 at 04:03
3

Jars

When you create a jar out of your classes, possibly the dependencies are not included in that jar. When running that jar, you need to put the jars containing the dependencies on the classpath (with the -cp switch to java). Most important dependency is the scala-library jar. Of course knowing what is not found by NoClassDefFound would help.

Sbt

When building with sbt, maybe it is missing dependencies that you have manually added to the Eclipse project? (Note: I did not use sbt).

Maven

I found the clearest and most painless way is to go with maven alone, or possibly maven + Intellij Idea (community edition is free) + Scala Plugin. Works very smooth.

For maven, you need to adapt the available scala archetype a bit since the libraries it refers to are not the most recent version, but apart from that it is very fine.

Here is a pom.xml I'm using: https://gist.github.com/1096870

Use the standard maven folder structure (source root is src/main/scala) and then mvn package creates the jar fine.

ron
  • 9,262
  • 4
  • 40
  • 73
  • @Snoopy: Don't say 'Thanks', but upvote helpful answers. That, which solves your problem best (if any) should be marked as accepted answer. – user unknown Jul 21 '11 at 21:35
1

Use the below steps for time being .But this is not the full time solution.Better to go for sbt build jar for Spark-Scala combination. Temporary solution using java class ,calling the scala main class. MainClass.java

public class MainClass {
    public static void main(String[] args) {
        SampleApp app=new SampleApp();
        app.main(args); }
}

SampleApp.scala

class SampleApp {
   def main(args: Array[String]) {  
     println("First Scala SampleApp")}  
}

Export it as a jar by using normal java jar export by choosing the MainClass main method. name the jar file as Sample.jar Run it in the Cluster using below command.

/spark/bin/spark-submit --class com.scala.MainClass SampleScala.jar

The output you can get as: First Scala SampleApp

Kumar Basapuram
  • 179
  • 2
  • 7
  • This did it for me. Super-annoying that Eclipse doesn't recognise Scala main files! – StackG Jun 26 '15 at 08:37
  • Also note that I created a new Java project and added the Scala libs, as recommended here: http://stackoverflow.com/questions/11413888/exporting-scala-project-as-jar-from-eclipse – StackG Jun 26 '15 at 08:53
0

To build off of what @Kumar Basapuram wrote:

Make a java class called "Wrapper.java".

package animals;
public class Wrapper {
    public static void main(String[] args) {
        SampleApp app=new SampleApp();
        app.main(args);
    }
}

Link this main method to the main method in the "SampleApp.scala" class.

package animals
class SampleApp {
  def main(args: Array[String]){
     var c = new Cow("Bessie", 100)
     println(c.speak)
     var h = new Horse("CJ", 50)
     println(h.speak)
     var s = new Sheep("Little Lamb", 25)
     println(s.speak)

     println(s.weigh)
     println(h.weigh)
     println(c.weigh)
  }
}

Project with Java and Scala Classes Picture

Right Click on the Project ScalaPracticeCreation. Click Export... Click Runnable JAR file under the Java folder Exporting Scala Class into a jar Executable Picture

Click Next >

Select Wrapper - ScalaPracticeCreations

Select Export destination to a place on your computer

Select "Extract required libraries into generated JAR" under the "Library handling:" option

Click Finish

Run the file through the Eclipse IDE and it works.

Run it through the Command Prompt and it does not work. Command Prompt Picture

To fix this remove the println methods from the "SampleApp.scala".

package animals
class SampleApp {
  def main(args: Array[String]) {
    var c = new Cow("Bessie", 100)
    var h = new Horse("CJ", 50)
    var s = new Sheep("Little Lamb", 25)
    c.weigh().toString()
  }
}

add "System.out.println(app.main(args));" to replace "app.main(args);" in the Wrapper.java class

package animals;
public class Wrapper {
    public static void main(String[] args) {
        SampleApp app=new SampleApp();
        System.out.println(app.main(args));
    }
}

Now reexport the program after running it. success in the command prompt Picture

Now it works.

Here are the extra filler .scala classes. Note that the Demo.scala class is irrelevant.

Weight.scala:

package animals
abstract class Weight(size: Int) {
  def weigh = "My size is " + size
}

Animal.scala:

package animals
abstract class Animal(name: String, weight: Int) extends Weight(weight){
  def speak = name + " says " + sound
  def sound: String
  override def weigh() = "My name is " + name + " and I weigh: " + weight
}

Cow.scala:

package animals
class Cow (name: String, weight: Int) extends Animal(name,weight){
  override def sound() = "mooooo"
}

Horse.scala:

package animals
class Horse (name: String, weight: Int) extends Animal(name,weight){
  override def sound() = "neigh"
}

Sheep.scala:

package animals    
class Sheep (name: String, weight: Int) extends Animal(name,weight) {
  override def sound() = "baaaa"
}

Note that this may not be the best solution although it is a functional solution. Scala sbt may be a better solution: Scala sbt or this Scala sbt-assembly.

Sean
  • 1
0
% cat a.scala 
package foo

object Whee {
  def main(args: Array[String]): Unit = {
    println("I'm in a jar")    
  }
}
% scalac29 -d whee.jar a.scala 
% scala29 -cp whee.jar foo.Whee
I'm in a jar
%
psp
  • 12,138
  • 1
  • 41
  • 51
  • Tanks for the answer, but I understand nothing what you are doing – Snoopy Jul 23 '11 at 11:26
  • This does not make a runable jar for you. It only compresses your code inside of a jar file. To make it runable, you need to at a manifest, where you define the main-class. – tgr Sep 25 '12 at 09:43