I am trying to read XML file from JAR used as library in my web app. How can I achieve that? My directory structure for XML file is:
commons/resources/config.xml
where commons is a Java project for which I will create a JAR and place under
apache-tomcat-8.0.32/webapps/myWebApp-1.4/WEB-INF/lib
after building and deploying it.
You can read the XML file as resource from classpath this way: this.getClass().getResourceAsStream("/config.xml"). It returns a stream that you can use for reading the content of the file and do with it whatever you want. It is only possible within the webapp the jar belongs to because webapps are isolated with respect to classloading.
Related
We are using Websphere 9 application server. We want some of the configuration files such as xml and properties files in a separate directory of Websphere server and want them too see accessible by ear/war file during the run time. I heard about shared libraries approach, but it apppears that only class and jar files can be used as shared libraries, but not xml and other files. Can anyone tell me an alternative solution where the external xml configuration files be made available for war/ear file during run time or in class path?
If you add a directory as a shared library path, the directory itself will be added as a class path entry to any class loader referencing the shared library (along with any jar/zip files within it), so you'll have access to loose files such as XML files through the getResource() API.
Note that the argument to getResource() needs to be relative to the location within the directory. For example, if you have the file test.xml, you could add it to the directory /sharedlib, created a shared library named "library1", and associate it with your EAR or WAR, and then your application could use use this to get at the file:
this.class.getResource("test.xml");
That would return you a URL pointing at /sharedlib/test.xml.
We currently have a library that compiles to a jar and is used widely by the company. The jar contains an xml file that sets properties for our cache. In order to change values in the xml file, it seems we need to unzip the jar, change the xml file properties and repackage.
Is there a better way considering this jar is a dependency that is just expected to work from other components without extra setup? The property file is loaded from a ClassLoader.getResource call using the filename of the resource.
Prerequisites
Apache Tomcat 7
Spring 3.2.11.RELEASE
Apache Camel 2.14.1
My Webapplication is deployed in ${catalina.home}/webapps/ as usual
Requirements
Reading xml file placed outside of war-Archive (for example from ${catalina.home}/myfolder/)
The xml file should be reloadable. So if the xml changes the new xml file should be available in my Webapplication
The xml file should be mapped to Java-Objects
First try
I have added the file to classpath via tomcat in catalina.home/conf/catalina.properties:
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,${catalina.home}/myfolder/
The file is placed here:
${catalina.home}/myfolder/myFile.xml
Reading and mapping the file to Java-Objects works via a timer in apache camel.
from("timer://myTimer?fixedRate=true&period=20000")
.setBody(simple("resource:classpath:myFile.xml"))
.unmarshal(myFileJaxbDataFormat)
.process(myFileTimerProcessor);
myFileTimerProcessor takes the mapped Objects and stores it to a Spring-Bean.
This Bean is used by other Camel-Routes to access the Data contained in the xml file.
Problem
As Claus Ibsen mentioned below the problem is that the ClassLoader caches the file. So the file is not read again if data in it has changed.
If the file ${catalina.home}/myfolder/myFile.xml changes it should be read again and the new values should be available to the timer so it can read the new values for the application.
Is there a possibility to read a xml file outside of war-Archive and reload it if it's content changes?
Is there a more common wary to do that?
Thanks in advance.
Regards,
Max
EDIT 1:
I have restructured the question to ask not only specific details.
The file is cached by the Java classloader, not something Camel can do anything about. You likely need to load the file using file resources instead of classpath.
I have a java application in Eclipse that uses an eml file like so
File matches = new File("matches.xml");
The file is located in the default package as all the other classes. When I create the JAR it bundles in the XML file with it. My application require me to be able to make changes to the XML file. How can I set it up so the JAR can reference the XML file outside of itself?
My application require me to be able to make changes to the XML file.
Then you will need to extract it from the Jar and save it somewhere on the local file system.
See How can an app use files inside the JAR for read and write? for more details.
If you're using new File("matches.xml") that won't use a file within a jar file at all. It will only look on the external file system.
If you need to be able to use an external file if it's present, or the version in the jar file as a fallback, you'll need to test for the file's existence (File.exists()) and use Class.getResourceAsStream("matches.xml") for the fallback behaviour.
As you want to keep the file outside the jar and want to update it so the jar can read, so you can put the file in the same directory where the jar is and use the following code to access the file
FileInputStream file = new java.io.FileInputStream("matches.xml");
So this can be the directory structure.
- matches\
- matches.jar
- matches.xml
I am trying to use a jar file which itself is a web application in another web project. In my jar which i have created using eclipse's export to jar functionality, I have stored a csv file in a folder. To use relative paths in the code in the jar I access it using
MyClass.class.getResource(ApplicationConstants.ALIASESFILE).getPath();
and this works fine when I deploy (glassfish) and use the project as a separate application. But when I am using the same from within another project, it gives a path as shown below
D:\javaProjects\AutomodeGS_Prachi\lib\internal\RESTWSGS.jar!\aliases\aliases.csv
I am getting a file notfound exception.What could be wrong?
The getResource() method is returning a "jar:" URL. The path component of that URL is not a normal filesystem pathname, and can't be opened directly using Java's file classes.
The simple way to do this is to use Class.getResourceAsStream(...) to open the stream. If you need an "identifier" for the JAR entry, use Class.getResource(...), but then open the stream using URL.openStream().
This works fine from glassfish may be because glassfish has exploded jar on file system so that your csv file is acutually a file to the file system,
if you try to read it from another project it fails because the jar containing your file is in classpath that is fine, but the csv file is under jar file and it is no longer a File
You can read it as Stream
InputStream is = MyClass.class.getResourceAsStream(ApplicationConstants.ALIASESFILE);