Java - Get server absolute path - java

How to get the absolute path of server location in my machine?
Suppose I am using glassfish server then I need to get absolute path of glassfish docroot location as below:
C:\glassfish3\glassfish\domains\domain1\docroot
At run time, I need to create file on that location using java io package like:
C:\glassfish3\glassfish\domains\domain1\docroot\myfile.txt

If you use GlassFish to start GlassFish, i.e. use asadmin start-domain|start-instance then we offer the following iron-clad guarantee:
The current working directory of the JVM is absolutely, positively guaranteed to be the config directory of the domain or server. In the default case that would be:
c:/glassfish3/glassfish/domains/domain1/config
If you want to write something to (the default) docroot, you can do this:
File f = new File("../docroot/yourfile");
Another option that is guaranteed to always work in every scenario even if you start the server with java directly (e.g. java -jar glassfish.jar) is to use the value of the System Property like so:
File f = new File(System.getProperty("com.sun.aas.instanceRoot") + "/docroot/yourfile");

I don't know if this is the best way, but it works for me :)
String path = new File("").getAbsolutePath() + File.separator + "docroot";

you can try following:
System.getProperty("catalina.base");
And you can find other properties by watching following variable in debug mode.
Properties properties = System.getProperties();

I had an similar problem and ended up with using
path = getClass().getProtectionDomain().getCodeSource().getLocation()
because I needed the path on a static function. This points somwhere to the WEB-INF/classes directory. With this you could point to something like path.subString(0,path.indexOf("WEB-INF")).
One problem that I had with this: When running a test from Eclipse, it pointed me to the "build" directory of the project.

This is a very bad idea. If you are running in a WAR or EAR file the docroot will not be on a writable filesystem. Assuming this is the case may lead to headaches later.
Use a different method, such as a servlet initialization parameter, to specify a writable filesystem location.

For that you need not to go for complete path because
when you are creating file than by default it will create at ROOT of you server
which is C:\glassfish3\glassfish\ here.
hope this will help you.

Related

How to avoid hard code full path in Paths#get method

I want to save a copy of Primefaces UploadedFile to my project directory. I have been searching the internet for the solution, what I have found is using Paths#get method. The example given in this answer is Paths.get("/path/to/uploads");, the problem is, where is the exact path of /path/to/uploads? I can't find it. I mean where should I create the path /path/to/uploads? Under my project directory? but which folder? I solve this issue temporary by hard coding the full path like Paths.get("C:/uploads/");
FacesContext.getCurrentInstance().getExternalContext().getRealPath("/") will return you the current installation directory of your project.
And as #Kukeltje suggested, never ever save an uploaded file to your project directory, ... save it outside the webapps or even outside your container.
Therefore create a directory outsite your container (where you want to place your uploaded copies) and append ../ to the above path for each back step.
Say, if your application is deployed at D:/Tools/Tomcat7/webapps/your-application-name (e.g. on Windows using Tomcat) and you want to save copies to D:/Tools/uploads then following will give you required file path:
String uploadsFilePath = FacesContext.getCurrentInstance().getExternalContext()
.getRealPath("../../../uploads");
Use it with the Paths.get(uploadsFilePath) and develop your download logic (I am not sure which library you are using for the Paths class).
How about getClassLoader().getResource(Path/to/file)
So like
MyClass.class.getResource(bla/bla)
Which are now nested in src/resources
Like this You are system independent
#profit
You have several options:
For very quick development, you can use a hardcoded path, but be sure that it exists in your SUT (system under test).
You can define it as a static final string in your module, but this means that each time you want to change that path, you will need to recompile...
You can read that value from a property/config file.
There are more options (like using the registry if you are on Windows, or using an environment variable).

Path resolution in eclipse package structure

This is a very simple question for many of you reading this, but it's quite new for me.
Here is a screenshot for my eclipse
When i run this program i get java.io.FileNotFoundException: queries.xml (The system cannot find the file specified) i tried ../../../queries.xml but that is also not working. I really don't understand when to use ../ because it means go 1 step back in dir, and in some cases it works, can anyone explain this? Also how can I refer to queries.xml here. Thanks
Note: I might even use this code on a linux box
I assume it is compiling your code into a build or classes folder, and running it from there...
Have you tried the traditional Java way for doing this:
def query = new XmlSlurper().parse( GroovySlurping.class.getResourceAsStream( '/queries.xml' ) )
Assuming the build step is copying the xml into the build folder, I believe that should work
I don't use Eclipse though, so can't be 100% sure...
Try
file = new File("src/org/ars/groovy/queries.xml");
To check the actual working directory of eclipse you can use
File f = new File(".");
System.out.println(f.getAbsolutePath());
You could try using a property file to store the path of the xml files.
This way you can place the xml files in any location, and simply change the property file.
This will not require a change/recompilation of code.
This would mean you will only need to hardcode the path of the property file.
If you prefer not hardcoding the path of the property file, then you could pass it as an argument during startup in your server setup file. (in tomcat web.xml). Every server will have an equivalent setup file where you could specify the path of the property file.
Alternatively you could specify the path of the xml in this same file, if you don't want to use property files.
This link will show you an example of reading from property files.
http://www.zparacha.com/how-to-read-properties-file-in-java/

