I am working on a java application that uses gradle with the launch4j plugin to create a windows exe wrapper. I am required to write a 'help' framework to display help documentation to the user from within the application, and I am unsure of a method to do this, given that the only items in the classpath are the various jar files in the lib folder.
I had planned on making HTML documents for the help files, and loading these documents in the GUI through the JavaFX WebView control. With this in mind, I have the following directory structure in my application distribution:
root
|
+ config
+ help
+ lib
- Application.exe
- LICENSE
Assuming I can continue to do this as I had planned, how might I get the help and config folders into the classpath for launch4j, using only gradle config scripts (not manually editing the launch4j.xml file). If this can't be done, is there another recommended way I can include external files on the classpath so I can safely reference them using ClassLoader.getSystemResource()?
You should put your help (and config) directories as resources into the JAR. To do so with Gradle, move these directories to the src/main/resources directory. From there you can access their contents via getClass().getResource() / getClass().getResourceAsStream().
Related
I'm kinda new to spring and web development as a whole.
My question is:
When you build a spring boot project (using Maven) into jar file and deploy it via Docker, everything is in one jar file. How can you access your resources (css, js, images, html...) if you want to edit something? Like change something in css file or add something to html page. Is it even possible? Or do you have to build a new jar file everytime, when you need to change something (in frontend)? Also, when there are being uploaded some images or other files, where are they stored? This stuff is very confusing for me and i can't find any related books or help at all.
Thanks for help!
when you package any java program it is nothing but a zip file. Based on what kind of package it is, you wither name it as a Jar or War.
Jar == Java archive
War == Web archive
Now, given the fact that jar and war both are essentially a zip archive, it gives you flexibility to extract and modify them just like any other zip file.
On windows, I think softwares like 7zip let you update the jar inline. I have done it multiple times, especially when I wanted to change application.properties alone on cloud machines, and no other code changes were required. In such cases, building the whole jar and transferring it again to cloud machine could be time consuming. So I would just extract the contents, update whatever I want to, and rezip the package.
Here is the commands you can use -
jar xf jar-file
This should extract the files into a directory.
This SO thread will guide you towards creating jar files.
Something like jar cf myJar.jar ** should be enough to generate a jar file IMO, but syntax might vary.
The jar file is actually just a zip file containing all the files and classes of your application, so technically you can change files in it like any other zip archive. Best practice is to build the jar file using Maven or Gradle from source every time you need something changed.
It's good practice to keep the source in version control using Git, and tag each build in the git repository - that way you can easily keep track of changes to the jar file by looking at what's in git at the time of the build.
Here's how I created a jar file using maven.
Now for my JavaFX Application, I'm using afterburner FX Framework. Now I need to create an installer for this app to be deployed to other devices. I'm using Install4j. My steps:
mvn clean package
copy and paste the generated jar file into a different directory
add that directory to install4j Files
on Launcher under Java invocation, I select the jar file, and then I select my main class: `BOOT-INF.classes.inc.pabacus.TaskMetrics.TaskMetricsApplication`
I Build the installer and run it, install to Program files, and then open the exe file
But then an error dialog shows up:
java.lang.NoClassDefFoundError: BOOT-INF/classes/inc/pabacus/TaskMetrics/TaskMetricsApplication (wrong name: inc/pabacus/TaskMetrics/TaskMetricsApplication)
So what I did wrong was two things:
Initially, like way way back, I tried using JavaFX with Spring Framework - unsuccessfully. I'm no longer using Spring, but I still had some leftover Spring in my pom file, which caused it to put the files in a BOOT-INF directory when i package it to jar. I just simply had to remove the Spring leftovers, and the boot-inf directory was gone.
So in install4j, you select a directory that would contain the files you would add to your installer. In the tutorials, they had a separate lib directory which contained external libraries. So I thought that's all I needed. I copied my dependencies into a lib folder via maven, then i put them into a directory along with my jar. So that's all my directory had - the jar file and the lib folder. That doesn't work. I didn't know. Apparently, it needs all the files inside the target folder generated by maven. I should've just used the target folder itself.
So there you have it. I have now successfully created an installer. I do hope no one walks as silly as me, but if you had also encountered the same mess up, well... here ya go.
You seem to have configured
BOOT-INF.classes.inc.pabacus.TaskMetrics
as the main class when the correct package name is
inc.pabacus.TaskMetrics.TaskMetricsApplication
Alternatively, your VM parameters configuration for the launcher is incorrect and includes text that can be interpreted main class.
I'm having a Java 7 application that's being built using ANT script (application is built into a jar file) and deployed to clients using JNLP file.
Currently I need to put some "property" into JNLP file but that property isn't visible from within my app unless I mark that particular property as "secure" (meaning to put "jnlp." as property name prefix). That works but I don't think it's a good way to provide my custom properties to the application.
In order to use jnlp properties they way I should, I have to "sign" jnlp file as described here.
As I'm using Java 7, the ability to make JNLP template is nice but I'm not sure were to put described JNLP template in my project structure nor how to include it in my Ant build.
I'm not very "fluent" with Ant.
You need to use the signJar task in Ant. Here is a link to the documentation and examples of how to use it.
https://ant.apache.org/manual/Tasks/signjar.html
You need to add the JNLP to the JAR file under the directory and name specified in your link, which is done via the <jar> task, and then sign it with the <signjar> task.
As the article describes if you want to sign your JNLP file you have to put it into the JNLP-INF subdirectory. So your project structure should look like this:
YourApp.jar:
\- com (folder with your java classes)
\- META-INF (folder which contains the manifest)
\- JNLP-INF (folder which contains your.jnlp file)
\- ... (other folders like res, dtd etc.)
The JAR file is created and signed in the usual manner - there is no extra task necessary. Please note, that when the app is started, the JNLP file used must be identical to the JNLP file in the signed JAR in order for the application to run.
under "jar" i have only 2 subnodes: "manifest" and fileset dir="${workspace.path}${project.name}/bin"
This means that a manifest will be created and every file and folder which is in the /bin directory will be included in your app.jar file. So e.g. eclipse automatically puts each of the source directories into the /bin file. So depending on what kind of IDE you are using / or not using you have to copy the JNLP-INF manually. Since signing is always done on the whole jar file you doesn't need to do anything...
I currently have a large Java program built using Swing and I am exploring the possibility of migrating to JavaFX. I am particularly interested in the ability to support native packaging since my current configuration involves simply double-clicking an executable JAR file and I find that many of my users are confused by this. Here is my problem: my program uses a plugin architecture in which, upon launching, it discovers various tools contained in JAR files and Groovy scripts. Because the end user can add their own tools by adding their own JAR library or script file the tools must exist in a folder outside of my main JAR. The folder must be discoverable by the end-user such that they could add/modify these files themselves. Here is my current configuration:
./ - the root of the program
|__ main.jar
|__ Resources folder containing JAR libraries and script files
This flexible configuration also allowed for the program to simply be copied into new locations without requiring a proper setup. So, I ask, is there any way of maintaining this type of open configuration while using the native packaging utilities that are now available? Would I need to create a resources folder outside the location of the JAR itself during some kind of setup? If this is the case, how do I go about doing this?
I wish to compile my java project in eclipse but I am at a loss and I can't figure out how to include my pictures and my database in the project or how to compile them all into one .jar file. Any help will be appreciated.
To add to what Bruno said. If you're using eclipse to build/package your project then:
add resources subfolder to project root folder
right click project -> properties -> java build path and in source tab add the folder you just created.
You can load data from InputStreams obtained from the classloader (using data on the classpath, possibly in a jar) instead of a FileInputStream (assuming that's what you do) as described here: http://download.oracle.com/javase/1.5.0/docs/guide/lang/resources.html
For the database, it will depend on whether the database engine you're using can load from the classpath. This method doesn't allow you to write, and some database engines may require write access for locking (depending on what you do with the DB).
Any file/directory you copy under the /src of your eclipse project will be included in the jar file created by eclipse and will be accessible from the java programs of that project as classpath resources.