Tomcat7 deploying app with custom files - java

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.

Related

how to create file in java in resources directory

I have a maven project and need to write JSON objects in file.json that should be located in
src/main/resources/
But before I need to check if file exists. If not than create it.
public static void writeMenuJSon(String jsonParamIn) {
JsonParser parser = new JsonParser();
JsonObject modulJson = parser.parse(jsonParamIn).getAsJsonObject();
//TODO check if file exists and create file if not
code here ...
// write to file JSON object
try (Writer writer = new FileWriter("path to file")){
Gson gson = new GsonBuilder().create();
gson.toJson(modulJson, writer);
} catch (IOException e) {
e.printStackTrace();
}
}
Something is totally wrong if you are creating dynamically file in src/main/resources This is only going to work in your development environment. When you deploy your code using Jar or War there won't be this directory on file system. It will be contained within Jar / War or other packaging.
If you understand above and still want to do it. Go related to your current working directory to create file, Usually the working directory when you launch your Main from IDE is setup to root of project so create a file at
src/main/resources/foo.txt
will do it. Alternatively you can figure out your current working directory from your IDE launcher or at runtime using
System.getProperty("user.dir");
What are you exactly trying to achieve writing the JSON file to the mentioned directory ?
I might miss something important in your question but:
it is possible to create code that does this thing but i'm not sure at all how are you going to run this code and is it sane solution to your problem?
When you mvn package the project name P having this "src/main/resources/" resources there will be added to package P.war/.jar or so but there will not be any JSON-file in directory until you run the code - this code you are after - that generates it and it is not done without some -maybe ugly- extra job.
If you have this code included in this project it will be run only when the project package is run. And there will not be this "src/main/resources/" where to write it.

How to use a .properties file in Eclipse Java Dynamic Web Project?

