Where do you use Java code? Trouble sending .jar files [closed] - java

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Apologies for the generic nature of this question.
I have been learning Java for a few months now, and I've created a few simple projects which have some functionality. I wanted to send the projects to a friend and I'm running into countless errors and struggles. Passing a .jar file is causing "Main class not found" errors when they try to open it.
I tried using third party software to wrap the .jar files into an .exe file and the same errors still persist.
Beyond that, I'm convinced that passing around .jar files wrapped into .exe files via third party software is NOT how Java was intended to be used. I've read two books on Java and they all talk about structuring the language, but I'm confused about WHERE I'm supposed to be using this code because it has become painfully obvious that it is NOT intended to be passed around in file format.
Is this a server programming language? Used on the back end of websites mainly? I'm not sure where one would be using the code written in Java.

You should build an executable jar.
Check here and here.

You need to create your JAR file as an executable JAR file if you want someone to be able to run it. That is how you send around Java executables. Look here for more info:
How do I create executable Java program?

I'd recommend you spend some time with http://docs.oracle.com/javase/tutorial/. Java program basically runs on top of virtual machine (not directly on your physical machine). Java program is compiled into *.class files, and a collection of *.class is commonly bundled into a *.jar file.
If you want to run your java program, one common way is to execute the java virtual machine runtime (JRE) and specify your jar package to be loaded into the classpath, eg:
java -jar /path/to/my.jar
Your jar file has to be packaged properly such that it indicates what is the main class (if any)
Packaging jar into exe is possible, but is not best practice. Java paradigm is a write & compile once -- runs everywhere.

from Oracle:
If you have an application bundled in a JAR file, you need some way to indicate which class within the JAR file is your application's entry point. You provide this information with the Main-Class header in the manifest, which has the general form:
Main-Class: classname
The value classname is the name of the class that is your application's entry point.
Recall that the entry point is a class having a method with signature public static void main(String[] args).
After you have set the Main-Class header in the manifest, you then run the JAR file using the following form of the java command:
java -jar JAR-name
The main method of the class specified in the Main-Class header is executed.
Setting an Entry Point with the JAR Tool:
The 'e' flag (for 'entrypoint'), introduced in JDK 6, creates or overrides the manifest's Main-Class attribute. It can be used while creating or updating a jar file. Use it to specify the application entry point without editing or creating the manifest file.
For example, this command creates app.jar where the Main-Class attribute value in the manifest is set to MyApp:
jar cfe app.jar MyApp MyApp.class
You can directly invoke this application by running the following command:
java -jar app.jar
If the entrypoint class name is in a package it may use a '.' (dot) character as the delimiter. For example, if Main.class is in a package called foo the entry point can be specified in the following ways:
jar cfe Main.jar foo.Main foo/Main.class
Setting an Application's Entry Point

For a quick answer, libraries are bundled in jars, which are then added to the classpath of another application.
Pretend you invent a new sort algorithm which is faster than all the others. You could bundle up a small number of classes into a jar, which is basically just a zip file containing your compiled .class files.
Now your friend needs to sort some data and wants to use your classes. He would write his code to import your classes (using import at the top of his .java files), and then work with them in his code. When it came time for him to compile his .java files into .class files, he would add your jar to his classpath. Eclipse/netbeans can set this up for you, or if you're running javac from the command line it would look something like this:
javac ... -cp "fastsorting.jar" ...
Sometimes (rarely, in the real world) someone has a JAR which is really a fully fledged program, meant to be run. I say rarely, because jars aren't the most common way to distribute software. More popular is as a web service or through an applet on a website. In this case, a jar's manifest file (just a text file telling java information about this jar) will have a main class, which is run when the the jar is invoked through java.

Related

