Is there a way to get the application directory in Java? - java

This likely isn't possible, but I thought I would ask just to be sure. I have a batch file which starts my java app using relative paths. Ie. i have:
Application\start.bat
Application\lib*.jar
My application creates a configuration file in the Application directory. My batch script uses relative paths to point to the lib directory jars. This has worked really well for me because I can move the program wherever I want and it will just run. However now I would like to be able to call the same app from command line as well not just from a shortcut which has the working directory set to Application. The problem is that I want to be able to call my application from any directory on the command line and right now this doesn't work because the working directory will be different.
I know I can always add another parameter to my app for the working directory but then I still have to create a batch script with a hard coded path to my application. Is there any way around this in Java, for example to get the directory that my main java file is in on top of the working directory? Is there a launcher app perhaps?
I can't bundle my app as a jar because it creates configuration files which I want to be in the same directory as the application.

Consider just changing current dir in start.bat:
#cd /d %~dp0
java ...
This would change it to the folder where script is located.
pushd/popd commands can also be used to preserve current dir for calling script if needed.
Alternatively getClass().getProtectionDomain().getCodeSource().getLocation() can be used from java to get path to jar/classes.
There is also path-independent approach with config path system property:
java "-DconfigDir=%~dp0" ...

There is no portable solution that is going to work in all cases. Indeed, the notion of an application directory does not necessarily make sense; e.g. consider applets and applications launched using WebStart.
If the notion of an application or installation directory does make sense, then the simplest way to support it is to have the application's launcher / launch script pass it to the application Java code via an application specific -D property.

Related

How do I change the Tomcat default working directory?

In my web application, when I do new File(".").getAbsolutePath(), the path returned is <tomcat_home>/bin. I want to change it to <tomcat_home>/webapps/<app_name>.
The default directory for HTML ./path works fine and is the path I want. But the Java path ./Path is different in the same project.
I have tried to add a parameter like workDir="Path" in the <Host> area of the server.xml file on my Tomcat server, but it doesn't work.
How do I change it?
The general question of how to change the working directory of a java process has been asked before. The simple answer is that the java language and the java virtual machine don't provide a way to change the working directory of the JVM process. You won't be able to change the working directory after tomcat has started.
Tomcat's startup scripts (bin/startup.sh and so on) don't set a working directory. The tomcat process will normally inherit whatever the current directory was for the startup script. See this question. To make tomcat start in a different working directory, you'll have to figure out what is launching tomcat, and change that process to change to the desired directory before it runs startup.sh.

get the root directory of a maven application

I need to provide a settings file for my program, to which the user should have access to write some of the settings i need.
I created a file under a new directory (called settings) on the root of my application, but i have problem finding it at run time.
I use
File SettingsFile=new File(ClassLoader.getSystemClassLoader().getResource(".").getPath()+"settings/CreateSettings.txt");
When i execute this under eclipse i get
/application/home/dir/target/classes/settings/ZipCreateSettings.txt which is wrong.
If i execute it on terminal using java -jar, i get the correct path,
/application/home/dir/settings/ZipCreateSettings.txt
This would cause me problems cos i need to run the application directly from eclipse and not use the terminal, even though it is going to be executed using the jar when it is up and running.
I cant keep it like that anyway, cos this code might end up in someone else's hands, and they would have no idea what to do with it.
I have also used some other techniques like
new java.io.File("").getAbsolutePath(); but this always gives me the current working directory, so if i execute the jar from /home, i would get /home.
I think the problem might be maven (which i am not familiar with at all) since my code worked with a plain java application some time ago.
Since your file will be located outside your classpath, it is basically outside your application. Your application is not aware of files existing outside it's classpath. So you will need some kind of way to provide the Full/Absolute path to your file. You can't use the classloader in your case.
I suggest you use a system param instead of a hardcoded value. See here

How to get location of runnable .jar File when run from GNOME

I am developing a small Java application using Swing, that is supposed to run on Windows/Linux and MacOS.
Eventually it will ship as a runnable jar with some config files in the same folder. To load them I need the path to the folder the jar is stored in within the program.
There are already a couple of threads like this one or this one.
My problem is, that all the solutions discussed there work fine, when I run the program from within eclipse or call the runnable jar from a terminal like so:
java -jar /path/to/jar/jarfile.jar
However when I click on the jar file in Cinnamon or Gnome (which is what most of the users will know to do), I do not get the correct paths. (MacOS users report the same issue)
Here is what I've tried so far and what the output is when run via double click (all those display the desired path when run from eclipse or a terminal):
ClassLoader.getSystemClassLoader().getResource(".").getPath()
Output: file:/usr/lib/jvm/java-6-openjdk-common/jre/lib/ext/pulse-java.jar!/
SomeClass.class.getProtectionDomain().getCodeSource().getLocation().getPath();
Output: ./
System.getProperty("user.dir");
Output: /home/myusername
Is there any other way to do it or am I doing something wrong when exporting the jar? Any help would be appreciated!
Cheers
Nick
Make it simple, and use a startup script (.bat/.sh file) to run your application. This startup script will get the path of its own location in the filesystem, and pass it as an argument or system property to the Java application. This has the additional advantage of being able to pass other arguments, like the size of the heap, etc.
On windows, %~dp0 is the path of the directory containing the executed bat file. On Unix, you can use $(dirname $0).
You could store all config files as resources in a jar, and copy them to files in home.dir + ".AppName/".
Painful as it is, the Preferences API, Preferences.systemNodeForPackage, seems the wisest alternative, if there is little structured config data. There is an inputStream method for import; your initial config template could be a resource in the jar.
Just get the class path using System.getProperty("java.class.path") and scan it for your ".jar" name. Note that path separators are OS dependent (File.pathSeparator)

