I am new to eclipse + Java. I am trying to create executable jar file with eclipse
export option. It works very well. But in my project, I have almost 10 packages (my own) and 4 main classes. I want to create a executable jar file that can execute any of main class from 4 main classes.
For example: Double click write class name and run that class
Dont use executable jar. Instead create a normal jar which will have compiled classes.
From command line, call whichever main class you want to call as a argument to the java jar command.
java -jar test.jar com.company.unit.MainClass1
java -jar test.jar com.company.unit.MainClass2
Executable JARs don't work that way. They write a manifest file in the JAR that declares where the main class is, and it runs that one. You would have to create 4 different JARs.
Alternatively, you can just create one main class that lets you type in which of the four you want, and then have it execute that one. Basically, you'd be mimicking the functionality that you are looking for on your own.
Just a quick example of how to deal with command line options to launch different things, I would have put it into a reply to #serplat's answer but then I can't format it.
public static void main(String[] args)
{
if(args.length == 0) {
// Do default here--no options specified
} else if(args.length > 2) {
// Complain that there are too many args, or implement multi-args
} else // known just one arg
if(args[1].equals("option1") {
// call the main of your first app
} else if(args[1].equals("option2") {
// start your second app
...
}
}
There are much better ways to handle command line stuff, but this is understandable and should do what you need. Later you might look into something more flexible.
I have recently made a tutorial that shows you how to create an executable jar file that will run with a double click in Windows, Mac OSX and Linux. For my project, I packaged a slick library game I had made. Hope it helps.
http://aramk.com/blog/2010/12/05/how-to-make-a-multi-platform-executable-java-jar-file/
Related
Below is my sample class file:
package org.foo.tutorial;
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
In order to execute the project (maven framework) we run:
>java -cp Something-1.0.SNAPSHOT.jar org.foo.tutorial.APP
The above command works fine and gives me the output 'HELLO WORLD'.
However, if I leave out the third argument in the above command (org.foo.tutorial.APP) I get the following error:
Error: Could not find or load main class target.MavenTutorialApp-1.0-SNAPSHOT.jar
My question is:
Why should the groupId and app name matter when I am supplying the entire 'jar' file ?
The error is a bit misleading. Your java command is incorrect since you don't specify a class. The Something-1.0.SNAPSHOT.jar is meant to be part of the -cp option but java is interpreting it as the class.
That's how java behaves
The java command starts a Java application. It does this by starting a
Java runtime environment, loading a specified class, and calling that
class's main method.
If your .jar file contains an entry point specified by a Main-Class header in the manifest, then you can simply run
java -jar Something-1.0.SNAPSHOT.jar
Let me try to answer your question.
Why should the groupId and app name matter when I am supplying the
entire 'jar' file ?
Lets divide the question into smaller part -
What is group id? - The id of the project's group.
What is artifactId? - The id of the artifact (project) and off course version is part of default artifact name.
While running a java program under jvm there are no such effect that how you built jar, for example it is produced by maven or gradle build process or even command line.
Things that matter is jar file and entry point or the class where main reside.
This may be out of scope of this question, but i felt relevant.
To run java program from jar file, you can explicitly mention like above. Also you can create executable jar file by adding manifest file, where it define the entry point of the executable -
Main-Class: org.foo.tutorial.APP
How to create executable jar?
Also maven maven-assembly-plugin helps to package executable jar.
help
we have a big project with many classes (~100) and in some there are main methods.
Building a runnable .jar-File to be executed under a WinXP environment fails; we have the idea that maybe it is because there is not only one but many main-methods in our project?!
So I read some about it and as fas as I got it, a .jar can contain more than 1 main-method; they would be called like this:
java -classpath myJarFile.jar A
java -classpath myJarFile.jar B
java -classpath myJarFile.jar C
where A,B and C have their own main methods (see http://www.coderanch.com/t/373658/java/java/Executing-main-methods-jar-file)
My question is: Does having more than one main method affect the problem-free running on Windows ?
Thanks in advance!
You've said you're making a runnable jar file, but your examples (java -classpath myJarFile.jar A) aren't using it as a runnable jar; they're just using it as a jar. You're specifying what class to run on the java command-line. That should work just fine.
Re runnable jars: The point of runnable jars is that you don't have to start them with the java command directly; you just double-click the jar in a file explorer, make it the target of a shortcut, etc., and the java tool is run automatically (via file association), using the jar's startup class, which is specified in the manifest you used when creating the runnable jar:
Manifest-Version: 1.0
Main-Class: Startup
In that example, Startup is the startup class for the runnable jar.
You could make the jar a runnable jar (e.g., pick a default class to run the main from and make it the startup) and still allow the jar to be run via the java tool choosing another class. That's fine.
No - the main method is just the entry point for the program.
For executing the application Main method is just like door for entire application. But you can add some other class as well which is have there individual main methods but entry main method should all ways be one.
No, it's not a problem if you are able to control the invocation of your program (as opposed to this being a dropin/plugin, for example).
Does having more than one main method affect the problem-free running on Windows ?
It will if you try to do java -jar myJarFile.jar. The jar manifest allows you to optionally specify no more than one main class.
If you want have multiple main methods you need to use following syntax only
java -classpath myJarFile.jar A
I have written two simple Java classes (one of them containing "main()", and the other called by "main()").
Class #1 (containing "main()"):
package daniel347x.outerjar;
import daniel347x.innerjar.Funky;
public class App
{
public static void main( String[] args )
{
Funky.foo();
}
}
Class #2 (called by "main()"):
package daniel347x.innerjar;
public class Funky
{
public static void foo()
{
System.out.println( "Funky!" );
}
}
The above classes appear in different project root folders, and use Maven as the build system (each project has its own POM). The pom.xml file for the main project includes the proper entry to add daniel347x.outerjar.App as the main class, and it properly includes the dependency on daniel347x.innerjar. Both projects build successfully into JAR files.
I use NetBeans to wrap these as Maven projects (in fact, I used NetBeans to create both projects). When I run the main project from within NetBeans, it runs successfully and I see Funky! as the output.
However, when I attempt to run the main class straight from the Windows command line (cmd.exe), passing the JAR file containing Funky on the command line's classpath, as such:
java -classpath "P:\_Dan\work\JavaProjects\JarFuckup\innerjar\target\innerjar-1.0-SNAPSHOT.jar" -jar "P:\_Dan\work\JavaProjects\JarFuckup\outerjar\target\outerjar-1.0-SNAPSHOT.jar"
... I receive the dreaded NoClassDefFoundError:
Exception in thread "main" java.lang.NoClassDefFoundError: daniel347x/innerjar/Funky
at daniel347x.outerjar.App.main(App.java:7)
I have carefully confirmed that, inside the innerjar JAR file noted above containing Funky, that the path structure is daniel347x\innerjar and that inside the innerjar folder is the Funky.class file - and this file looks correct within a HEX editor where I can see the ASCII strings representing the name of the class.
The fact that the class can't be found defies my understanding of Java, which I thought allows you to pass JAR files as a -classpath parameter and it will be able to find classes inside those JAR files.
This very basic point has me flummoxed - an answer that explains what I am doing wrong would be greatly appreciated.
The classpath is ignored when using the -jar option. A way to run your app would be java -classpath "P:\_Dan\work\JavaProjects\JarFuckup\innerjar\target\innerjar-1.0-SNAPSHOT.jar";"P:\_Dan\work\JavaProjects\JarFuckup\outerjar\target\outerjar-1.0-SNAPSHOT.jar" daniel347x.outerjar.App
Perhaps a better approach would be to add a manifest file to the Jar that specifies the class path of the dependent Jars by relative paths. Then..
java -jar "P:\_Dan\...\outerjar-1.0-SNAPSHOT.jar"
..should do it.
Double clicking the main Jar will also launch it. That is mostly useful for GUIs.
How can I create the class file and jar file for this coding, when I compile this program its not working because there is no main function in the program. And also I am trying in command prompt but I don't know how to set the classpath? please help me
My Coding is here
public class NewLogFields implements ILogNotify
{
public void onLog(Level level, String comment, IMediaStream stream, String category,String event, int status, String context) {
if (category.equals(WMSLoggerIDs.CAT_session) && event.equals(WMSLoggerIDs.EVT_destroy))
{
Long csBytes = (Long)WMSLoggerFactory.getGlobalLogValue(WMSLogger IDs.FD_cs_bytes);
Long scBytes = (Long)WMSLoggerFactory.getGlobalLogValue(WMSLogger IDs.FD_sc_bytes);
System.out.println("disconnect: csBytes:"+csBytes+" scBytes:"+scBytes);
}
}
}
Once you compiled the coding in wowza media Serever the jar file is automatically created in the library folder,see your Installation Library folder.Still you have problem Gothrough this link Wowza Quick Guide
What do you want to do?
Create a class and an jar file out of this Java code so that you can use this in another Java program?
Then you have to compile it:
java NewLogFields.java
Looks like you are unable to compile it at all. This could be because the interface ILogNotify (or the jar that contains this) is not in the classpath.
You can include the path/jar containing this interface in the classpath by using:
javac -cp .;path_to_jar_or_class NewLogFields.java
where path_to_jar_or_class is the path to the folder or jar file that contains ILogNotify.
For example, this may be something like ./logNotify.jar or ./log/
You can set use switch -cp or -classpath with javac command.
for example javac -cp path and name of jat file or class file yourjavafile.java
create the class file using the compiler: javac NewLogFileds.java
create the jar file using the jar command: jar cvf stuff.jar NewLogFileds.class
You are correct that the program needs a main() function in order to run.
add:
public static void main(String args[]) {
// code here
}
With that you could run the code with or without the jar:
java NewLogFields
or
java -cp stuff.jar NewLogFields
There are ways of creating a MANIFEST file that tells java which class to run from the jar making the last line more simple.
The link that you provided tells you how to do it:
Compile your class in the normal way.
Create a JAR file containing your class in the normal way.
Copy the JAR file into the wonza installation's lib as described in the javadoc.
Edit the startup script to add the -Dcom.wowza.wms.logging.LogNotify=... option to JAVA_OPTS ... as described in the javadoc.
The "full-path-to-your-ILogNotify-class" is actually supposed to be the fully qualified class name of your class; it is obvious from the examples.
Edit WowzaMediaServerPro-Service.conf and log4j.properties as described in the javadoc.
Restart the server.
If you put your JAR file in the directory like the instructions tell you to, you won't need to modify the classpath by changing -cp argument.
Your class doesn't need a main method because it is not a free-standing application. Rather, it is a "plugin" class that gets dynamically loaded and instantiated by the Wowza core as required. The "-D..." option and the config file change tell the Wonza core which class to try to load.
I'm am creating a VoIP client server pair in java using the netbeans IDE. I would like to use only 1 project but I am unfamiliar with with how netbeans would create the Jar file. I need a to if this is possible and if so, how to set it up.
The JAR File Specification allows only one Main-Class attribute per JAR, but the JAR may have an arbitrary number of classes that declare a main() method. Any such class will be included in the project's Build Packaging property, unless specifically excluded.
As a concrete example, H2 Database includes these classes with main():
org.h2.jdbcx.JdbcConnectionPool
org.h2.tools.Backup
org.h2.tools.ChangeFileEncryption
org.h2.tools.Console
org.h2.tools.ConvertTraceFile
org.h2.tools.ConvertTraceFile
org.h2.tools.CreateCluster
org.h2.tools.DeleteDbFiles
org.h2.tools.Recover
org.h2.tools.Restore
org.h2.tools.RunScript
org.h2.tools.Script
org.h2.tools.Server
org.h2.tools.Shell
Addendum: Apparently, my junk-drawer project needs maintenance.
$ find scratch/src -name \*java | xargs -J % egrep 'main[ \t]*\(Str' % | wc -l
109
I don't know how Netbeans work, but it should be no problem putting more than one main class in a JAR. Actually a main class is just a class having a main method and a JAR is a collection of class files.
The only restriction is that there can only be one class that will be started with double-clicking the JAR.
To start the each class you must not use the -jar option, but provide the full class name.
For example, if you have a Client and a Server class in your JAR, the Client is started by
java -cp file.jar Client
and the Server by
java -cp file.jar Server.
An option is to create a third starter class used to start either the server or the client based on a command line argument (or a GUI window).
I believe the purpose of a 'main class' means that the eventual JAR' manifest file, will label one class as being the 'class to run': so that the end-user can just double-click it* or run a simplified commandline like:
java -jar <jar>
rather than having to specify the whole package/class name like:
java -cp <jar> com.yourcom.package.classname
If I'm right, then I don't see how it would make sense to have more than one main class ?
Maybe I misunderstod your question - or there is another purpose to the 'main' class?
If you mean having two classes which have a 'main' method - then this is fine - the end user can launch any of the classes by name - and so long as they have the standard main method sig, for instance:
public static void main(String[] args)
it should just work.
*(on Windows at least, and whether that works also depends on which JRE they have and probably other things)
In netbeans, if you want to create jar file of your project with your selected main class then ,
1. right click on your project (If you couldn't find your project then go to window -> Project from netbeans menubar )
2. Go to set configuration -> Customize.
3. Select run from categories, In main class write your packagename.classname (ie you have created file xyz in mypackage, then write mypackage.xyz)
4. click ok.
5. Again right click on projectname, select clean and build.
6. Your jar file is created at location of your projectname -> dist -> projectname.jar