File paths in Java (Linux)

I have created a Java application that loads some configurations from a file conf.properties which is placed in src/ folder.
When I run this application on Windows, it works perfectly. However when I try to run it on Linux, it throws this error:
java.io.FileNotFoundException: src/conf.properties (No such file or directory)
If you've packaged your application to a jar file, which in turn contains the properties file, you should use the method below. This is the standard way when distributing Java-programs.
URL pUrl = this.getClass().getResource("/path/in/jar/to/file.properties");
Properties p = new Properties();
p.load(pUrl.openStream());
The / in the path points to the root directory in the jar file.
Instead of
String PROP_FILENAME="src/conf.properties";
use
String PROP_FILENAME="src" + File.separator + "conf.properties";
Check the API for more detail: http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html
I would also check what your current working directory is if your path to that file is relative. You just need to make a File test = new File("."); and then print that files canonical path name.
If you are referencing any other locations like user.dir or something to that effect by using System.getProperty(), you'll want to at least verify that the directory you are using as the relative root is where you think it is.
Also, as Myles noted, check the slashes used as file path separators. Although you can always use the "/" and it works.
And if you are referencing the path absolutely, you'll have trouble going between one OS and another if you do something silly like hard-code the locations.
What you want to do is check out System.getProperties() and look for file.separator. The static File.pathSeprator will also get you there.
This will allow you to build a path that is native for whatever system you're running on.
(If indeed that is the problem. Sometimes I like to get the current directory just to make sure the directory I think I'm running in is the directory I'm really running in.)
Check your permissions. If you (or rather, the user that the Java process is running under) doesn't have appropriate permissions to read the file, for example, you would get this error message.
This is a typical Windows -> Linux migration problem. What does ls -l src/conf.properties show when run from a prompt?
Additionally, check capitalisation. Windows isn't case-sensitive, so if the file was actually called e.g. CONF.properties it would still be found, whereas the two would be considered different files on Linux.
You should check the working directory of your application. Perhaps it is not the one you assume and that's why 'src' directory is not present.
An easy check for this is to try the absolute path (only for debugging!).
I would check your slashes, windows often uses '\' vs linux's '/' for file paths.
EDIT: Since your path looks fine, maybe file permissions or executing path of the app is different?
check your slashes and colons
in my case i set my PS1 to following value
PS1='\n[\e[1;32m]$SYSNAME(\u)#[\e[1;33m]\w [\e[1;36m](\d \T) [!]\e[0m]\n\$ '
i am trying to read from the env .such as system.getenv
Java was throwing exception
java.lang.IllegalArgumentException: Malformed \uxxxx encoding
Try the double slash, after doing things in JBoss I often had to refactor my code to use the double slashes

Loading application properties in a Java desktop application

What is the best way to store and load application level properties in Java.
Is there anything simulare to .net where I would just put something in the app.config
<appSettings>
<add key="emailAddress" value="me#example.com" />
</appSettings>
And then retrieve it like this:
string AdminEmail = ConfigurationManager.AppSettings["emailAddress"];
Do I have to load properties files into file streams and such? seems like unnecessary work.
I have tried this:
Properties props = new Properties();
FileInputStream fis = new FileInputStream("myProps.properties");
props.load(fis);
fis.close();
But this is give me a java.io.FileNotFoundException exception. Where does the properties file need to go to in relation to the class?
The Preferences API provides this functionality. It has many warts, but if you are looking to do this in an OS-agnostic fashion, this is the only way to accomplish this using the standard Java runtime libraries. You can of course always write your own OS-specific code to meet your needs. Yes, you can write simple code to load a properties file, but the location of that file can become a problem across multiple operating systems. I assume since you are writing a desktop app in Java, you care about OS portability. Otherwise Java might not be the best choice for a desktop app.
If you use a FileInputStream like that, your path is relative to the current directory of the OS, which usually is the startup directory.
If you instead use the Java built in resources mechanism (as described in the API, getResourceAsStream() et al), the path will be relative to the location of your class. With this approach you can also load resources from within jars and even over networks (for Applets for instance). The concept which is used is a sort of virtual filesystem, which is called the 'classpath' in Java jargon. There is a devx article covering it a litte more in detail.
In short, this sort of code works well:
Properties prop = new Properties();
//with properties in the same dir as current class
prop.load(getClass().getResourceAsStream("my.properties"));
//with properties in the root dir of your jar, or in base of classpath
prop.load(getClass().getResourceAsStream("/my.properties"));
You will need to add error handling...
Typically it will attempt to load from the application's current directory, which can vary depending on how you run it. You should be able to determine this at runtime by doing:
String currentFolder = System.getProperty("user.dir");
The file path it would be looking for in that case is relative to where you started your java application from. This is not where the main class is or the jar file but where you called Java from. If you are starting your application with a script that calls Java, then it is that directory.
Say for example, you application is bundled in a jar file 'app.jar'. Put 'myProps.properties' in the same directory and run 'java -jar app.jar' from that directory. It should find your properties file that way.
You can use Properties with a ResourceBundle. I use this in a application to store labels, buttons and messages in different languages
First you create a properties file, like test.properties. It´s a text file and inside it you put your information like this:
propertyname=value
In your case
emailAddress=me#example.com
email2=blablabla#example.com
and so on...
To get this properties in the code, create a ResourceBundle object with the name of your property file to call the properties.
ResourceBundle rb = ResourceBundle.getBundle("test");
To get an specific value from a properties file, just call the ResourceBundle
String value = rb.getString("emailAddress");
This way, the String named value contains the value of the property named "emailAddress", located in the test.properties file
String value2 = rb.getString("email2");
Likewise, the String named value2 contains the value of the property named "email2", located in the test.properties file
When you do not specify an absolute path, the one chosen is the current one.
It's not exactly what you asked, but if you want to use XML files as configuration, you could have a look at Apache Commons Configuration

