Java Webstart Application - Loading Properties From a Separate File - java

I'm currently setting up our project to deploy to users via java webstart instead of the current set up in which users run a .bat file from a shared network drive. When the application is run, it is passed an properties file argument which contains information such as database credentials which allows for the switching between different environments etc.
I would like to know if there is a way to specify this in the JNLP file and have webstart pull down the properties file from the webserver. I've spent a decent amount of time investigating this online and the only thing I could come up with was to simply specify the filename as an argument like so:
<application-desc main-class="Main">
<argument>example.properties</argument>
</application-desc>
and then include a separate link which let users download the properties file from the server. The issue with this is that if the JNLP file and the properties file arent downloaded to the same directory (which seems to be the default behaviour in IE) then the whole application falls over. Is there a way of bundling my properties file along with the other resources in the JNLP file or am I going about this in a completely incorrect fashion? Any help would be greatly appreciated!

You can set the properties in the .jnlp file itself instead of having a separate properties file.
http://www.coderanch.com/t/200871/JNLP-Web-Start/java/Properties-files-JNLP
Other solutions are:
Put the properties file inside the main jar or in a separate jar and add it as a resource.
Put location of the properties file as a property or as a main argument and download it from the program itself.

Looks like the jnlp is an XML file which includes a list of jar files to be placed in your classpath.
If you include a properties file in one of your jars then you can read it using this.getClass().getClassLoader().getResourceAsStream("mypropsname.properties").
Do all your users need the same properties file?

Related

Problems with JPackage due to different path structure between Windows and Linux

On Windows I have just converted my application installer from Izpack to JPackage and because of the structure created by JPackage I had to make some code changes to allow my application to find various config files, basically they are copied from app folder to C:\Users\Username\Appdata.... on first start (but bit more complicated than that).
I am now using JPackage on Linux, and the application copies config files from app to $HOME/.appname. However whereas on Windows app is a subfolder relative to launcher with Linux its now in ../lib/app so the code doesnt work
So I have to make some linux specific changes, but it got me wondering am I doing something very wrong here in order for me to have to make these changes ?
One way to load configuration files is using the classloader: the files are packaged in a jar along with the rest of your application and you load them as a stream, not as a file:
Properties properties = new Properties();
InputStream stream = YourApplication.class.getResourceAsStream("/resources/conf.properties");
properties.load(stream);
The path (example) /resources/conf.properties is relative the .jar file where the file is bundled, so it does no depend on the installation folder.
The above example assumes that you're using a Properties file but this works for any resource you can load as a stream.

Use File Input and Output in .jar FIle

So I've created just a simple application which I'm using to apply for a highschool internship. It was built using Eclipse.
I initially exported into a runnable .jar file, but the location I initially saved files, ("src/fileDirectories") didn't work on export.I then set the location to "./fileDirectories") which works and the app can actually run, however the .jar file creates the folder directory in the same folder as the .jar file.
This isn't too bad, as I can create a folder with the .jar and the saved files in it, which is fine, but similar to images, I'm wondering if there is a way to save .txt files in a directory to the .jar file so everything works with just the .jar application.
Assuming the files you want to access are static, and are not changed by the application, you can do this using the classpath.
When you access a file using new File("path"), Java will look for it in the file system, relative to the working directory (i.e. where the application was launched from.
An alternative way to access files is to look them up from the classpath - this is the list of locations Java searches for resources. It includes, among other things, the top level of your JAR archive. You can access this as follows:
this.getClass().getResourceAsStream("/my_file.txt")
Build tools will generally have preconfigured directories (e.g. src/main/resources) which get copied from your source tree into the JAR so they can be accessed in this way.
This is great if you have some static resources or config which you want to access at runtime, but don't want to have to pass around with your application.
However, if what you want is a working folder for files which your application will make changes to or create new instances of, like user documents, you don't want this to be editing the JAR - you'll need to make a separate folder for these.

How to read a local properties file from an executable jar?

I developed and tested my program on Eclipse Indigo. No problem finding the properties file when run.
I created a runnable jar using Eclipse export.
The program cannot find the properties file when the program is run from the jar.
The properties file is not in the jar, it is in a subdirectory of the directory where the jar is deployed.
As noted above, this directory is on the classpath in the Eclipse run configuration.
C:/myApp/myApp.jar C:/myApp/properties/myApp.properties
props.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("myApp.properties"));
Do I just need to edit the Jar manifest to put the config directory on the classpath?
properties.load(this.getClass().getResourceAsStream(configFileSrc));
This should work.
In my case, configFileSrc = "/apiconfig/appconfig.properties"
I had to add staticresources dir in the build path.
Thanks
Yes. Make sure you specify the path of the config directory relative to the directory where the jar is located. Since you said above that the config directory is a sub directory of the jar location, this will probably just be
<configDir>
where <configDir> is your configuration directory name.
You will also need to use an absolute resource name for the lookup, by adding a slash to the properties file name:
props.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("/myApp.properties"));
This is because the relative name your specify will have the package path of the class appended to it, which you don't want.
Is there any specific reason you need to use the contextClassLoader? A simpler invocation would be to use the classLoader of the class containing the lookup. And, since the class can delegate to it's classLoader, you can simply say:
props.load(getClass().getResourceAsStream("/myApp.properties"));
Finally - have you considered putting the properties file in the jar itself? If it's not going to change at all, this would be a better option. You wouldn't need to specify the classPath in that case. Note that if you want, you could put it in a sub-directory in the jar , but you would have to change the resource path you looked for, and again use an absolute resource name
Here is some info on absolute and relative resource names:
http://docs.oracle.com/javase/1.5.0/docs/guide/lang/resources.html
Hope this helps!
The real problem here is that you need to make up your mind where your application is going to load the properties from when the application is deployed.
(How it works in Eclipse is kind of irrelevant ... unless you expect your users to install Eclipse to run your app!)
If you want it to load the properties from the JAR file, they need to be in the JAR file.
If you want it to load the properties from the file system, they need to be in the file system. That means you have two subsidiary issues:
Where in the file system will your application look? Bear in mind that this has to work for all of the OS platforms you support, and that different OSes have different conventions for where "configuration settings* should be stored.
Is there a default version of the properties file, and how will you install it?
If you want to load it from the CLASSPATH and not the JAR file, that means you cannot make your application an executable JAR. (Running as java -jar ... will ignore all attempts to set an external classpath.)
If you opt for a non-executable JAR file AND loading the properties from the classpath, you have more problems:
How do you set the classpath?
How do you install the properties file "alongside" the JAR file?
Are there security concerns with a (potentially) user writable directory on the application's classpath?
This is probably the worst option.
Once you have decided how (from where) your application needs to load its properties when deployed, the code for implementing your scheme is relatively straightforward. (Modulo the problems mentioned above.)
You could even combine a couple of options; e.g. look for the properties file in the file system and then fall back to a "default" properties file in the JAR file. Or you could make the file system location of the properties file a command line option or supply it via an environment variable or via -D and the system properties.

