newbie: modifying application files

Hi all,

I have a small web app, that needs to keep some configurable values and some external files somewhere on the system. I have 2 problems:

1. how do I tell the application where those files are? The app should know, at deployment time, where the user installed those files.

2. how does my web app able to access those files? Aren't there any security contraints?

To solve #1, I was thinking of maybe setting a system property and somehow make it accessible to my app. Does anyone know how to do this?

To solve #2: I have no idea how I specify a file name outside my web app's directory... Let's say I want to create a java.io.File object that writes to some file, how do I do that?

Thanks,

[740 byte] By [sagmama] at [2007-10-2 9:27:18]
# 1
You would normally pass configuration info that applies to the entire webapp via <context-param> elements in web.xml. Your servlets can retrieve the info viagetServletContext().getInitParameter(String paramName);
Gita_Weinera at 2007-7-16 23:33:56 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2

> Hi all,

> I have a small web app, that needs to keep some

> configurable values and some external files somewhere

> on the system. I have 2 problems:

>

> 1. how do I tell the application where those files

> are? The app should know, at deployment time, where

> the user installed those files.

Well, the user shouldn't have free rein over your web server! I'm assuming you'd want to control where the user can install those files (the user installs files on the server?)

You can probably just specify the values in a props file(I'm assuming you'll decide that ahead of time), then just call Properties props= new Properties();

Input Stream is= YourClassName.getResourceAsStream("props.txt");

props.load(is);

>

> 2. how does my web app able to access those files?

> Aren't there any security contraints?

The security constraints are imposed by the SecurityManager on the *server*. If you don't set up a security manager, then your code can basically do whatever it wants.

Now if you want to access files on the *client's* machine, without them actually manually uploading them, that's a bit trickier, and there are definitely security restrictions for that.

>

> To solve #1, I was thinking of maybe setting a system

> property and somehow make it accessible to my app.

> Does anyone know how to do this?

No, you don't need to set up any system properties, just specify it in that props file, and leave it in your classes directory. Of course if the properties change,you probably need to restart the server (it caches the filestream)

>

> To solve #2: I have no idea how I specify a file name

> outside my web app's directory... Let's say I want to

> create a java.io.File object that writes to some

> file, how do I do that?

Easy: you just specify the absolute (I think relative works too) path

File temp =new File("C:\mydir\file");

temp.createNewFile();

Again, this points to the c: drive on the server, not the client's machine. But unless you really have to, it's probably better to keep everything contained in the webapps directory of tomcat.

>

> Thanks,

Hope I answered your questions.

radtad82a at 2007-7-16 23:33:56 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3

...

Properties appProps=new Properties();

appProps.load(this.getClass().getResourceAsStream("/your_file.properties"));

...

Must ensure your_file.properties is in the root of your classpath, that is explicitely under classes directory.

orly_oteroa at 2007-7-16 23:33:56 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

Thanks for the answers.

Let my clarify: my product is composed of a .war file and some files under c:\program files\myproduct - or any other directory - depends on what the user chose at installation time. I want my web app to "know" what directory the user chose, so that it could access the data files. That's it.

You suggest that I put this path inside a .properties file? But that file is inside my .war! How can I change it during install? Isn't there any other way? That's why I thought about a system property or an env entry on the web server: I'll bet you can set it using some web server command line, and then access it via the web app, no?

sagmama at 2007-7-16 23:33:56 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5

Hello,

Have you tried any posted solution?

In my last post I wrote:

...

Properties appProps=new Properties();

appProps.load(this.getClass().getResourceAsStream("/your_file.properties"));

...

Every Java web app should include a classes directory

if you place the properties file inside the this dir. the above code should work.

Hope this help.

orly_oteroa at 2007-7-16 23:33:56 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 6
You have said the files are located where the user specified at install? But if this is a web app then "Users" should not be installing this.. you sound as if you mean this will reside on every users machine?Maybe I misread your post.. but I just wanted to clairify.
gmachamera at 2007-7-16 23:33:56 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 7