How do I set a classpath for multiple jar files? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I don't want to make the code messy Is there a way to set a classpath to exexute my java program, because my jar files are from different directories they are like 30 jar files
Various strategies are available.
runnable jars
A 'runnable jar' can be run with java -jar thejar.jar, and depending on your OS and how you installed java on it, just doubleclicking the jar in the user interface works too (and does the same thing as java -jar thejar.jar.
This 'maps' to java -cp someclasspath myapp.pkg.Main as follows:
The thejar.jar is scanned for the file META-INF/MANIFEST.MF. This is a text file containing key/value pairs separated by a colon.
java.exe looks for an entry named Main-Class and takes the value of that as myapp.pkg.Main. It then looks for an entry named Class-Path and parses the value for that to use as classpath. This classpath string is space-separated, and all paths are relative to the same path the jar you run is in.
Thus, if you have, say:
/usr/local/myapp/myapp.jar
/usr/local/myapp/deps/guava.jar
/usr/local/myapp/deps/jooq.jar
and the myapp.jar file contains the class file /my/app/Main.class, then this needs to be in the manifest:
Main-Class: my.app.Main
Class-Path: deps/guava.jar deps/jooq.jar
and then you can just java -jar myapp.jar, from anywhere (you don't need to be in the /usr/local/myapp directory. Note that -jar automatically uses this mechanism for the classpath. $CLASSPATH and the -cp option are completely ignored.
So, how do you get that file in there? Well, build systems tend to have ways to let them automatically build up the list of 30-some jar files, but your question doesn't explain how your build works, so you'd have to peruse the documentation of maven or gradle or whatnot. Alternatively, script it together with some bashisms if you've handrolled your build (not recommended).
The * include
Another option is to use the * include option. java.exe itself can pick up every jar file in a given directory (not recursively, though - it won't pick up jars in subdirectories). The problem is, on every OS except windows, it is the job of the shell to unpack * into a list of files, so your shell will do that. Which you don't want it to do, because it unpacks using spaces, and the -cp command line option doesn't work that way. Thus, on ALL OSes except windows, you must put the classpath in single quotes in order to suppress the shell's feature that it will detect that * and unpack it.
Thus, with the same setup as above, you can also run:
java -cp 'myapp.jar:deps/*' my.app.Main
and that also works, though you'd have to [A] be running some posix based OS and [B] have to be in the /usr/local/myapp directory. On windows, I think java -cp myapp.jar;deps/* my.app.Main will work.
Note that it has to be just *. Not *.jar.
Use your build tooling
Most build tooling has a 'run' command that includes the proper (runtime) dependencies automatically. This includes IDEs.
Shading
Also called 'fatjars' or 'uberjars' or 'striped jars', this is the notion of taking all class files in all the jars needed at runtime and packing them into one gigantic jar file.
This is a dumb idea for many reasons:
It's slow as molasses; your average serious project has hundreds of dependencies, so that one gigantic jar is half a GB in size. Just writing that out to disk takes time, let alone transferring it around to your deployment and test servers. You want the time and effort it takes to make a change in your code and see your test results to be as low as it reasonable, and the fatjar concept fundamentally clashes with this notion.
signed jars do not work well with this model.
It makes updating deps harder.
You could in theory consider the notion of 'I make a single fat jar and now I can just zip that up and mail it around to folks', and thus conclude that fat jars are nice, but this is no good either:
gmail and other services will flat out strip that jar right out of your email because it's generally used to convey malicious code. Mailing jars around isn't a good deployment model
The current only official supported style of distributing java apps is NOT by just shipping jar files around; there are no JREs anymore (JRE8 was the last official release. Some third parties still make them. Doesn't make it any more officially supported though). You're supposed to ship an installer which takes care of setting up a treeshaken JRE and keeping it up to date. Various tools make this possible such as jmod and jlink. These aren't used much, but that's probably mostly because the vast majority of java apps run on servers and aren't themselves client apps meant to run directly on end user hardware. See for example minecraft or eclipse: Java-written desktop apps. Neither 'ships as a jar file' and certainly not as fat jars.
"Just shade it / make a fatjar" is extremely common advice. You are now armed with sufficiently knowledge to know it is bad advice.

Exporting a runnable jar, opening it returns an UnsatisfiedLinkError

I currently wrote a simple GUI in Eclipse which runs as intended. I was hoping to export it so I can share it with my friend (who doesn't need to install eclipse and the java libraries). I tried all 3 library handling method Eclipse provides and none of them works. I read a little online and saw something about a manifest file, but wasn't quite sure what to do with it. Is it going to help?
This is where I placed the folder that comes with the .dll file.
This is the result. Am I doing something wrong?
As indicated by the error messages in the first screenshot, what you are missing here is the native library - the software library written and compiled to native code specific to the operating system. What you will need to do is provide the libraries specific to the operating system on which your software will run, eg. dlls for 32 or 64 bit Windows. The manifest does not provide the capability to include those libraries.
When the program is run on Windows, Java will look for native libraries in the following locations:
The current directory
The directories in the PATH environment variable
The directories in java.library.path (if it's specified)
It may be easiest to simply put all files in the one directory. If you do this, you should be able to run the program in the same way as you do now.
The java.library.path option is only needed if you want to put your native library files in a directory separate to the one in which you run your program and not on your PATH. It is only in this case that you will need to add java.library.path, eg. by adding -Djava.library.path=c:\path\to\your\lib after java. Also note that you may use a relative path, ie. a path that is relative to the directory you are in when you execute the command.
I also see from your later error messages that you have another dependency, but on a java library LeapJava.jar. As running a jar with -jar will only work if you have a single jar, but because you have more than one (your own program plus the dependency), you'll instead need to use the -classpath (or -cp for short) argument and add your main class. The classpath argument is a semicolon-separated list of classpath locations, while the main class is the one containing your public static void main method, eg. your.package.name.YourMainClass. So assuming your UI.jar is still in C:\Users\Ian\Desktop\Leap Data UI, you should be able to navigate to that directory and execute with:
java -cp UI.jar;UI_lib\LeapJava.jar -Djava.library.path="UI_lib\x64" your.package.name.YourMainClass

How to create Windows executable from JAR

I have a simple Java program (lets call it MyProgram.java) that does some I/O, re-names some images, deletes a directory, etc. I've been browsing around S/O looking for a simple way to run a Java program's main method from command prompt. I've compiled the source code into a jar, and tried using Jar2EXE Wizard, however I kept getting an unexpected compilation error that I wasn't getting while running my code from the IDE.
Does any one have either a Jar -> EXE converter solution they've had success with or can walk me through how to run my program from a batch file?
[..]or can walk me through how to run my program from a batch file?
The simplest way is to execute:
java -jar YOUR_JAR_FILE.jar
in your batch file. However this requires a manifest file to be present in your jar file which specifies the Main class to use and jar files it depends on. If you do not want to work with a manifest file you can specify these things manually. If you do not depend on external jar files you can execute:
java -cp YOUR_JAR_FILE.jar some.package.Main
This will execute the public static main(String[] args) method in class some.package.Main contained in YOUR_JAR_FILE.jar.
If there are other jar files you depend on (in your case that would be IOUtils/FileUtils), specify those jar files as well:
java -cp YOUR_JAR_FILE.jar:library1.jar:library2.jar some.package.Main
(in your case library1 and library2 are IOUtils and FileUtils respectively).
You can specify any number of jar files and you can also use the wildcard *.jar to include all files in the current (or another) directory. Note however that you cannot write * or x*.jar or the like. Only *.jar (or some/directory/*.jar) is accepted.
In 90% of the times, the order of the jar files does not make any difference. However sometimes it does make a difference: If a resource is loaded from the classpath (could be a class or something as simple as a configuration file), the jar files are searched in the order you specified. If a resource exists in multiple jar files, only the first one found will be used.
You can consider using install4j.
If you want use batch file you can write this:
java -jar sources.jar
If your code have more than 2 static void main(String[] args) you need explicitly hit the method:
java -jar sources.jar classes.package.Main
Directory structure:
-\project\
-\project\run.bat
-\project\sources.jar
Take a look at JSmooth. It wraps your JARs as executables and provides options for detecting, and handling lack of, the JVM. I've used it on a simple app and it was painless.
Bonus: it is available as a portable app with no installation needed.

Running java from a bat file in such a way that path doesn't need to be specified

I think I have seen this done, but am not sure where. What I want to do is to create a bat file I can package with my class files when sending to a friend to show them progress/ask advice on non programming matters. My friend is not very handy when it comes to code and doesn't like changing computer settings. Just using java myClass as a command line won't work here because although my friend does have java installed, he has not set his windows environment variables so his command prompt knows where to find java.
What kind of line would I need to add to my batch file to make it so it can compensate for problems like this?
Create a manifest file (manifest.txt):
Main-Class: com.mycompany.myapp.MyMainClass
Package your app as a jar:
jar cfm myjarfile.jar manifest.txt *.class
Create a batch file:
start myjarfile.jar
If it is about sharing and running a single java file without jar dependencies. And you are only worried about the java runtime environment setup, then you can use online java code compilers and executors. Here is one:
http://javalaunch.com/JavaLaunch.jsp
You can google for more!
Use an IDE, NetBeans or eclipse and package your files as a Jar file.. that can be executed directly and you do not need to worry about dependencies, other classes or libraries.

Is it allowed to repackage Oracles JDBC driver? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I would like to distribute my Java program as a JAR file. My program requires the Oracle JDBC driver, which is also delivered as an JAR file. But the java -jar command accepts only one JAR file. Therefore I have to merge the two JAR files. This can be done quite easily but am I allowed to do that? Am I allowed to distribute my program as a JAR file containing the contents of the Oracle JDBC JAR file?
But the java -jar command accepts only one JAR file.
That's not correct. Your JAR file can contain a Manifest with a Class-Path: entry which can name the Oracle .jar file.
Yes you can package Oracle JDBC drivers into your jar file, as long as you are not modifying the jar file or any of the file there in. In some of the libraries it is required to include the license files also as part of your distribution - you need to read the license details of the respective jar files. Generic Oracle distribution license terms can be found here http://www.oracle.com/technetwork/licenses/distribution-license-152002.html
Regarding the java -jar part of your question please refer following explanation:
To launch the executable jar file we use the command java -jar executable.jar
JVM would look into the manifest of jar file and execute the main method of main class - that you specify in jar file. Any dependency of the application can be satisfied by classpath settings - we dont need to specify all the dependency jar files while launching the application.
There are different ways of classpath settings:
Set the system classpath (on Windows set CLASSPATH=app1.jar;app2.jar;driver.jar; and on Unix/Linux export CLASSPATH=app1.jar:app2.jar:app3.jar ). This method is useful when you have control over system variables and it is controlled environment, this method is not preferred for distributing applications to client
Mention the classpath while launching the application. This can be done by using -classpath option of java comman - for example java -classpath app1.jar;app2.jar;driver.jar -jar executable.jar this method is useful for quick testing and if the number of jar files to be referred are less
Specifying the mainfest classpath. This is the best option for packaged application. We can specify the dependencies in the manifest classpath, like this Class-Path: app1.jar app2.jar driver.jar
Note: please use proper delimiters in classpath entries, for example on windows ; is the delimiter for classpath entry, on unix : is the delimiter and in manifest class path you have use space as delimiter. Also where ever app1.jar/app2.jar/driver.jar is mentioned you have to use absolute or relative path of jar files

Categories