I'm developing a Dynamic Web Project in Eclipse. I created a .properties file for store database details (Username, Password etc.). I added it by right clicking on the project and New -> File . I used the Java util package Properties class. But it does not working. I can not retrieve any property from the file. Here is the code I used,
Properties prop = new Properties();
try {
prop.load(new FileInputStream("database.properties"));
String db = prop.getProperty("database");
String userName = prop.getProperty("dbuser");
String password = prop.getProperty("dbpassword");
} catch (IOException ex) {
ex.printStackTrace();
}
Is there something wrong or Is there any particular place where I should put properties file.
What you did is correct, ie right clicking the project and new--file.You have to Put your properties where you start your jvm from. Please look into the attached image. The properties file is marked in red. Look if your properties file is also located something like this.
Also add this in your code to find out where to put your file:
System.out.println(new File(".").getAbsolutePath());
For more details please follow this link- FileNotFoundException when using java properties file
Normally, you make sure the properties file is in the project runtime classpath (e.g. WEB-INF/classes) and then load it using either the System classloader or the property file handler's classloader, i.e. (Freehand typing from memory -- NOT COMPILED)
try{
Properties p = new Properties();
InputStream in = MyPropertyHandler.getClass()
.getClassLoader()
.getResourceAsStream("com/package/props/database.properties");
p.load(in);
catch(IOException e){
e.printStackTrace(System.err);
}
I'm betting you aren't pointing at the correct location. Make sure you're properties file is in the correct place. Using that code, I believe it is looking for ${CURRENT_WORKING_DIR}/database.properties, which is the case of a web app in eclipse is WEB-INF/classes (i think).
You should instead be using the more portable java.util.Properties#load(InputStream) with the result of javax.servlet.ServletContext#getResourceAsStream(String).
Try to give absolute path or relative path to the proprty file, also check this propery file path has been add to source folders or not, if not it will not be copied to your classes folder. (Right cclick on project , check java build path under source tab.
You should have .properties file in same package as class that is using it.
Or better, read properties file with getResourceAsStream method (otherwise you can have some problem later when you'll have file in .war archive).
InputStream inputStream =
getClass().getClassLoader().getResourceAsStream("database.properties");

How to create a folder in eclipse for storing serialized objects?

I want to serialize some objects in my Java code. I don't want to put it in some random folder on the hard drive. I want it to be inside A FOLDER in my eclipse project folder. How do I make this folder and store my objects in it ?
Is this a good practice ? Will there be a problem if I try to make a self-contained JAR out of this project ?
Below source code shows how to create subfolder in current directory:
import java.io.File;
public class SourceCodeProgram {
public static void main(String argv[]) throws Exception {
File currentFolder = new File(".");
File workingFolder = new File(currentFolder, "serialized");
if (!workingFolder.exists()) {
workingFolder.mkdir();
}
System.out.println(workingFolder.getAbsolutePath());
}
}
When you run this source code and refresh Eclipse project you should see serialized directory in Eclipse project structure. Now you can use it and store all files in it.
In my app, when I want to store some data in hard drive, I always use user recommendation. I create application.properties file which contains key:
working.folder=/example/app-name
App reads this file at the start and creates this folder if it needs it. Second solution can be "app parameter". When I need only one or two parameters from users I read it from command line. For example user run my app using that command:
java -jar app.jar -dir /example/app-name
When user do not provide any folder I use default folder - current directory.
helpful links:
How to get Current Directory through File.
Getting the Current Working Directory in Java.
List item.
args4j.
Reading Properties file in Java
It depends what information those serializable objects have.
Also if you want to have a folder inside your codebase (but deployed as a folder only), you can write code, to write or read files:
URL dir_url = ClassLoader.getSystemResource(dir_path);
// Turn the resource into a File object
File dir = new File(dir_url.toURI());
// List the directory
String files = dir.list()
Note directory should be in classpath.
Steps:
Right click your project's folder in the Package Explorer
Locate the "New" menu item and hover it
Locate "Folder" in the opened menu and click it
Give your folder a name
Click the "Finish" button at the bottom
This will create a folder that should be accessible from your working directory when running from within eclipse.
It is a bad idea to fiddle with files that are within the JAR file during runtime. Imagine a scenario when there are two or more JVMs running the same JAR, this will also mean they work with the same files and reading/writing to those files may cause collisions. You would generally want to separate those files from each other.
So unless those files are read-only, you should not include them in your JAR (otherwise it is fine)
Aren't you better off writing to the user directory, e.g. in a subfolder like .myApp/?
You would do something like this to set up/initialize the directory:
File userDir = new File(System.getProperty("user.home"));
File storageDir = new File(userDir, ".myApp");
if (!storageDir.exists())
storageDir.mkdir();
// store your file in storageDir
Have a look here to find out where userDir is usually located (though you don't necessarily need to care).
If you launch your program in Eclipse, then by default the current working directory of the process will be the project's root directory. Then you can initialize and use a directory named serialized in your project's root like this:
File serializedDir = new File("serialized");
if (!serializedDir.exists()) {
serializedDir.mkdir();
}
Relative paths in your code will be relative the working directory, which is the project's root by default. You can change the default working directory in the launcher configuration.
It depends on your project whether this is a good solution or not. If you don't want/need to share the serialized objects with others then I see nothing wrong with this.
When using the Export function of Eclipse to create a jar from the project, keep in mind that the folder will be selected by default. You have to explicitly deselect it to exclude from the jar. (In any case, it's better to use Maven or Ant for generating jars instead of Eclipse, which you only have to configure once, so no need to worry of the directory getting included by accident.)
You probably also want to exclude the directory from version control.
In order to do this you need two things:
A) Access/Create the specific folder
B) Actually serialize your objects and save them to disk.
For A) this is certainly answered by the other answers here which show how to:
1) Check if folder exists.
2) Create the folder if it does not exist.
Additionally, projects launched in eclipse have as the working directory the eclipse project folder.
For B) you need to serialize your objects using the FileOutputStream .
See http://www.tutorialspoint.com/java/java_serialization.htm .
You can either serialize each object into a separate file, or create one class with an ArrayList (or some other data structure) that contains references to all the objects.
Below a sample Class doing just what you asked using Static Methods as I didn't want to have to instantiate an object. Also, you need to press F5 in your eclipse project to refresh the package explorer and view the new folder and files.
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
public class CreateDirAndSerialize {
public static void main(String args[])
{
ArrayList<String> sampleString = new ArrayList<String> ();
sampleString.add("Test1");
sampleString.add("Test2");
sampleString.add("Test2");
//Get the directory
File directory = getSerializedDirectory();
writeObjects(directory, sampleString);
}
public static void writeObjects(File directory, Object object)
{
try
{
FileOutputStream fileOut =
new FileOutputStream(directory+"//serializedData");
ObjectOutputStream out =
new ObjectOutputStream(fileOut);
out.writeObject(object);
out.close();
fileOut.close();
}catch(IOException i)
{
i.printStackTrace();
}
}
public static File getSerializedDirectory()
{
File serializedDir = new File("serialized");
if (!serializedDir.exists()) {
serializedDir.mkdir();
}
return serializedDir;
}
}
As the question referred to projects within eclipse, the above is for code within an eclipse project. If you want to interact with Eclipse itself, we are talking about eclipse plugin development which is another story entirely so you need to specify that.
Finally, you can also create a custom class holding any variables you want and instantiate a singleton object for containing all your other objects. There are however some limitations when serializing objects, e.g. :
- Object references with static modifier are not serializable.
See this for some rules/tips for some serializable: http://www.xyzws.com/Javafaq/what-are-rules-of-serialization-in-java/208
You can ignore Eclipse and create the directory (and files in it) programmatically, or manually.
Then, refresh your project explorer view in Eclipse, and voila, the directory and files are part of the view.

files no longer readable

I have a Java project which has this file structure (shown in Eclipse):
ProjectName
+- Deployment Descriptor: ProjectName
¦- Java Resources:src
¦- Package1
-MyClass.java
¦- FileFolder
-MyFile.txt
And so far from myClass I'm able to read MyFile.txt using:
try
{
reader = new BufferedReader(new FileReader(new File("FileFolder/MyFile.txt")));
while((line=reader.readLine())!=null)
{
line=line.trim();
myVector.add(line);
}
reader.close();
}
catch(Exception e)
{
e.printStackTrace();
}
But when I put Package1 into a Dynamic Web Project AND the FileFolder folder in root, the file is no longer found.
Does anyone know how to read the file?
Thanks in advance!
Dynamic Web Projects generate WAR files.
The server may or may not expand the WAR file back to a file system structure.
You're best off using the Class or ClassLoader .getResourceAsStream("/FileFolder/MyFile.txt") which can read files from JAR/WAR files, and returns an InputStream.
Example:
reader = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream("/FileFolder/MyFile.txt")));
Edit: If this is from a Servlet, consider using gawi's answer instead.
Edit 2: If this is in a static method, you'll need to use MyClass.class instead of this.getClass(), where MyClass is the class name.
You are opening a file using a path relative to the current working directory. That's not likely to work on a web app container because the current working directory will not be the root of your application.
Furthermore, you file might not be on the file system but rather in a WAR file.
The proper way to open a file in a webapp is to use the ServletContext.getResourceAsStream() method.

Using external properties files in weblogic

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());
}

Categories