user=administrator in my case. i.e. some administrator will install my product on some machine that is also a web server.

So my product will have 2 parts:

1. a web application running under the web server

2. some files under c:\program files\whatever

At DEPLOYMENT time, I need to somehow tell my web app where I placed #2, so that it could access them.

The proposed solution with the .properties file is not suitable because my web app is a .war file.... how am I supposed to change the .properties file (inside the .war file) at DEPLOYMENT time?

sagmama at 2007-7-16 23:33:56 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 8

Normally .war files are deployed using tomcat adminstering pages or resin ones or just pasting the war file under webapps of those application servers and re-starting it.

What information do you need to collect during deployment that your web application cannot determine and use through its interface?

Why are you expecting that an admin is going to let you to copy files under C:\Program Files\...

What about if the OS upon which Java is installed is not Windows(as usually)?

In my case I will never install a "web" application that writes files to /usr/bin or any other system-related directory.

If your properties file collect or contain or store information such as jdbc driver, db user name and password, xml parser, DAO classes implementation names, location for another files, etc., the approach I wrote could be used.

orly_oteroa at 2007-7-16 23:33:56 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 9

My answers:

"What information do you need to collect during deployment that your web application cannot determine and use through its interface?"

The path where the data files are (they were installed separately, by a different installation/product and my web app should know where to find them and read/write them). Think of it as a web app that should provide a web GUI for another product that doesn't have one.

"Why are you expecting that an admin is going to let you to copy files under C:\Program Files\..."

I assume the files are already there (see above).

"What about if the OS upon which Java is installed is not Windows(as usually)?"

It was just an example... it could have been a unix path.

"In my case I will never install a "web" application that writes files to /usr/bin or any other system-related directory."

Where do you store the app's lifetime data (data that is changed during the app's lifetime)? What do you do when it's time to upgrade the web app? how do you keep the old data between deployments?

"If your properties file collect or contain or store information such as jdbc driver, db user name and password, xml parser, DAO classes implementation names, location for another files, etc., the approach I wrote could be used. "

Can you describe how/when this file is set with data? In my case, I don't know the user/pwd before deployment, so I somehow have to write a .properties file during deployment. But where and how do I write it? Can you give an example?

sagmama at 2007-7-16 23:33:56 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 10

Hello all,

Here are my thoughts based on what you have written so far:

I'm assuming that you are writting a generic application to be used for instance with differents DB user/pwd pair, probably using differents DBs products depending on what your client has installed, for instance, in my case, during my free time, I'm writing a kind of ezine builder or online content managment tool through which(to simplify) articles are collected or edited and saved to DB, and when ready to be read by the public, some xml processing is carried out to generate .jsp files(after all, when the articles are ready, they are not going to change that much, and it's better having "static" content than reading them from DB each time a user clicks a link). Since I don't know what DB product is going to be available for me when I had finished the product and I'd decide to post it online, I do give a choice thorugh an admin module to enter jdbc url, etc.(more than that, I'm using Hibernate). This is just an example. My properties file(s) are stored locally to my web application.

If this is the case, you could include a module for administration purposes that doesn't rely on any properties file values at all(at least it does not depend on non-local file path), for instance:

/

...

WEB-INF/

...

admin/

...your protected administration files.

This admin module takes care of collecting properties values based on user input such as jdbc driver name, jdbc driver upload(if necessary), etc., AND web application upgrade. This module is included in your application, so it is not generated by an installer, so you must implement some logic to execute a WIZARD INSIDE this administration module to collect crucial properties values to start using the application, and save those properties values locally to your web application.

