JavaFX native packaging with an external resources folder - java

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?

Related

How to access src/dist folder in Gradle project?

I'm developing Java application on Eclipse, using Gradle. From the application I want to access the files in src/dist folder. When developing, I can access the files by using the path src/dist. But when the application was exported to "distributed" style (by using Gradle task installDist), the relative path from System.getProperty("user.dir") to the files in src/dist will change.
What it the best way to access to those files seamlessly both while developing and after distributed, either by changing my Java source code or Gradle build script? I have come up with following ideas:
Add an option that indicates the actual location of the files. When running on Eclipse I can add the options to the Run Configuration.
Check if the program is running inside jar. I can do it by checking getResources() or something.
Please tell me if you have better way to achieve this, or what is the best practice from the viewpoint of maintainability.

launch4j and external files on classpath

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().

Reuse Ant build.xml for TFS 2013 BuildDefinitions

I have successfully built a Java web application using TFS's java support via ant. My problem is that I have several applications that share a common build process and would like to reuse the build.xml (with parameters passed in to differentiate the output), however, the TFS Build Definition does not allow me to reference a build.xml file that is in a shared location outside of the workspace mapping for my particular build.
For example, assuming the following Version Control structure:
Source
Applications
Application 1
Main
src
WebContent
Application 2
Main
src
WebContent
For each build definition I would like root to be that of the Main branch of that application so that only those source files are copied to the build server. I would like the build.xml to be stored in, say, Applications directory as it will be shared across Application 1 and Application 2. When I try this I get the following error:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\BuildExtensions\Microsoft.TeamFoundation.Build.Extensions.Ant.targets (306): There is no working folder mapping for $/Source/Applications/build.xml
This is because my Source Control Folder in the build definition is set to a child folder (Main). If I set my Source Control Folder to be the Applications folder, I believe it will work, however, I then notice that the build attempts to transfer ALL files under Applications to the build server which slows the build down to a crawl. Any thoughts on how I can achieve the desired reuse? Perhaps something in the TFSBuild.proj file that would restrict the files that get transferred using a parameter ${ApplicationName}/Main or something like that?
Thanks in advance for any assistance.
You can set up you workspace to include folders and cloak others. I can imagine that it would be arouse work to cloak all of the other stuff in scope. A recommended practice would be to have the shared folder under its own folder rather than the root of applications. That way you can map that folder explicitly as well as the branch that you want to build.
When the XAML builds are retired at launch of TFS 2015 the new build system allows you to have tasks that are shared between build definitions.

Dependency issues in deploying using Java Webstart

I am working on a project in Java which has a directory structure something like this:
MainFolder
/ | \
Folder1 Folder2 Folder3...
|
Program.jar|Run.sh
In Folder1 I have main jar file along with the shell script to run the program.
In Folder2 I'm having configuration files in xml which may later be modified by the program
and In Folder3 I'm having jar files that the main program depends on.
Now I want to deploy this program using Java web-start.My current understanding is that web start allows us to deploy programs using 1 or more jar files.My problem is that I need the directory structure also.Can anyone suggest a solution for this.
As mentioned by others, the shell script raises problems. What does it do specifically to 'run the program'?
For the configuration files - 'Folder 2', webstart provides the PersistenceService. I have a small demo. (1)
As far as the Jars in 'Folder 3' go. Move them, as well as the Jar's in folders 2 & 1 to a single directory named 'lib'. The main Jar and the configuration files will be required eagerly, which is the default for JWS. If any of the other Jars (ex. '3') might not be needed immediately or at all, they should be deployed as download='lazy'.
To access the local file system - for reading input supplied by the user or writing a new file they created - a JWS app. normally needs to be digitally signed and trusted. But JWS also provides the much more limited form of access through the FileContents object. For more details, see the demo. of the File Service in the page linked below. (1)
1) Demos of the JNLP API, including the PersistenceService & FileContents object.
I think you will have to make some changes to the structure for webstart deployment (possibly package it as a jar or set of jars), also the launching will be done via JNLP, by webstart and not Run.sh.
Additionally you will have to sign your deployment if you need permissions to write to the disk.
See the FAQ for webstart here
Also check out the developer guide on how to deploy using webstart
Java WebStart does not provide any help in making the filsystem as you need it - it only provides the program components for memory.
If you need this structure, you will need to maintain it yourself (and then, where?)
If the only thing you need is a shell script to run, you can keep the contents of that file as a resource inside your jar, create a temporary file at each run, put the desired contents inside, and execute it, and then delete the temporary file when you are done. Note that this brings you into the wonderful world of code signing which is rather tedious.

Whats best way to package a Java Application with lots of dependencies?

