I am trying to use a number of external libraries in a Java project. The project runs fine from Intelij but I want to package it in a jar, (or something else) so I can distribute it to others. When I package it in a jar it works if I just do hello world, but as soon as I start using my libraries I get the error bellow. I have also tried packaging it as an application but when I run the batch file it just opens and then immediatly closes a command window. I read all the other posts and nothing is fixing my problem. Please help
My error
My build.gradle
The problem is most likely that your classpath does not point to the correct relative location of your 3rd party libraries. You can check the manifest file to verify if the paths are correct.
However, if it is a runnable jar file with a main method (which it looks like it is), you should use the Application plugin and package it with the Distribution plugin. Right now you are using the Java Library Distribution plugin, which is for libraries. If you do this, you can remove most of the stuff under your jar task.
When testing it locally, run gradle run and when ready, use gradle distZip to create a zip of it all. It will create a script used to start the application with the correct classpath.
Alternatively, you could also package it in a fat jar using the Shadow plugin or similar.
Related
I have created a JavaFX application and have a generated Jar file (generated with Gradle) that will launch.
When the application does launch, it doesn't connect to the embedded database though. I feel as though I am missing something very simple but after a lot of research, I haven't been able to figure it out. When running the jar file from the command prompt, I get the following error:
java.lang.ClassNotFoundException: org.apache.derby.jdbc.EmbeddedDriver
From the reading I have done, I understand I may be able to add this to my classpath but I have not been successful with this after multiple attempts and I have made this application to be run on another computer. This is possible, right?
If possilbe, I would love to change something in my build.gradle file or surround the .jar in a folder or something like that that would make this simple for the person running the program. Program size is not a concern short of multiple gigabytes.
You've got two problems
The driver class is not in your app jar
If you embed that db into the app jar, you're not going to be able to write to it
You can make a 'fat jar' but the isn't going to solved the second problem. You really need to make an installer to do this, in order to leave the db in the file system, so it can be written to.
Problem
Part of what Gradle does is dependency management. That means it knows what dependencies you need and how to find them (based on configurations in the build script). When you execute/build your application via Gradle the tool will automatically search repositories, download+cache dependencies, and place those dependencies on the class-path/module-path. Once you deploy your JAR file Gradle is no longer involved, so your deployment is responsible for including the needed dependencies.
In other words, you need to ship your application's dependencies with your application JAR file.
Solutions
You basically just need to make sure you include your application's dependencies with your application. Here are at least three ways to do that.
Copy Dependencies
Copy the dependencies into a build folder as part of the build process. Here's an example of such a task, using the Kotlin DSL:
tasks {
val jar by existing(Jar::class)
val copyDependencies by registering(Copy::class) {
from(configurations.runtimeClasspath)
into(jar.get().destinationDirectory)
}
jar.configure {
finalizedBy(copyDependencies)
}
}
Now if you execute ./gradlew jar Gradle will create the JAR file and then copy the dependencies into the same directory as the JAR file. Then you just need to make sure all the JAR files are deployed together.
If I remember correctly, the default class-path is the working directory. But to specify the class-path you would use -cp, -classpath, or --class-path when executing your application. The module-path, if needed, is set with -p or --module-path.
Fat JAR
Create a so-called "fat" or "uber" JAR file. That's a JAR file that includes not just your own application code but all your application's dependencies as well. You could configure the jar task for this, but it would probably be easier for you to simply apply the Gradle Shadow Plugin.
// Kotlin DSL
plugins {
id("com.github.johnrengelman.shadow") version "<version>"
// other plugins...
}
And then you'd create the fat JAR with ./gradlew shadowJar. See the user guide for more information.
Self-Contained Application
Create a self-contained executable using a tool like jpackage. This tool gives you an application that has all its code and the JRE embedded, and then gives you an installer or native executable (e.g. exe on Windows). Here's the user guide for jpackage. There are Gradle plugins to make using jpackage from Gradle easier, such as The Badass JLink Plugin.
Note jpackage was added in Java 14 and was incubating until Java 16. Also note that jpackage can't "cross-package". That is to say, if you build your application on Windows then you can only create installers/executables for Windows; same for MacOS and Linux. If you need to package for multiple platforms then you'll need access to each platform.
JavaFX
Since you've tagged this question with JavaFX I want to give a note of caution. Though if you're not using JavaFX 9+ then this is not relevant to you.
Technically JavaFX only supports being loaded as named modules. That means it needs to be placed on the module-path, either via --module-path or by including it in the custom-runtime image built by jlink / jpackage. As of JavaFX 16 a warning is now emitted if JavaFX is loaded from unnamed modules (i.e. the class-path).
Executable JAR files are placed on the class-path. That includes fat JARs. And if you are not using a JDK that includes JavaFX—meaning you have Gradle pull in the JavaFX dependencies—then JavaFX will be included in your fat JAR and be placed on the class-path. Now, despite not being supported and now emitting a warning, nothing seems to currently break if JavaFX is on the class-path. Except for one caveat: Your main class must not be a subclass of javafx.application.Application. You'd have to create a separate main class that simply launches JavaFX.
Because of all this, I would highly recommend using jpackage to deploy JavaFX applications. You may want to read this Q&A as well.
I'm using gradle for my build tool. I have a project that uses a jar file and I have the jar file imported into my gradle for my project which works great when doing build and deploy.
Problem is that I'm developing the jar file along with the project. When I change the library code, I have to build and move the jar file into my project. PITA.
Instead, I'd like to set up my IntelliJ environment so it uses the module's code first and then looks at the jar file later/never.
It seems like something that IntelliJ should be set up to do, but searching turned up nothing and I can't seem to find anything banging around in the IDE.
Anyone tackle this?
Currently such setup is not supported for Gradle project. There is however a hidden option that you may try to set:
external.system.substitute.library.dependencies = true
via "Help | Edit Custom Properties" and restart.
The corresponding request for this is https://youtrack.jetbrains.com/issue/IDEA-134885
I am using IntelliJ IDEA to develop a Java project. To include the mysql-connector-java library I use, I created a folder named lib in the root of the project and added the JAR to it. After that I added it as a global library using the context menu.
When debugging it, everything is working fine. But when I navigate to the production directory and try to run it from the command line it cannot find the library. How can I include it in the production directory to allow accessing it when running my main class? Or is there another way to get this done? I just want to make sure, that all external libraries my project is depending on are properly included.
in the command line you should use -cp to add jars or directories to classpath (as explaind here ). if you want to run with intellij Idea then you create a run configuration (which I thing you've already done) and then in the configuration select you module in option use class path of module part of the configuration.
You have to add the library/jar to your BuildPath.
Just take a look at the "Correct way to add a library to an IntelliJ project"
I have a java application I've written in eclipse. It works fine there.
It works fine run from a command line in the directory where I export it to. In that directory is another directory containing two jar files that I need for the application, and the manifest file has a Class-path option specifying them.
I want a way to use eclipse to generate the necessary file(s) to package this application to run on another machine. Is that possible?
If I choose "create executable jar file", it creates this huge file; it does unpack and repack the two libraries, which I know is one way to get their functionality included. I would actually prefer it if they were left as their own jars somehow, but I am not certain eclipse can do that. More annoying is the fact that the executable jar file option puts lots of files from my eclipse project into that jar file. I don't see an option to choose what gets included there, though I do see a place to enter inclusion and exclusion "rules' in the project properties. Do those apply here? Is there somewhere else I go to select what does and does not get included in the "executable jar"?
If I choose "create jar" (ins of "create executable jar"), I don't see where there's an option to include these two jar files anywhere. Perhaps there is no place to include them where they could be used.
If possible, I do not want to use Ant, I do not want to use Maven, I do not want to download another tool. It seems to me that Eclipse already has all this information and I suspect it can already do this without having to go and learn yet another "nifty" tool.
Eclipse has its own Jar export wizard for generate a runnable jar packed with required library or with the required library in a folder aside the jar.
Going in File ---> Export then choose Java - Runnable Jar
You can then choose how pack the jar and how handling libraries :
You can also save the ant script for later modification or use ...
You actually should use Ant or Maven for your task, I see no other option. Ant is already packed with eclipse, you only need to install a JDK, not only a JRE.
Ant is very easy to learn and you can find billions of examples in the internet. With ant you can do exactly what you want.
Maven is the more up-to-date way to build and package jars and do much more other stuff. Maven also is a good choice for you.
I'll second a vote for Maven. Eclipse has a decent maven integration (m2eclipse). Then check out this answer for building the jar effectively using Maven2
Building a runnable jar with Maven 2
So I've been pigeon-holed into writing some Jython code. I've been using the latest version of Eclipse IDE with the PyDev plugin for development. Up until now, things have been moderately tolerable. I've gotten all my Python scripts working and I'm successfully including a couple of JAR files and the class directory of another Java project as external dependencies. Everything seems to run fine through the Eclipse IDE.
Now I need to package everything up and deploy it. From what I can gather, the best way to do this would be to package everything up in a JAR file. The Jython documentation suggests starting out with the jython.jar file and adding to it. OK. So I modify my main python module and start adding all my python source to the JAR.
It executes but of course can't find all the external dependencies.
How is one supposed to add the external JAR files so that they are correctly seen by the Jython interpreter? How is one supposed to manage more complex dependencies in a setup like this?
Is there a plugin for Eclipse or maybe something like Ant or Maven that can handle all of these steps for me with the push of a button?
I can't be the first person that has needed to deploy Jython code with complex dependencies can I?
I've made some headway on getting this all working so I thought I would put some notes here in case they help anyone else out. I'd still like to hear from others on their experiences trying to put together something like this.
It turns out that Eclipse as of 3.5 has a project export option for Java -> Runnable JAR File. If you use this option, you can point to a Java main class in the export wizard. You also have the option to have it repackage all the JARs that you are dependent on in your new JAR file. Make sure to check the box to save the export as an ANT build so that you can repeat the process quickly. NOTE that the first time you do this through the interface, it may fail, but it will still have created a JAR file.
Now here's where it gets strange. To track all the dependencies, I am still using a mostly incomplete Maven build in my project. I create the Maven .POM file. And I told Maven what my external JAR dependency was. I then told Maven to do a dependency update for me. It pulled everything into my Maven repository as expected.
Now when I do my ANT build, it appears that it is getting its list of JARs to include in the final build from Maven. I'm not really sure if it is supposed to work that way. I'm also not 100% sure that it is working. I guess I'll find out when I have to add another external JAR to the project.
Anyways, if you follow this question you'll see that you can take the latest builds of Jython and pull the org.python.util.JarRunner.java file out and use it in your own project. This is you Java.main class that you will need to point your ANT build at. From there, convert your main Python/Jython script to be the run script that was talked about in that question.
Next, build up another copy of the Jython JAR file in your Jython directory. This one should have the /Lib directory pulled into the JAR. Save that off and then point your Eclipse IDE Jave Build option for your PyDev project at that JAR as an external dependency. Your JarRunner will now work and execute the run.py file under Jython.
If all that works, you should then be able to rerun the ANT exported build from earlier and you will end up with a single JAR file that you can execute on the command line as:
java -jar {yourjar} args
And distribute to your customers without any additional dependencies.
If that all seems a little bit convoluted, it is. If anyone has a better way of setting this all up using Eclipse, please let me know.
Make your life easier and just use Maven and the mavenjython compile plugin.
See my answer of this question: Using Jython with Maven
You get full automation of the build and deploy process, and the result is a jar that includes jython and all other dependencies.