How do I read a file from a location on my server?
I can successfully read from /WEB_INF/classes using:
InputStream systemParamInputStream = getClass().getClassLoader().getResourceAsStream("ldap.properties");
However, I would like to have this file somewhere on the server, so that it can be configured by the support folks when the application goes live in production.
My liberty profile server.xml lives here: C:\eclipse\runtime\usr\servers\tmpServer.
This would be fine, as indeed would any other location around there.
"WEB-INF/classes" is part of your classpath.
You can continue to read files as you do, by adding another folder to the classpath of the server. In that folder you would have the configuration files.
But you can also access the file directly like this:
InputStream systemParamInputStream=new FileInputStream(filePath);
The trick would be to find a clean way of configuring filePath of the configuration file as hardcoding is not nice. This is an option:
new FileInputStream(System.getProperty("filePath","C:\\eclipse\\runtime\\usr\\servers\\tmpServer"));
And you would send filePath as program parameter -DfilePath=c:\\
I'm using java.util.Properties:
Properties props = new Properties();
props.load(new FileReader("path to your file"));
This thread shows different approaches for doing it.
The one I have successfully tried is to specify a folder as a library in server.xml, so that it will be available in the classpath:
<library id="configResources">
<folder="${server.config.dir}/config" />
</library>
<application location="foo.war">
<classloader privateLibraryRef="configResources" />
</application>
Two minor warnings regarding this approach:
Requires 8.5.5
May result in a server.xml XML validation error in Eclipse due to the use of the folder element (cvc-complex-type.2.4.a: Invalid content was found starting with element 'folder'. One of '{fileset}' is expected.). I gave a try to use a fileset instead but could not get it to work.
Related
I'm banging my head off the wall on this one...I have a (so far fairly simple) google app engine project. During runtime I want to read in some XML files (resource file, not servable-static file) for processing. Having done a bit of research, I settled on reading the resource file through the servlet context (similar to the following). Works just fine on the dev server.
final InputStream inputStream1 = servletContext.getResourceAsStream("/" + pathToXmlFile);
Problem: Doesn't work in the cloud. First I thought the way how I am loading the resource is wrong, but I have noticed that the XML file in question doesn't appear to be uploaded at all. It is currently located here:
src/main/webapp/data/stuff.xml and
src/main/webapp/WEB-APP/data/stuff.xml
(I wasn't sure where to place the XML file, so I duplicated it into two locations.) The deploy log shows how the files are skipped:
2017-08-10 13:13:42,451 DEBUG root Skipping upload of [data/stuff.xml]
2017-08-10 13:13:42,461 DEBUG root Skipping upload of [WEB-INF/data/stuff.xml]
I have tried a number of things, without success, to get the file deployed. Things I tried:
Clear out the temp staging directory
Manually clean the build
Renamed directory / files
Include the file within the classes directory
Playing around with the resource-files section in the appengine-web.xml file (removing it, using various syntaxes)
Removing older versions of the app from the cloud
Restart Eclipse
FYI, current content of appengine-web.xml
<resource-files>
<include path="/data/*.xml" />
<include path="data/*.xml" />
</resource-files>
(Not sure if the slash is required....)
Note that the deploy does work for changed/new .class files, so my changes to Java classes are uploaded just fine. Somehow the deploy mechanism doesn't recognize that the XML file must also be uploaded.
FYI - Windows, Eclipse 4.7, Java 8, Cloud Tools 1.2.0.201706082053
Any help appreciated, especially if anybody knows how the deploy mechanism decides which files to deploy!
Try this:
<resource-files>
<include path="/data/**.xml" />
</resource-files>
This should include all xml files in data/ and its subdirectories.
Their documentation on include and exclude syntax, as I'm sure you're aware, is pretty skimpy. I'm pretty sure you want the double asterisk there though, and a bit more sure that you want the leading slash. I'm trying to find more info on it now, and will post a link if I do.
Thanks Brendan, the ** did the trick. FYI, the setup is now as follows:
<resource-files>
<include path="/data/**.xml" />
</resource-files>
<static-files>
<exclude path="/data/**.xml" />
</static-files>
Just using a single * was not good enough for "any XML file", it had to be **. As side-effect of the resource-files entry, the XML file now suddenly was also available as static file, accessible through the browser. So the exclude section inside static-files prevents the exposure of this. Not sure if this is overly elegant or the easiest/cleanest way to do it, but it works...
FYI, the "data" directory is contained directly underneath "webapp", and to access the resource the code is: servletContext.getResourceAsStream("/data/stuff.xml");
Note I also had to manually "touch" the XML file in order to get it to upload.
Thanks again.
I know this question has answered many a time with most useful answer as below,
Where to place and how to read configuration resource files in servlet based application?
However, We have some special requirement as below,
Webapp will be deployed to tomcat.
Normal java app in form of .jar will be placed under folder /myapp
myappConfig.property file will be placed under /myapp
Directory Structure on client machine
/myapp
/myapp.jar
/assests/myappConfig.property
/tomcat/webapps/myapp.war
Basically myapp.jar and myapp.war will access sql db connection values for MySql database connection and db operations.
Accessing myappConfig.property from myapp.jar --> Working fine
File jarPath = new File(Myapp.class.getProtectionDomain().getCodeSource().getLocation().getPath());
String propertiesPath = jarPath.getParent();
System.out.println(" propertiesPath-" + propertiesPath);
mainProperties.load(new FileInputStream(propertiesPath + "\\assets\\myapp.property"));
Can anyone help/suggest how to implement,
Accessing myappConfig.property file from mywebapp,
provided run time change in myappConfig.property file does not required myapp.war to be redeployed
Thanks for your help in advance.
edit
Below is the steps in which we want to deliver the project to client.
Below is my app directory
/myapp
/myapp.jar
/assests/myappConfig.property
/tomcat/webapps/myapp.war
pack everything in one package with some packaging tool.
Run this package in client machine at any location and it will have same directory structure as above
Here, I do not want to hard code any location in webapp or tomcat for "/assests/myappConfig.property"
Normal Java app I can read property file but for wepapp I am not getting clear idea for how to do that?
You can add a <context> to tomcat/conf/server.xml (in this example, linux path):
<Context docBase="/home/yourusername/tomcat/assests" path="/assets" />
If you are using Windows:
<Context docBase="C:\path\to\myapp\assets" path="/assets" />
And then you can access it like any other resource within your webapp (e.g.: /assets/myappConfig.property).
If you are using JDBC for example, you could store the connection properties in a Singleton and request it from there, and that class could take care of change checks on that file.
I have a web application which needs mybatis to connect to a sql server.
I have a separate property file as jdbc.properties which contains the dburl, username, password etc. and mybatis-config.xml file has following to read that
<properties resource="jdbc.properties"/>
If I add jdbc.properties file to the src folder it works fine.
But I have several other property files located at "catalina_home/bin/config" folder so I would like to move my jdbc.properties file also to that location.
But mybatis is not able to read the property file from their no matter how I changed the path to the resource.
However if I moved the jdbc.properties file to the "catalina_home/lib" folder it works. Therefore then I tries resource path like this "../bin/config" but it didn't worked either.
My question is, can I move the jdbc.properties file to the bin/config folder and let mybatis to read it from there.
EDIT: Since my production environment may change its CATALINA_HOME location I cannot give the full path to the config file location.
The reason that mybatis cannot find these properties files is that tomcat's bin/config folder is not in classpath of tomcat (or your web application) unlike $CATALINA_HOME/lib. And mybatis looks for file specified in resource attribute in classpath.
If you use url attribute you can specify full path name to file there.
<properties url="/full/path/to/you/jdbc.properties"/>
I need to read an application.properties file from a servlet application using Tomcat container. The file can not be included in my war so it can't be under webapps or Tomcat root folder in any ways. The file has to be somewhere in the folder. I also can not use FileInputStream to read the properties file. Only option I have is to define a JNDI name for a folder / directory and look that JNDI properties during runtime to find the folder location to read the file. Is thee any working example out there?
I have chalked out a solution for myself reading the following similar posts and articles.
The Context Container
Reading a global variable from tomcat with JNDI. Example not working
java:comp/env is not bound
I have defined a Environment inside my Context for my web application under
\conf\Catalina\localhost\mywebapp.xml as follows....
<Environment name="propertiesfilelocation" value="E:\\tmp\\application.properties"
type="java.lang.String" override="false"/>
Then accessed my properties file using a JNDI lookup to get the file name.
Context ctx = new InitialContext();
Context envCtx = (Context)ctx.lookup("java:comp/env");
String propertiesFileLocation = (String) envCtx.lookup("propertiesfilelocation");
LOGGER.info("String property === " + propertiesFileLocation);
properties.load(new FileInputStream(propertiesFileLocation));
#home : Yes you are right it involved FileInputStream. However, I am happy with the solution because I am no longer hard coding my folder location inside my Java code which makes my app more portable.
I have a slightly different approach to a similar problem. I also toyed with the idea of JNDI but I found this a bit of overkill.
I found another article by BalusC. It allows you to specify folder relative to your tomcat installation and deploy all your properties files there. So you keep configuration external to your application but you don't require seperate configuration for every properties file for every app.
Here it the link:
Where to place and how to read configuration resource files in servlet based application?
and the preferred choice is as follows:
Put it in the classpath, so that you can load it by
ClassLoader#getResourceAsStream() with a classpath-relative path:
Properties properties = new Properties();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("filename.properties"));
Here filename.properties is supposed to be placed in one of the roots
which are covered by the default classpath of a webapp, e.g.
webapp/WEB-INF/lib, webapp/WEB-INF/classes, appserver/lib or JRE/lib.
If the properties file is webapp-specific, best is to place it in
WEB-INF/classes. If you're developing a project in an IDE, you can
also drop it in src folder (the project's source folder).
You can alternatively also put it somewhere outside the default
classpath and add its path to the classpath of the appserver. In for
example Tomcat you can configure it as shared.loader property of
tomcat/conf/catalina.properties.
I hope this helps.
Allan
The server is a simple jetty Server
How to set the log4j.properties file i have a proper log4j properties file,
but while setting the log4j.properties
using the following manner, i have the log4j.properties in my src folder
PropertyConfigurator.configure("log4j.properties");
it works fine when i am working locally, but when i create a jar file and run its throwing an exception like java.io.FileNotFoundException:
i have tried extracting it and created it in another folder called resources and tried accessing that by the following method
PropertyConfigurator.configure("resources/log4j.properties");
even after that its showing the same error
how to export the entire project as a jar file and make this log4j problem to work?
Found another link
Log4j Properties in a Custom Place
and in that it is required to set the class path
java -Dlog4j.configuration=conf/log4j.properties -classpath ...
Do not know how to set the -classpath and dont know whether this method will work!!
And even if its exported as a jar file it should work!
If the log4j.properties resource directory is on the classpath, you could use:
PropertyConfigurator.configure("classpath:resources/log4j.properties");
To see the working directory for Jetty, you could add:
System.out.println(System.getProperty("user.dir"));
before the PropertyConfigurator.configure statement. This would allow you to see where the property file is located in relation to the server's working directory.
In order to make it work immediatley, you can configure them from code:
Properties props = new Properties();
props.setProperty("<KEY>","VALUE");
PropertyConfigurator.configure(props);
Hardcode the props object with all the properties from log4j.properties file.
This is not the solution you ask, but it might very helpful if you are short on time.