loading from JAR files during deployment vs development

when i am loading some data into my java program, i usually use FileInputStream. however i deploy the program as a jar file and webstart, so i have to use getRessource() or getRessourceAsStream() to load the data directly from the jar file.
now it is quite annoying to always switch this code between development and deployment?
is there a way autmate this? i.e. is there a way to know if the code is run from a jar or not?
when i try to load it withoug jar like this:
InputStream is = this.getClass().getResourceAsStream("file.txt");
the returned inputstream is simply null, although the file is definitely in the root directory of the application.
thanks!
Why do you use FileInputStream during development? Why not just use getResourceAsStream from the very start? So long as you place your files in an appropriate place in your classpath, you shouldn't have any problems. It can still be a file in the local filesystem rather than in a jar file.
It's helpful to develop with the final deployment environment in mind.
EDIT: If you want something in the root directory of your classpath, you should either use:
InputStream x = getClass().getResourceAsStream("/file.txt");
or
InputStream x = getClass().getClassLoader().getResourceAsStream("file.txt");
Basically Class.getResourceAsStream will resolve relative resources to the package containing the class; ClassLoader.getResourceAsStream resolves everything relative to the "root" package.
You could read your data always as a ressource. You only have to add the path where the data lies to your classpath.
If your data stays in WEB-INF/somewhere/mydata.txt inside your jar file, you will access it with:
getClass().getResourceAsStream( "/WEB-INF/somewhere/mydata.txt" )
Now, if you create a development directory /devel/WEB-INF/somewhere/mydata.txt and put /devel to your classpath, your code will work in development and production.
EDIT after explanation in question:
In your case this.getClass().getResourceAsStream( "mydata.txt" ) the resource is taken from the same position where the classfile of this is taken from. If you want to keep this, then you have to create a directory /devel/<path of package>/mydata.txt and again add /devel to your classpath.
How about setting a system property in your dev environment, via the -D switch? e.g. java -D:mypropertyname=mypropertyvalue
You could set the property in ant scripts in your dev environment, other environments don't get the property:
e.g.
public static boolean isDevEnvironment(){ return System.getProperty("mypropertyname")!=null;}
You might find a better way to hack it from one of the existing System Properties
If a file is considered part of your deployed application (as opposed to be part of the installation specific files) and can be located through the classpath then consider simply always using getResourceAsStream since it works regardless of the actual deployment scheme as long as it is in the classpath.
You might also find the information available from the JVM relevant (if allowed by the security manager):
// Get the location of this class
Class cls = this.getClass();
ProtectionDomain pDomain = cls.getProtectionDomain();
CodeSource cSource = pDomain.getCodeSource();
URL loc = cSource.getLocation(); // file:/c:/almanac14/examples/
http://www.exampledepot.com/egs/java.lang/ClassOrigin.html?l=rel
There shouldn't be any difference between development vs deployment, IHMO.
Classloader.getResource or getResourceAsStream works well, you can read resources and even write them.You can write your own Protocol handles and access everything as an URL/URI, which allows you to read and write resources and also allows proper identification of who actually provide the resource.
The only problem is if an URLStreamHandlerFactory is already registered(in a J2EE application the container could install a factory and you don't have any way to go over and install your own) and you cannot use your handlers "anywhere".
Knowing that, it is preferred to implement your own "resources". At that time when I need it I couldn't find something like that so I had to implement my own ResourceManager. For me it looks more intuitive to access a resource like
Resource layout = ResourceManager.resolve("view://layout/main.jsp")
instead of
URL layout = Classloader.getResource("some_package/view/layout/main.jsp")

Categories

Resources