In order to load external JAR files that are not placed in WEB-INF/lib folder of my web application I have written a custom loader class by extending org.apache.catalina.loader.WebappLoader class.
What it does is on startup it scans the folder (in my case it is cataline_home\plugins\) and adds all the classes/jars in this folder to the classpath of my web application.
This all is working fine, it loads all the available classes and I can even execute them from my application; but for some reason these classes can't access the properties files within the JAR's.
Say I have JAR called pluginsms.jar, inside this JAR I have a properties file called sms.properties and I am using ResourceBundle resource = ResourceBundle.getBundle("sms"); to read this file, it works perfectly fine when I run it as standalone but when I try to load it in my web application (via the custom WebappLoader) it throws: Resource Not Found Exception.
Given below is the source for my WebappLoader:
public class PluginLoader extends WebappLoader {
#Override
public void setContainer(Container container) {
StandardContext ctx = (StandardContext) container;
try {
File pluginFolder = new File(System.getProperty("catalina.home"),
"plugins");
for (File file : pluginFolder.listFiles()) {
if (file.isDirectory()) {
continue;
}
if (file.getName().endsWith(".jar")) {
addRepository(file.toURI().toString());
}
}
} catch (Exception e) {
e.printStackTrace();
}
super.setContainer(container);
}
}
What my guess is that your property file resides in WEB-INF or Webcontent folder and you are accessing you property file using relative path. While your jars who want to use this property file can't see this path that's why you are getting this exception. I would suggest you to use static path for property file. I hope that can help you.
Related
I am trying to consume the WSDL file in the spring boot application, WSDL file is placed into the src/main/resource/wsdl/file.wsdl.
Project structure:
Code:
static {
URL url = null;
try {
url = new URL("file:///" + System.getProperty("user.dir") + "/src/main/resources/wsdl/outbound.wsdl");
} catch(IOException e) {
java.util.logging.Logger
.getLogger(OutboundService.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}",
"file:/D:/ERPLOGIC/ERPProjects/JAVA/mavenproject/eclipse-workspace/topconpoc/src/main/resources/wsdl/outbound.wsdl");
}
WSDL_LOCATION = url;
}
It works fine in locally, but when deployed in the AWS server as a war file, it does not work.
What is the proper to refer to the path in the Spring Boot application?
Try this
URL url = Thread.currentThread().getContextClassLoader().getResource("wsdl/outbound.wsdl");
This should work
The file is placed inside the Java resources directory src/main/resource and should be loaded from there in all cases. The reason it's not loading properly when deployed is that file is not in that location once packaged. Use the class to locate the resource file from the packaged Java app. This should work both locally and when deployed. Make sure to replace ClassFileWhereCodeLives with the class the static code block is inside of.
url = ClassFileWhereCodeLives.class.getResource("/wsdl/outbound.wsdl")
This is the content of my netBeans project:
To use the folder called "ErrorSet" i use this line:
File file = new File("ErrorSet/error_list.xml");
It is necessary to import this file because it contains custom error codes, to the point:
When you want to import something in a netbeans project, the default "root" from where you use the files is the project name folder like [projectName]/ErrorSet/error_list.xml ...
Where do i need to place the ErrorSet folder when deploying the [projectName].war from dist folder in tocmat7 so that i can use new File properly? What does the File("ErrorSet/error_list.xml") parent directory become since its in tomcat7?
Keep in mind that Web Pages and Source packages are different things.
To use the classes inside Source packages with custom files, you have to place your files inside a Package and use getClass().gerResource() like this:
In case the ErrorSet folder is a folder inside another package use this:
File file = new File(getClass().getResource("ErrorSet/error_list.xml").toURI());
And if the error_list.xml is in the same package as the class, simply use getResource("error_list.xml").
Don't use java.io.File.
Instead, use a stream that you can get from the ClassLoader, like this:
InputStream in = null;
try {
in = request.getServletContext().getResourceAsStream("/WEB-INF/ErrorSet/error_list.xml");
if(null != in) {
// read the XML
}
} finally {
if(null != in) try { in.close(); }
catch (IOException ioe) { /* log this */ }
}
Now, put your file into /WEB-INF/ErrorSet/error_list.xml in your deployment.
This will work whether the file is on the file system or packaged up in an unexploded WAR file. It will also work in environments with a SecurityManager installed that won't allow the web application to read files, because the servlet container probably does have privileges to read those files.
I have an application which is a ear file which contains war and some jar file. I want to access my war's web-inf folder using java code. I tried a lot but could not found anything that can help me to access my war file.
I extracted my ear file in folder structure according to jboss forums but still cant access web-inf folder.
i tried this code but it is returning the jboss bin folder not deployment folder
org.jboss.vfs.VirtualFile vFile = org.jboss.vfs.VFS.getChild("WEB-INF/config/custom.xml");
org.jboss.vfs.VirtualFile vFile1 = org.jboss.vfs.VFS.getRootVirtualFile();
I also tried using JNDI but could not solve the main problem.
InitialContext ic;
try {
ic = new InitialContext();
String moduleName = (String) ic.lookup("java:module/MyModule");
String appName = (String) ic.lookup("java:app/devcenter");
System.out.println("app name is : " + appName);
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Can anyone help me? How can I access my WEB-INF folder so that I can change my xml content at runtime?
The simple answer is you can't. An EAR is an archive which means you'd have to know the path, uncompress the archive (or at least the file from the archive), change it and compress the archive again. This would likely require or trigger (can't recall if it happens automatically) a redeploy.
If you have a file you're using for configuration I would suggest you store it in a known path you add to the paths in the server configuration.
You can't access it that way. What you can do is include that in your build path. Then you can access it like you would access any resource files. So copy them over to a folder inside your source folder. For example - src\main\resources\config\custom.xml. Your java classes will be inside src\main\java\ and your resource files will be there.
I have a Web Application project in java. If I deploy that project, then the project has on the Tomcat server at folder level a structure as follows:
-conf
-image
-META-INF
-profiles
-WEB-INF
I want to read some files from the folder "profiles" and "config". I tried using
Properties prop = new Properties();
try{
prop.load(new FileInputStream("../webapps/WebApplicatioProject/profiles/file_001.properties"));
} catch (Exception e){
logger.error(e.getClass().getName());
}
it did not work. Then I tried with
Properties prop = new Properties();
try{
prop.load(getClass().getResourceAsStream("../../../../profiles/fille_001.properties"));
} catch (Exception e){
logger.error(e.getClass().getName());
}
it did not work also.
How can you read files from folder "profiles" and "conf", which are outside the WEB-INF folder?
if the file is under WebContext folder we get by calling ServletContext object reference.
Properties props=new Properties();
props.load(this.getServletContext().getResourceAsStream("/mesdata/"+fileName+".properties"));
if the file is under class path by using class loaders we can get the file location
Properties props=new Properties();
props.load(this.getClass().getClassLoader.getResourceAsStream("/com/raj/pkg/"+fileName+".properties"));
As Stefan said, don't put them out WEB-INF/... so put them into WEB-INF/ and then read them in this way:
ResourceBundle resources = ResourceBundle.getBundle("fille_001");
Now you can access the properties inside fille_001.properties.
You can use ServletContext.getResource (or getResourceAsStream) to access resources using paths relative to the web application (including but not limited to those under WEB-INF).
InputStream in = ctx.getResourceAsStream("/profiles/fille_001.properties");
if(in != null) {
try {
prop.load(in);
} finally {
in.close();
}
}
If you really must, you can reverse engineer the location. Catch a FileNotFoundException before you catch the generic Exception and log File.getPath(), this puts out the absolute filename, you should be able to see form which directory the relative paths are derived from.
You should use ServletContext.getResource. getResourceAsStream works locally for me but fails in Jenkins.
You can use
this.getClass().getClassLoader().getResourceAsStream("../../profiles/fille_001.properties")
Basically Classloader starts to look resources into Web-Inf/classes folder. So by giving relative path we can access location outside of web-inf folder.
I am working on deploying a J2ee application that I have previously been deploying in JBOSS into Weblogic 10.3.1.0. I am running into an issue with external properties files. In Jboss I can just put the properties files into $JBOSS_HOME/server/default/conf, and they are loaded onto the system classpath and I can access them without any problems. I was able to put shared libraries into $MIDDLEWAREHOME/user_projects/domains/mydomain/lib and they were loaded into the system classpath without any problems but I am unable to load properties files.
Does anyone know how to include external properties files in Weblogic?
Thanks,
I figured this out and have it working the way I would expect. First I did try the suggestions as above. If i added a folder to my classpath, or put the properties files in a folder on my classpath, the jars in the file were picked up, but not properties files. If i put my properties files in a jar, and put them in a folder on my classpath everything worked. But I did not want to have jar my files everytime a change was made. The following works in my env.
If i place the properties files in %WEBLOGIC_HOME%/user_projects/domains/MYDOMAIN then they are getting picked up, without having to be placed in a jar file.
In weblogic jars will be loaded from the lib and the non jar files will be loaded from the domain folder
There are ways to read properties file in Java from weblogic classpath
One (Properties file located in the weblogic domain): Drop the properties file inside the Domain directory. This way the properties file is added to the weblogic classpath automatically and we can read from Java using resourceAsStream.
Two (Properties file from a User defined location):The advantage with this approach is that the property file can reside outside the JAR or EAR file and can be modified conveniently.
package com.test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertyFileExample {
private static Properties prop;
public static void myMethod() {
InputStream is = null;
try {
prop = new Properties();
String propFilePath = System.getProperty(“propFileLocation“);
InputStream iStream = PropertyFileExample.class.getClassLoader().getResourceAsStream(propFilePath);
//Note that the propFilePath is a -Dparam defined below in the setDomainEnv
prop.load(iStream);
prop.getProperty(“dbuser”);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In the weblogic setDomainEnv (under bin) => we need to pass the location of the property file as a -D argument to JAVA_OPTIONS
set JAVA_OPTIONS=%JAVA_OPTIONS% -DpropFileLocation =/dev/file/properties/some.properties
You can set a directory on the classpath and Place your custom properties file in that folder/directory. So that, the entire directory along with property file will be on classpath.
To set the directory on the classpath in weblogic 10.3.x
Create a folder in %DOMAIN_HOME%\config\ folder. example appConfig.
Place your custom property file (Let's say config.properties) in appConfig directory/folder.
Modify the setDomainEnv.cmd (Windows) to include appConfig in the classpath by setting %DOMAIN_HOME%\config\appConfig as value to EXT_POST_CLASSPATH(this variable is already defined in the setDomainEnv.cmd file) variable as below:
set EXT_POST_CLASSPATH=%EXT_POST_CLASSPATH%;%DOMAIN_HOME%\config\appConfig
You can access that file in you java code as below:
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream ("config.properties");
Properties prop = new Properties();
prop.load(inputStream);
String value = prop.getProperty("key");
Hope this helps.
The most flexible way is to use weblogic deployment plans and Generic File Loading overrides
External properties file with Weblogic
http://docs.oracle.com/cd/E21764_01/web.1111/e13702/config.htm#DEPGD188
Although it may be a little extra effort, if you put the files into a JAR before dropping them into that lib directory, that should work.
You can look at your setDomainEnv.cmd (Windows) or setDomainEnv.sh (Unix/Linux) script in your domain files and see what locations are added in the CLASSPATH for your domain. Then just choose one folder and place the properties file there, if you want a specific location for your properties file just edit the script.
that was my solution:
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
InputStream is = null;
String urlExte = System.getenv("DOMAIN_HOME")+"/properties/SmsBalanceadoWS/";
org.springframework.core.io.Resource resource = ctx.getResource( "file:"+urlExte+"/application.properties");
try {
is = resource.getInputStream();
} catch (IOException e) {
LOGGER.debug("ERROR"+ e.getMessage());
}