If you haven't setted those properties to a file(you haven't run the admin wizard to generate prop file), for instance classes/properties/version-1.properties(this way you can read this file using the approach I have written before, which means it doesn't depend on a file path like /home/..../version-1.properties, AND this could give you some freedom to upgrade to another properties using version-2.properties or whatever you need.), well, if you havent generated this file you could redirect to the admin login page. This could be done(if using struts) in a RequestProcessor subclass, or implementing a Filter.

Another approach that came up to my mind is having the admin module as a web app root application, this means:

/

.... admin files

WEB-INF

These files could run a WIZARD(as mentioned above) to generate the required properties file, BUT this admin application DOES require not to depend on any non-local file path, it will include your client application as:

/

... admin files

WEB-INF(same as last posted so far)

classes

...

yourAPP

...

WEB-INF

classes

...

once your properties are collected they are copied to yourAPP/WEB-INF/classes/properties/yourProperties.file(following this approach, the properties file can be read using the code I have written in other post in this thread without the need of a global files path). Well, once you have generated the required file, you can build and export a .war file from yourAPP directory and all files under it, then that .war file can be deployed with all of its properties already included. But if you require to change properties, it may still require an admin module inside it, as the first approcach I wrote.

Why am I talking about writting properties file and/or any file locally to a web app? Well, I don't know if you are an honest developer or if one of your developers is a malicious one, but in the case you are, are all developers as honest as you?. If a system administrator let developers copy files to /usr/bin, what could prevent from copy .sh files to that location? What the consequences might be?

Just my thoughs,

Regards,

OO

P.S. Sorry about my English

orly_oteroa at 2007-7-16 23:33:56 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 11

Hi and thanks for the answer.

I assure you I'm not doing this for malicious reasons...

Anyway, if I get you correctly, you simply suggest that if the prop file doesn't exist, I pop up some GUI asking for the external path in my case (assuming the logged on user is authorized), and storing it in some .properties file inside the web app, correct?

I just want to make something clear: I cannot MOVE the external files into my app because they are not mine to move. They belong to a different product, to which I am only supposed to provide a web GUI. If I move the files, the product won't work :-)

By the way, realisticly speaking, I need more than the external product's path, and it would be useless to get some poor user to fill all that info. The external product already stores that info in its own platform-specific way (registry, .ini files, etc). Fortunately, this product provides an API to read that configuration! So what I currently do is use JNI to access that API, find out where the product is installed, and many other details and that's it! In order for my web app to find the API, I have to add the API libs to the web server's library path, and place my JNI bridge .jar file in the server's common/lib directory (otherwise, libraries are loaded more than once = exception).

sagmama at 2007-7-16 23:33:56 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 12

OK,

So what's the problem? If you don't need user interaction to read or set the properties and you can read them through an API provided by the application you are building the interface to, Why are you interested in read/write the properties from an installer and not just from your web application?

You could implement classes following ServiceLocator & Singleton patterns, if retrieved properties is NULL, just instantiate the class you have implemented thorugh JNI to find out properties and serialize them to disc(local path to your web-app), any subsequent properties retrieval should return in-memory retrieved Properties or read them from previously stored properties file.

for simplicity:

package utils;

import java.io.*;

import java.util.Properties;

//Singleton pattern implementation.

public class PropertiesUtil{

private static PropertiesUtil pu=null;

private Properties appProps=new Properties();

private PropertiesUtil() throws IOException{

/*Reads container environment variable "application.properties"(NO MORE NEEDED) which points to a properties file.

* 1.) "dao.user.impl" specify the class name's implementation for Users DAO.

* 2.) more class names here.

* 3.) "mail.smtp.host" specify the smtp server address.

* 4.) and so on.

*/

try{

//appProps.load(new FileInputStream(System.getProperty("your_property_name", "")));

appProps.load(this.getClass().getResourceAsStream("/your_properties_file.properties")); //Located in classes.

}

catch(IOException io_e){

//If file not found, instantiate & call class and methods related to JNI calls to find out properties based on provided Application API

//SET appProps

//Serialize appProps.

}

}

public static PropertiesUtil getInstance() throws IOException{

if (pu==null) pu=new PropertiesUtil();

return pu;

}

public Properties getAppProperties(){

return pu.appProps;

}

//... more methods if needed.

}

Any time in your web application:

...

Properties p=PropertiesUtil.getInstance().getProperties();

...

What is wrong with saving .properties file under classes directory?

Regards,OO

orly_oteroa at 2007-7-16 23:33:56 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...