Specifying the location of Java communication libraries

Is there a workaround or a solution to having to place the javax.comm.properties file and the win32com.dll file in their respective folders?
My program works fine when I have the files stored as below:
%JAVA_HOME%/jre/lib/ext/comm.jar
%JAVA_HOME%/bin/win32com.dll
%JAVA_HOME%/lib/javax.comm.properties
This worked well until IT changed the permissions on our computers so that we can no longer write to these folders. I'd like to be able to install the Java program I wrote that uses the serial port once without needing to re-install it every time IT decides to update our JVMs. Does anyone know of a way to do this?
It's always a good practice to decouple the execution of your application from the configuration of the machine it is running on. In your case the first task will be identifying where you want to store the extra libraries and configuration files that are needed (its probably best to bundle them with your application). Once that is done, then you can configure your application to find them at launch:
Assuming the following directory tree:
myapp
|
--lib (archives and shared libraries stored here)
|
--resources (configuration files go here)
You could do:
java -Xbootclasspath/a:myapp/lib/comm.jar -cp "myapp/lib/*:myapp/resources" -Djava.library.path="myapp/lib"
Your JAR and DLL files would go into the lib sub-folder, and the property file would go into the resources subfolder.

Can my Java software be transformed to .exe software?

Without learning new programing languages, can we using Java get .exe (executable windows file) software directly? And is there away to make .jar (Java ARchive) software transform to.exe (executable windows file)?
Would this conversion effect the performance of the software?
One of the important points of Java is that it'll run on any platform (e.g. Windows, Linux, etc) that has a suitable Java Virtual Machine (JVM) installed. A .exe file is compiled to work on only one platform.
What you think you want is to turn a .jar into an .exe so you can launch it easily. What I expect you really want is just an easy way of launching a Java app that anybody can understand, including your parents.
The easiest way of doing this is to create a Windows batch file that launches your Java app. One of line of script, one new file, one new instruction to your users - "Double click on runme.bat"
There are ways of turning a .jar into an .exe, but you should think about whether that's really what you want, and if so, why.
Note: you can launch a .jar in Windows by just double clicking on it, as long as the main class is specified in the manifest. You might want to look into tools like Apache Ant to simplify building .jars and their manifests. Just a thought.
EDIT:
A batch file in Windows is a simple text file that contains commands. You can test the commands by running them in the command prompt (Start -> Run -> cmd). When you run a batch file the commands in it are just fed to the command prompt one at a time.
How to run a Jar from the command prompt: "java -jar myfile.jar"
If you create a batch file (.bat - use Notepad or your favourite text editor) containing "java -jar myfile.jar" (without the quotes!) then double-clicking it will launch the main class specified in the manifest of myfile.jar. myfile.jar has to be in the same folder as the batch file, though.
If you use the command "java -jar lib\myfile.jar" (again, without the quotes) then your batch file will run myfile.jar, which needs to be in a folder called lib that's in the same folder as the batch file. Use this approach when you have a whole load of Jars with your application and you don't want to shove them in the user's face :)
Note that moving the batch file will break it, unless it uses absolute paths to the jar file - e.g. "java -jar C:\dev\myfile.jar". Of course, if you use absolute paths then moving the Jar will break the batch file anyway :)
Also, note that you should be able to run a Jar file just by doubling clicking on it in Windows, as long as the main class is specified in the manifest. Give it a try. Of course, convincing your users that they can double click on it is another matter entirely...
As a final note, if you use a batch file, your users will get a nice command prompt window sitting in the background until your Java app closes. That is, unless you start your batch file command with "start". E.g. "start java -jar myfile.jar". If you have your app configured to log to System.out or System.err, you will still get a command prompt when your app writes to either of those streams, though.
Final final note, in the Linux world the equivalent of batch files are shell scripts.
You can launch a .exe from java with Runtime.exec() or ProcessBuilder.
You can make a .exe launcher with http://launch4j.sourceforge.net/
Yes, it is possible: http://www.excelsior-usa.com/articles/java-to-exe.html
I'm not sure if this is an appropriate answer because I don't work with Java but could you not using a shortcut file pointing to the java runtime and pass the jar as an argument, this
I realise this is not the only way, nor probably the best way but to me it seams a little better than creating a batch or converting to an exe file if all you're looking for is a convienient way to launch a java app
The very simplest way is to write a windows batch (.bat) file which will start the application.
I was using a wrapper for java to make exe files for a pretty long time:
JStart32
It is just a wrapper for *.jar files.
But ask yourself:
Wouldn't an exe kill the purpose of javas platform independency?
Check out jsmooth (free) and exe4j and you might want to read make your swing app go native

Categories