If I run a jar as follows
java -jar Name.jar arg1 arg2 arg3
it is understandable that when exporting (creating the .jar) I would have had to specify an Eclipse run configuration in order to identify the main method because there may be as many main methods as there are classes.
If I run a main program from within Eclipse, it silently creates a new run configuration which adds more clutter to the run configuration choices available when I want to export. If I do this for many classes, the chances are I have many essentially identical run configurations, with the only difference being the main method specified.
If I run a jar as follows
java -cp Name.jar package.MyObject arg1 arg2
java -cp Name.jar package.MyOtherObject arg1
then the Eclipse run configuration which identifies the main method is probably ignored. The entry point is identified on the command line. In this case, the fact that Eclipse requires a run configuration during the export process, seems to create a chore, but there seems to be no way to avoid this.
I prefer to run my .jar via the -cp option because it gives me access to many entry points. This way I don't have to re-export when I want to access a different entry point. The decision as to which entry point to use is postponed until the time I want to run. I don't have to decide when exporting. I preserve flexibility.
I know an alternative way is to just have an arg1 that specifies the task, so I can rely on just one run configuration that identifies the main method that has a big switch statement and then always invoke Java with the -jar option.
If I use -jar there is the clutter of many run configurations. If I use -cp there seems to be an nuisance step in the export process that involves the clutter of many run configurations. Is there a way to use Eclipse that avoids both of these problems?
Open the project and select File and Export and Java and JAR file. Do not select Runnable JAR file.
By default, every file in the project folder is check-boxed as a resource meant to be exported and you may want to un-check some or all of them. Unfortunately Eclipse does not remember this so you may have to un-check resources every time you are exporting.
Check-box the src directory which unfortunately makes it appear you want to export source but actually you need to check-box it in order to export the corresponding .class files.
Check-box Export generated class files and resources.
Browse to the destination JAR file that you want to export or overwrite.
Click finish.
Eclipse does not consider third-party JAR files to be resources in the above step 2 so you need to find a way to provide them to the -classpath or -cp when you invoke Java. The reason we need to do this is because when Eclipse exports a "JAR file" it doesn't seem to follow the build paths to your third-party JAR files. This is a capability that Eclipse has when it exports a "Runnable JAR file" but that's not what we are doing here. You can manually create a directory of your third-party JAR files and let Java expand a wildcard in -classpath.
Example Java invocation in linux:
java -cp ~/directory/destination.jar:/home/username/directory/thirdparty/"*" com.domain.package.MyObject arg1 arg2 arg3
Note that on linux we can allow bash to expand the ~ for your own JAR file, "destination.jar". For the third-party JAR files the long form /home/username is used because tilde expansion might not work in the middle of the string, just after the colon.
If we want to use the Java * wildcard -- not the same thing as the bash command line wildcard -- for the third-party JAR files, the * character must be quoted (made literal) in order for the wildcard to be passed to Java.
Exporting this way eliminates the need to select a run configuration and addresses the concern that prompted the question.
Aside: If your own JAR is exported to the same directory as the third-party JARs then classpath is simpler:
java -cp ~/singleDirectory/"*" com.domain.package.MyObject arg1 arg2 arg3
Related
Question: When running Maven in Eclipse, how do I send the console output to file?
I would like to achieve this using a pom setting or a maven plugin. I do not want to modify the run configurations or the maven system settings.
For reference, I am using Windows 7, Eclipse Luna, Java 6, Maven 3.
As per official command line options you could use -l,--log-file <arg> which provide the:
Log file where all build output will go.
As such, running:
mvn clean install -l output.log
Would not print anything to the console and automatically redirect the whole build output to the output.log file.
If you don't want to type it every time (or you actually don't want to use the command line) and you want it as default option (although rare case I would suppose), you could use new command line options behavior available since version 3.3.1 and have a .mvn folder where the concerned pom.xml file is located and a maven.config file in it simply providing the following line:
-l output.log
That is, the .mvn/maven.config file replaces MAVEN_OPTIONS just for its project, locally where it has been created, with the options it provides, not impacting other builds as per Maven settings of MAVEN_OPTIONS.
This is an IDE agnostic solution (it's a new built-in feature of Maven) and local to a project, but still not provided via simple POM editing, which cannot be achieved since the first phase of Maven default life cycle phases is validate, which:
validate the project is correct and all necessary information is available
That is, during the build, hence when the build has already started (and generated output), it validates the pom.xml file, hence too late to redirect build output at that stage based on some POM properties/plugin.
Go to run as and choose Run Configuration -> Commons -> Select a file.
This should redirect your output to the file you specified.
According to this you can try editing the ${MAVEN_HOME}/conf/logging/simplelogger.properties. I gave it a quick try and maven's output is redirected, but anything else writing to stdout (tests, for instance) still writes on the console
What about creating a fork of M2E and modifying it to read the output file for the launch config from pom.xml
https://github.com/eclipse/m2e-core.git
A possible solution is setting the output format in the mvn file. For example, in the directory /usr/bin, add the desired output informing the path the log will be saved at the end of exec "$JAVACMD" \ line: | tee /home/maven-log.log.
However, it only works when the maven is called by terminal line; when called by IDEs, like eclipse, this solutions does not work.
I have a selenium project in eclipse that i want to distribute to manual testers with no Eclipse or Java knowledge. Hence i am looking to distribute it to them as executable files so that they dont need to use eclipse to run them. Can any one suggest the best way to do this without having to install any 3rd party extensions?
P.S : My organisation doesnt allow me to install 3rd party extensions on Eclipse. It will require a lot of approvals. Hence i am wondering if there is any method available inside Eclipse itself?
I've done it some years ago, in my eclipse version:
file -> export -> java -> Runnable jar file
If you want an exe file you can use: Launch4J
Export your project as jar file and create a .bat file which will include all the necessary libraries in your classpath with your project and then make a call to the underlying script (in case if you are using testng then testng has option to make command line calls)
else use Maven
EDIT:
Something on below lines:
1. Create run.bat file
2. Content of the bat file:
JAVA_HOME={Path to your JDK}
CLASSPATH=%PATH%;{All the dependent jar files of your project as well as you project}
{Call to your Junit Script from command line} Something like this Run JUnit from command line
3. Run your batch file (run.bat)
I may not have provided the exact code but thats where you should be heading if you wish to run your JUnit tests from command line.
NOTE / FYI : Maven does not require any installation or approval..You just download the zip and unzip it and set environment variable and thats it.
I ran it in cmd and it said no main manifest attribute in, JGame2.jar
how do i show it where the main is?? it works fine in eclipse.
For
java -jar x.jar
to work, the jar file must contain a META-INF/MANIFEST.MF file, and this file must contain an entry for the main class. You can add a manifest in Eclipse. Note that any dependencies must also be accounted for, either by:
a class path in the manifest
-cp on the command line
use of some tool to combine to one jar
Eclipse is just an IDE, you might consider learning to use an actual build tool such as Maven or Gradle or Ant to allow you to repeatably build usable results.
I am designing a tool, that takes an sbt project path as a parameter. I would like to be able to build that given project on the fly, and be able to get its classpath.
I previously designed my tool as a sbt plugin to achieve this but it is not flexible enough for my purpose: I don't want to have to parameter anything in the sbt config files of the project I am studying.
I would like to use sbt externally, construct a project (from a sbt directory path) and compile it externally in my scala code without invoking sbt in a console. This is a reproduction in code of what happens when "sbt" is typed in a given directory in the console. Is there a straightforward way to achieve this?
I think you need to look at SBT jar file and source code. Find the "Main" class and call it programmatically. The code is here: https://github.com/sbt/sbt. The main class is: xsbt.boot.Boot. I got it from sbt jar file by unzipping it and looking at META-INF/MANIFEST.MF. So you can see how SBT passes command line arguments to it and take it from there. Here is the Boot class just in case: https://github.com/sbt/sbt/blob/0.13/launch/src/main/scala/xsbt/boot/Boot.scala. Have fun! :)
p.s. in your code just call Boot.main(<your sbt commands>).
I have a vaguely similar requirement. I produce a command-line tool as one of the deliverables from my project. The script launches the Scala runtime itself and naturally needs the effective class-path for the project's dependencies. To get that in an external form, I use the SBT-Start-Script plug-in. While that plug-in does produce an actual launcher, I need to do more than it provides, so I just use it to externalize the project's (current) class-path, which I extract into a shell array initialization in a separate source file that may be source-ed by the main launcher script.
I'm trying to package a small application (still learning Scala!) in a "clean way". The goal is to have an executable JAR file. I've done the following:
packaged a JAR using sbt -> will work with
scala -cp myjarfile.jar MyClass
or
java -classpath path\to\scala-library.jar;myjarfile.jar MyClass
but won't work with
java -jar myjarfile.jar
because then scala/ScalaObject cannot be found. And no use adding a classpath on this last one, since the -jar option will ignore the -classpath option. Note that I have added the scala libs in my system CLASSPATH variable, but it seems to be ignored too when -jar is used.
added the scala library contents (by unzipping them first) to the jar created by sbt. This then works (the jar can be double-clicked and launched), but the manipulation is somewhat lengthy, and the resulting file is several megabytes big. Not ideal.
After hours of googling, I can see no way to create a small jar file that will launch when double-clicked and that doesn't involve a painful manipulation. What am I missing? I'm guessing there should be some way to define where the scala libraries are at system level. How do you deal with small applications that you want to be compiled and ready-to-run for efficiency?
Note that while I'm using sbt, I don't have a jar tool at hand (I'm relying on a JRE, not a JDK).
Thanks!
Pierric.
The following setup works for me:
have scala-library.jar in the same folder as the executable jar (and call java from there)
put this into your manifest:
Class-Path: scala-library.jar
Another option is to merge the contents of scala-library.jar into your application jar. The drawback is that this will increase its size. But you can use Proguard to strip unused classes from your final jar. I think there is an easy way of using sbt to package an executable jar using proguard.
Regarding the shrinking using Proguard, you can have a look at this page. It's about Android development; just ignore this part and have a look at the tables of the shrinking results. Some example applications shrink to less than 100kB.
Edit
Maybe you need to refine your question a bit. What are you trying to achieve? Do you want to install the program only on your system or do you want to distribute it?
If all you want is quickly launching a Java application without much impact of the JVM start-up time you can have a look at nailgun.