Can an external jar access a file within a folder in a project

I am using an external jar (stored in my lib file within an eclipse project) and that jar needs access to a file to which I am supposed to pass the path. So far I have only been able to make it work properly if I store the file in a completely separate area on the server.
I'd like to be able to store this file neatly within the project. For examples sake lets say that testfile.txt is in the projects src/testfolder. From within java I try to reference the file like so:
File file = new File("src/testfolder/testfile.txt").getAbsolutePath();
But that returns a path on my pc. In this case its:
"/home/me/testfolder/testfile.txt"
I'd like to application to be portable so I can move the jar file around if necessary without having to worry about bringing external folders. How can I reference this file within the application and pass that url to an external jar?
Does the jar includes this file as well. If yes, then it should not be an issue as the absolute path will be taken care of automatically.

Avoiding hardcoding of Property File path specification

I'm having a small problem decoupling the path specification for properties files that my JAVA program uses , from the implementation itself.
The program may be deployed at multiple locations with different directory structures and I don't want the path specification to be hard coded into the Program code.
Here is the situation as it exists now.
I have one folder server/
Inside which there are 2 packages core/ & support/ (both of which have many subpackages underneath)
What I had done earlier was that , wherever the path for a properties file needed to be specified , I just gave a relative path i.e. properties/
In this scenario, the properties file needs to be wherever you're launching the program from. This worked during testing , when i was manually starting the program up using
"java ". and i would put the properties folder wherever I was starting the program from.
But in a real scenario, this program will be autostarted by a script (ksh) which is executed at scheduled intervals by a job.
In this case , giving the relative path doesn't work. I tried putting the properties files in the folder where the scripts are located , but that doesn't work either.
Right now , I am having to manually specify the path for each environment recompile the code and deploy a separate copy for each environment.
Is there any way to remove this coupling and just have one location for the properties file regardless of where it needs to be deployed?
use a System.Properties entry to specify the path, then on command line add it via
java -DmyProp=somepath -cp yourclasspath YourClass
In your app, you can retrieve it with System.getProperty("myProp"), just be sure to add proper testing and handle the Property Not Found scenario.
Another practice is to leave props in a jar and then load 'em with the LoadResource, in this way you just need to deploy different config jars in each deployment, but I think that the System.setProperty way is the fastest.
Generally some clients may not prefer to use -D= while starting your application. In fact you should also provide a .sh/.bat script file along with your jar file so that client can just double click on the script to run your application.
In this script you can have variable declared which you can ask the client to be configure accordingly. Client can just open the script file in text editor and type in the path of the configuration file.
Other way to use this script file would be to do following :
1) Check if YOUR_APP_NAME_CONFIG variable is set in system environment. If yes then go to step 3 or got to step 2
2) Ask the user on command line for the location of configuration file. Check if the location is correct. If correct then set the environment variable YOUR_APP_NAME_CONFIG with value of location of configuration file.
3)Start your application
Having a script file for your application gives you lots of liberty to do many stuff around automating the environment configuration for your application.
In your application get the config file path by System.getProperty("YOUR_APP_NAME_CONFIG").
This all may look like lot of pain but think from client perspective. Its cake walk for client that he just double click a script to start your application and for the first launch of application the script asks for some inputs if needed and then your application is good to go :)
What I did was pass another classpath parameter with the jar invocation..
java -cp classpath1;folder-where-propertiesfile-located Application.jar
and in the application use getClass().getClassLoader().getResourcesAsStream("properties-file");
This will automatically fetch the properties file form the appropriate classpath folder..
With this setup, I could change the properties file inside the folder and use the same jar file without re-archiving the jar..

Categories

Resources