I'm writing a java app using eclipse which references a few external jars and requires some config files to be user accessable.
What is the best way to package it up for deployment?
My understanding is that you cant put Jars inside another jar file, is this correct?
Can I keep my config files out of the jars and still reference them in the code? Or should the path to the config file be a command line argument?
Are there any third party plugins for eclipse to help make this easier? I'm using an ant build file at the moment but I'm not sure I know what I'm doing.
Is there an equivelent of the deployment projects in Visual studio, that will figure out everything you need and just make an installer? I've used install4j before, and it was powerful if no where near as automated as .Net deployment projects.
Cheers.
There is no one 'best way'. It depends on whether you are deploying a swing application, webstart, applet, library or web application. Each is different.
On point 2, you are correct. Jar files cannot contain other jar files. (Well, technically they can, its just that the inner jar file won't be on your classpath, effectively meaning that jar files do not contain jar files).
On point 3, you certainly can reference config files outside the jar file. You can typically reference a config file as a file or a resource. If you use the resource approach, it typically comes from the classpath (can be in a jar). If you use a file, then you specify the filename (not in a jar).
In general, most Java developers would use Apache Ant to achieve deployment. Its well documented, so take a look.
(1) An alternative to ant that you may wish to consider is maven.
A brief intro to maven can be found here.
For building a JAR, maven has the jar plugin, which can automate the process of ensuring all dependent jars are listed in your jar's manifest.
If you're using eclipse, then download the maven integration as well.
(2) Another alternative is to use OneJar (disclaimer: haven't tried this myself).
The answers vary depending on what kind of thing you're building.
If you're building a library, it's best to distribute your work as a jar file. It's possible to refer to your jar dependencies via the Class-path attribute in your jar manifest, although I generally think that's uncool. That attribute was designed for applets and it's used infrequently enough in libs that when this technique pulls stuff into the classpath (particularly common stuff the user might already be using), you can get unexpected version conflicts. And it's hard to track down why you're seeing them.
Publishing a jar to a Maven repo with pom info to track dependencies is an excellent choice for libraries as well. If you do that, please publish your Maven coordinates in your docs!
If you're building an app, the two popular choices are to distribute a zip/tar/whatever of a deployment structure OR to use an installer program. If the program is a server-ish kind of thing, the former is far more common. The latter is more common for clients. Generally, the installer program is just going to lay out the deployment structure and maybe do some extra tasks like installing in OS-specific locations.
To build your deployment structure (aka "kit") you'll want to create a repeatable process in whatever build system you're using. Ant has copious examples of this and Maven has the assembly plugins that can help. Generally you'll want to include a jar of your code, any dependencies, scripts to start the program, maybe a JRE, and any other resources you might need.
If you want to create an installer, there are many options both free and commercial. Some folks I know have recently had good experiences with the free IzPack but check out your options.
You should try FatJar. It's an Eclipse plugin that with just a right click at the Project can build a JAR file with all you need to run the application, including the necesary third party JAR.
We use it everyday, in conjuction with JSmooth to create the executables, to deploy our software packages to our customers, and works like a charm.
Well, if you are speaking of deployment of a standalone desktop application:
Before we switched to web start we have been creating three deployment archives, one for windows, one for mac and one for other platforms.
On windows we have successfully used the Nullsoft Scriptable Install System (known for it's usage by the older winamp versions) and its ant task, although some drawbacks are:
It is only usable on windows AFAIR
You have to do some work by hand, i.e. customizing the wizard-created script AFAIR
It can create a windows installation with start menu entries on the other hand. There also exists an eclipse plugin for integrated NSIS shell script editing.
On Mac OS X there is an ant task to create an .app file from your java files so that you can start it like a native os x application. But beware of not writing any setting to your home dir and using the the application dir instead.
For others you have to expect they are in a un*x env and deploy your app with a shell script to start the application.
In any case you may have to deploy your custom policy file to get access rights for your application.
If you want to get rid of all the packaging and stuff you should seriously consider using web start. We have saved much time since switching to it, i.e. simplified our deployment process, takes care of updates etc.
Update 2014
Use maven assembly plugin, see section "Creating an executable jar"
Ant. It's not the best thing in the world, but it's standard, it's apache, and it works.
There's some good examples on the web how to make a simple build.xml for any, and it's got some features like the 'war' task that knows how to put all the basic stuff (classes, web.xml etc) in the jar file for you.
You can also tell it to pick up other config files and jars and it will happily do it.
It's also really smart about what to compile. You give it a directory, and it finds all the java files and builds them only if their classfile is out of date, so you get some of the traditional make functionality for free without much effort.
You could look at other java projects (e.g. JMeter, SquirrelSQL, JEdit, Cernunnos, etc.). Each package their applications slightly differently, so consider your goals when you review these.

Categories

Resources