i'm trying to get the absolute path of my eclipse project :
so i write this;
File file= new File("");
System.out.println(file.getCanonicalPath());
projectPath=file.getCanonicalPath();
so it gives me the right path when i execute it in a class as java application C:\Documents and Settings\Administrateur\Bureau\ready code\JavaServerFacesProject
But when i try to use it in my web application it gives this :
C:\Documents and Settings\Administrateur\Bureau\eclipse\eclipse
So any idea how to do it
Many thanks
Reading a file from a web application is a classical pitfall, whenever you do this you will suffer.
Web apps (especially Java EE) are not thought out to use the file-system for read/write operation, they rely on the fact that the container (in your case Tomcat) knows how to get the needed resources.
So the basic advice is : don't do it.
But since I basically hate this kind of answers I will give you some advice.
Never use the working directory
You never know where your working directory is, and, more often then not, in any production system, the web-app has no right to write on the working directory.
For example, if you deploy your webapp to a tomcat server, run as a service on a windows machine, you'll find that your working directory is \Windows\System32
You really don't want to write some uploaded files there for example...
You have a few option, what I prefer is to set a path into the web-xml and possibly override it from server configuration (using context).
Second option, even better is, to save a path into a db-table accessed by the web app.
ex:
in the web.xml you set
<context-param>
<description>Uploaded files directory</description>
<param-name>file-storage</param-name>
<param-value>c:\app\storage\uploaded</param-value>
</context-param>
Then in the you server.xml (or you could use the context dir and place there a file with the following code) you override this setting in context.
<Context
<Parameter
name="file-storage"
value="E:\app\storage\uploaded"
type="java.lang.String"
override="false" />
</Context>
Check tomcat documentation
Third option, in the slightly happier situation, you want to write just some temporary file, there is the webapp working dir accessible as a servlet context param named :
javax.servlet.context.tempdir
If I where you I would go for the database table.
All this complexity is because you can have multiple instance of the same app on different instances of tomcat, even on different machines, and even different web application into the same instance, so there is no easy way to make a 'relative' path is all situations.
Most web-app resolve to serialize data on db (using lobs or similar objects), whenever there is such necessity, or to rely on some kind of service (FTP, cifs, nfs ...).
In Eclipse, you can set a Working Directory for your project in the Run Configurations dialog.
Have you tried setting a non-default one there?
(If you cannot set anything, you could try the JVM option suggested here: https://stackoverflow.com/a/7838900/1143126 )
Related
Java webapps provide a convenient way to make them run: It’s suficcient to drop the jar file into tomcat‘s webapps folder or upload it using the tomcat manager. If the jar file is named foo123.jar, the web application is soon accessible under http://<host>:8080/foo123/. However, in the majority of cases, there is a problem with the configuration: It’s a good practice to store data in a database, but where can I store the database connection parameters? Usually you have to adapt some server.xml or web.xml or other configuration file to put it there, but this hinders making use of the automatic deployment for such an application.
A “simple to use” web application should request its required configuration on the first run, like a “setup” screen, and then keep it in some place where it survives a restart of the servlet container. Of course, for database connection parameters, storing them in the database is not an option.
Following the specs, the servlet container has to provide a directory that a web application has write access to. It can be determined using:
File tempDir =
(File) session.getServletContext().getAttribute("javax.servlet.context.tempdir");
The content of this directory is bound to the ‘servlet context lifecycle’, if I got it right this means it is empty after a server restart. If that is true, it cannot be used for my purpose.
Does anybody know some kind of best practice for that? I don’t want to reinvent the wheel.
In lack of a better solution, I would implement it this way: As I said, if you make use of the easy deployment means described above, the context path is derived from the jar file name. So I could imagine to make use of this for the database connection as well. In simple terms: If the web application foo123 finds a MySQL connection on localhost:3306 (the MySQL default port) and can connect to it with username foo123 and password foo123 and has permissions to access a schema called foo123 it always uses that on restart.
What do you think of that?
You could just use a context.xml file. That will let you store the config files on a server-by-server basis and that means that you'll never have to put that information in the code itself.
This example seems to sum it up rather nicely.
I have a standalone simple java web application with servlets and jsp, say the name is FileDisplay I am access its home page through url - http://localhost:8080/FileDisplay/index.jsp.
What the application essentially does is, retrieves a list of file names(.xml's and .pdf's) with complete path. These files are stored in various external directories, say D:\ABCD, D:\XYZ, D:\PP\2012\08 etc but on the same machine as the web application just on a different drive. So the return list is something like-
D:\ABCD\filename1.xml
D:\ABCD\filename2.xml
D:\ABCD\pdf1.pdf
If I use a simple <a href=""> in the jsp then it doesnt work. in the viewsource it looks like -
file1
I think it is beacause these files are not part of the webapp, so the container doesnt think it is local and hence unable to open them. When I place the mouse pointer over the link, the status bar shows as file:///D:\ABCD\pdf1.pdf. I also tried prefixing file:/// in the href, even then it doesnt work. So I tried a few other things.
One thing I tried is setting the Context in Tomcat's server.xml but even that doesn't seem to work. I am using eclipse to build and deploy and run the tomcat, so the server.xml I modified for this context is one within the eclipse workspace.
The setting I used is -
<Context docBase="D:/ABCD" path="/File-Display/NB" reloadable="true"/>
I have another context set for the main application which is -
<Context docBase="FileDisplay" path="/FileDisplay" reloadable="true" source="org.eclipse.jst.j2ee.server:FileDisplay"/>
What am I doing wrong here?
Does it explain a bit more now?
I think you are on the wrong way.
If you want to provide access to different files distributed in your file system create controller (servlet) that accepts URL, reads appropriate file and writes it to the response output stream.
This way you can control access to your resources, make them secure, etc. You will be able to modify your application easily (e.g. if you change the files location). Etc, etc.
I have a Java webapp running on Tomcat.
At runtime, I create images files that I want to be publicly published on the tomcat server.
1/ How can I get the local URL where I want to copy my image files? (ie /mylocalpath/to/where/i/should/store/the/file/)
2/ How can I know the URL where other machines can access this public files? (ie http://mydomainname/myapp/myresource.png)
Keep the path in a servlet init-param, a JNDI string, or in a property file. (Or whatever is provided by your framework that allows simple configuration.)
Create a servlet/action/controller/etc. that's mapped to a known URL. Either pass in a param with the filename or make the filename part of the URL. Stream the contents of the file back to the user. (Search for "image servlet" for examples.)
Bear in mind the mime type of the file and set the appropriate header. If necessary, check if the requesting user has access to the file in question. (There are several ways to implement that.)
I've figured a much simpler way to do this (which may sound obvious to Tomcat experts but useful to others).
In Tomcat 6 "server.xml" file, I've added this line in the <Host> element :
<Context docBase="/mylocalpath/to/where/i/should/store/the/file" path="/uploads" />
Then, when i create my resource i copy it in this local directory and figure out the public URL pretty easily : http://myserver/uploads/myfilename
Hope it can help other people.
(I even think the context can be defined in a context.xml included in the WAR rather than in Tomcat's global configuration but a global definition was enough for my needs).
In ASP.NET, there is web.config which can hold application-wide settings. Is there a corresponding file (residing outside of the war or jar archive) for a Java EE Servlet?
What I need is some place to point out a configuration file, which currently holds four attributes which in turn, taken together, leads to the database where the rest of the data and configuration is stored. (Server, database, username and password.) These values need to be easy to change without repackaging and redeploying the entire application, hence the configuration file, but hardcoding the path to the configuration file in the application (even if it is as a constant) seems far from optimal.
Any hints? I've tried Google but found very little that seemed relevant - and what I did find appeared hideously over-engineered for my needs.
In ASP.NET, there is web.config which can hold application-wide settings. Is there a corresponding file (residing outside of the war or jar archive) for a Java EE Servlet?
That's the web.xml. You can define settings as <context-param> entries.
<context-param>
<param-name>foo</param-name>
<param-value>bar</param-value>
</context-param>
It's available by ServletContext#getInitParameter(). The ServletContext is in turn available anywhere.
String foo = getServletContext().getInitParameter("foo"); // Contains "bar"
You can also access it by EL.
#{initParam.foo} <!-- prints "bar" -->
What I need is some place to point out a configuration file, which currently holds four attributes which in turn, taken together, leads to the database where the rest of the data and configuration is stored. (Server, database, username and password.) These values need to be easy to change without repackaging and redeploying the entire application, hence the configuration file, but hardcoding the path to the configuration file in the application (even if it is as a constant) seems far from optimal.
As per the emphasis, I'd use a properties file for this particular purpose which is then placed in a path outside the WAR. You just need to add this path to the Java runtime classpath. Then you can obtain it as classpath resource:
Properties properties = new Properties();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("filename.properties"));
// ...
However, with the particular sole purpose to serve a DB connection, you're indeed better off with a servletcontainer-managed datasource as answered by Qwerky. All you possibly would need to configure is then just the datasource name.
If this is a web app then you'd be better served configuring the database connection as a resource on the server, then getting your app to retrieve it using JNDI. Your app server will have documentation on how to do this, its a basic task.
99% of serious web apps do this, the other 1% should.
You can have your application load an arbitrary external file by simply passing the path as a command-line parameter (to the servlet container startup script). Then store the values in the ServletContext
Is it possible to have one appBase served up by multiple context paths in Tomcat?
I have an application base that recently replaced a second application base. My problem is a number of users still access the old context. I would like to serve the, now common, application from a single appBase yet accessed via either context. I took a swing at the low lying fruit and used a symbolic link in the 'webapps' directory... pointing the old context path at the new context path; it works, but feels "cheezy." And I don't like that a database connection pool is created for both contexts ( I would like to minimize the resources for connecting to the database ).
Anyway, if anyone knows of the "proper" way to do this I will greatly appreciate it. I'm using Tomcat 6.0.16 - no apache front end ( I suppose URL rewrite would be nice ).
I'm not sure if the answer above will prevent your webapp from loading twice (as you'd have to deploy it to both new and old context paths), but I could be mistaken. Another option would be to have an extremely simple webapp left in the old context, that does nothing except have one custom servlet filter declared in the web.xml that re-writes all requests to the new path (essentially simulating apache's rewrite rule behaviour). You'd have to write the filter class yourself but it would be quite trivial.
Yes, go into the Tomcat Web Application Manager and scroll down to "Deploy directory or WAR file located on server". For "Context Path (optional):" put in the new context. For "WAR or Directory URL:" put in the same path as your existing app.