Folder Destination - Upload Files - java

I have a program which permits to upload a file from somewhere into another place. This another place is the path that will be on database. Where should I upload this file:
Into c://?
Into projectSomething/ (I´m working with glassfish and in this folder it saves on C:\Users\Alvaro\Documents\glassfish-4.0\glassfish\domains\domain1\config)
Into projectSomething/src/

Answers to such questions are always (at least partially) opinion based which is bad on SO. But I'll try to give you what is considered as good practice.
As you speak of glassfish, I suppose it is a web application. For evident security reasons, you should never allow uploaded files where you could have any of your application files. You should also think that some servlet containers or Java EE servlet can display an application without exploding the war. It is clear that in such cases, you won't be able to write anything under your project root!
So where can you put it? IMHO, the best is to see that as a deployment detail and configure it in a property file, a java system property or in a environment variable and clearly identify that in your documentation. That way it is no longer your problem as a programmer. You will be able to deploy it under windows or linux (where C:/ does not exists) under a special directory under your project root if it is guaranteed that the war will be exploded and the application will have appropriate permissions on that directory.

Related

Is Apache Tomcat meant to be one install per hosted application?

I'm trying to understand the model that Apache Tomcat adheres to, and the documentation apparently doesn't make sense to me.
As I understand it, Tomcat is a server for hosting a wide variety of services - so it's pretty generic. I've got this application that I'm trying to understand how to host, and its main method of deployment appears to be as a Tomcat-hosted web service - the application is called Camunda (its on github). After going through the docs for Camunda, my Tomcat directory becomes absolutely filled with Camunda-related jars, and config files, etc. The docs say to just plop everything right into the Tomcat lib folder, conf folders, etc.
Most of my experience with other "platform" / "service" style host applications has been that the application itself, in this case Tomcat, stays pretty untouched in its own directory. Through config files, etc, it knows how to host whatever it needs to host.
In the case of Tomcat, it seems that it's customary to basically "pollute" the Tomcat dir with a bunch of libs for the hosted content?
This is why I made the title "is Tomcat meant to be one install per application", because for all intents and purposes once you host something in Tomcat the directory becomes so coupled with that something that the Tomcat directory IS that something.
Is this normal? Just looking for some clarification in perhaps other terms that the docs put it, because the docs don't seem to be very clear to me.
Here is a link to the install process that I am following and referring to: https://docs.camunda.org/manual/latest/installation/full/tomcat/manual/
It's been a while since I've used Tomcat, but not only is it not one-install-per-application, it's not even one-install-per-virtual-host.
Tomcat is (amongst other things) a servlet container. The directory layout and such for servlets was standardized in the Java Servlet Specification v2.2. You can download the latest servlet spec here.
The docs say to just plop everything right into the Tomcat lib folder, conf folders, etc.
Hopefully they're talking about the ones in a .war file or similar, or shared libs in the shared locations. You can put shared libraries in a location where they can be reused across applications (or even virtual hosts), which was probably useful back when disk space was more expensive, but these days I assume most people put the libs for an app in the /WEB-INF/lib directory in the application's .war file.
This page talks about the "directory" layout of a .war file (which is basically a .jar with a particular structure).
It's true that typically .war files are expanded into subdirectories of the Tomcat installation directory, but as indicated in the answer that Dan_Maff linked to in a comment, you can modify the server.xml file to have it look elsewhere instead.
You can install a webapp called Manager that helps with installing, activating, deactivating, and managing web apps via .war files. (There's also a Host Manager for managing virtual hosts.)
All that said, you certainly could do one application per Tomcat install if you wanted. You'd need a reverse proxy in front of it (Apache, Nginx, etc.) so the same port (e.g., 80) could be used for the external URL of the various applications, and you'd need to assign each Tomcat install its own internal port for the reverse proxy to talk to.

Is it possible to import JNDI context.xml file from file system into Spring application?

We have a huge enterprise application which has a lot of JNDI entries written inside context.xml file. Currently the context.xml file is kept inside META-INF folder of our application. We need to move it out of the application and the server so that we can modify the JNDI entries whenever needed. We cannot keep it anywhere inside tomcat root folder, as we are using an image file to start the server and we wont be able to access the files inside server.
So I would like to know if it is possible to import the JNDI context file from the file system using spring ? If not spring, do we have any other alternatives to get this done ? I have been researching for 2 days and haven't found a solution yet.
EDIT:
Yes, I accept all these answers and that's the way we have been doing it all these years. Either keep the context.xml in the meta-inf folder inside the application or keep it in server conf directory or place it under conf/catalina/localhost/warfilename.xml. All these approaches work. But now we are doing a research on whether it is possible to have the xml file outside of the server in our local file system and have either tomcat or our application to import it. Please let me know if this is possible. It's a kind of research we are doing.
The reason being, we will sell our products to a lot of customers and we have our product bundled as an image file. For every customer we cannot create an image file separately. So we are just trying to move the context.xml file outside of our image and keep it configurable outside our application or server, so that we can modify the jndi entries when we install our product in customer's machine.
Please let me know if the question is still not clear. I really thank you for your help.
Thanks,
Sanjay
I don't understand what you're trying to do.
JNDI is a naming and directory lookup service for the server side. Clients should not be modifying those settings.
The context.xml has to be in the Tomcat /conf folder. No question about that.
I'm assuming "client" means a user interface that's talking to the server side.
If "client" means "other applications that are running on a single Tomcat instance, then that is even more true. Why should one client be able to modify a value that others use?
Spring has JNDI object factories. Those are how Spring would use JNDI.
Maybe the reason you can't find anything telling you how to do it is that no one should be doing such a thing.
It's still not clear what requirements you are imagining. Please clarify and I'll edit.

Where does WebSphere Liberty Profile Extract Applications?

I'm using WebSphere Liberty Profile. Nothing I do seems to be making it reload its applications (see my related question here: https://stackoverflow.com/questions/28157860/websphere-liberty-profile-application-not-reloading)
A coworker suggested that perhaps WebSphere Liberty Profile expands the contents of the war somewhere and works with that instead of using the actual war. So since it's finding the already expanded contents, it's not even opening the new war. Is it the case that WebSphere Liberty Profile extracts the war somewhere, and if so, where?
I found this answer for the equivalent question in ordinary WebSphere. Can anyone provide an answer that's specific to WebSphere Liberty Profile?
Liberty profile does not currently extract the .war anywhere. It does extract nested JARs for the purposes of class loading to an internal directory (servers/yourServer/workarea/.../somewhere/); the specific directory will vary and the presence/contents shouldn't be relied upon.
I thought of this directory for your other question, but I didn't mention it since it's internal, it shouldn't matter for non-JAR files, and JAR files containing properties files should get reextracted as needed. You could try starting the server with the --clean option just to be sure. If that happens to fix the problem, it is probably a product defect (timestamp miscomparison or something?), so perhaps zip/tar your server directory first (or config and output directories if they're separate) to provide to IBM support when opening a PMR.
Alternatively, you could just point the server at an expanded .war/ directory since the server will (partially) expand it to a private location anyway if you don't.

Making an open source Java webapp easy to install and deploy on Tomcat, Jetty etc

I'm distributing a simple Java webapp as open source. The webapp needs to be configured before it can be run – a configuration file needs to be created, and the location of that configuration file needs to be made known to the webapp as a parameter in web.xml.
Now my question is how to best package and distribute the webapp in order to make it easy to install, and how to describe that installation process in the documentation. The options I can think of are:
Distribute the webapp as a WAR archive. Recommend that users deploy the WAR into their Tomcat/Jetty/whatever, then drop their configuration file into /webapps/myapp/WEB-INF, and modify /webapps/myapp/WEB-INF/web.xml accordingly
Distribute the webapp as source. Recommend that users should drop their configuration file into the /src/main/webapp/WEB-INF folder, then modify their /src/main/webapp/WEB-INF/web.xml accordingly, then build a WAR using Ant or Maven, and deploy that into their servlet container.
There are probably other options that I can't think of.
What setup is likely to be most convenient to users that need to install, configure and deploy the webapp?
Edit: I should add that the configuration file isn't just a few lines – it's a large file that contains a database schema and other stuff and is potentially generated using an external editor; so just providing good defaults isn't an option.
Externalize this configuration and maybe provide some default values. If you make a new version of your app, everybody will have to remember to back-up that configuration file, then redeploy and then copy back that file--> this is a nightmare.
There are many ways to put that configuration somewhere else. You can use Java Preferences for example.
I would say the WAR, although not requiring the configuration would likely be more convenient :)
What is it, loosely, that must be configured such that there isn't a sensible default value for everyone? URL string?
Providing an answer of my own, after more reading on the issue: JNDI seems to be the “official”, although somewhat heavyweight, way of solving this. With JNDI, a configuration option (like the location of the full config file I need) can be declared in the web.xml, and its actual value can be set in a per-webapp context.xml that lives in the /webapps directory of Tomcat (or the /contexts directory of Jetty). This setup has a bunch of advantages:
The big configuration file can live outside of the servlet container and webapp
The webapp can be updated without danger of losing the configuration
The distributed war doesn't need to be modified or rebuilt
Downside: It's sort of complicated, requires messing around with XML, and configuring JNDI on Tomcat works differently from Jetty (requiring twice as much documentation).
Maybe use a system property for the config file location. Can easily be passed on the command line as -Dorg.example.config.file=/foo/bar, in startup scripts or in Java code. I think I've seen some tools, e.g. logging frameworks, use system properties for similar things in webapps.

Java EE EAR shared location of read/write resources within clustered environment

Within a Java EE environment (happens to be WAS 6.1 but could be any application server) I need to place a XML file, which is a configuration file, so that I can read and write to it.
This needs to be available in a clustered environment so I am looking at using the class path to load the file.
I am thinking I can store this file in the EAR root, reference it in the manifest and then load and save it.
I have tried this approach by having my file in a JAR and making this available via the MANIFES and I can load the config file from the class path no problem using the following.
this.getClass().getClassLoader().getResourceAsStream("configFileName");
That loads the file that is in the JAR, which is fantastic. But if I want to edit this file, programmatically, I cannot access the JAR files location (the EAR root) it returns me an interpreted path like this:
/usr/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/localhostNode01Cell/MyApp.ear/MyApp.war/TB_config.jar
That is not the correct location of the JAR the correct location is at MyApp.ear.
So the question is: how can I access and update (copy contents, create new, save, delete old) the JAR with my config file.
Or should I put the config file somewhere else?
What is the standard Java EE to make files that need read/write access available to WARs on a cluster?
Ok I have built a solution for this. It is more WebSphere based (our platform) but it is J2EE and I am suprised it was not mentioned. Basically I have used JMX to synchronise the nodes. The files are stored, and saved to, the deployment manager the nodes are then resynchronised using JMX calls and then the engines withing the applicaitons are restarted by calling servlets within the applications.
It works a dream
So #stacker, nodes are managed and the manager distributes files to the nodes.
The problem that you've hit is not unique. A lot of Java EE programmers can struggle with providing a "configurable" property file to administrators of a cluster. And the solution that you've chosen, well, has its limitations.
The problem with embedding a config file inside a JAR, is absolute path or the physical path of the file, in case you need to update it. If your container will not explode your EAR and WAR files, then placing the config file alongside the code is a bad idea - the administrator will have to deploy a newer version of the EAR/WAR/JAR. That is unless, of course, you can configure the container to explode the artifacts - WebLogic Server does this, I'm not sure about WAS.
There are several ways to resolve this problem:
Store the config file in a SAN that is accessible to all the nodes in the cluster via a 'canonical' path. That way, you could locate the file from any node in the cluster and update it. Remind yourself to restrict access to this directory. Although this sounds simple, it need not be - Java objects might have to be 'flushed' across nodes, once the configuration file has been updated. Moreover, you might have to cater to the scenario where property files can get edited outside the application.
Use a database. Much simpler and almost hasslefree, except that the Java objects might have to be flushed again.
Use a MBean. As good as a database, except that I haven't known a lot of people vouching for the MBean support in WAS. Also, I'm not really sure if object states can go haywire across a cluster, in this case.
You cannot write to an ear file, you should place the XML file in the DB as a text lob (large object).
Actually, as I am using WebSphere, it appears I can use the dynamic cache provided by the WebSphere deployment manager. The last chapter in the link below dicusses the use of the Dynamic Cache providing a shared object in a cluster. The configuration file is XML that is parsed as such by the engine (into a Document object) of the application and so is a Java object, thus it can be placed into the DistributedMap.
Looks like a clean solution. Thanks all for reading and your replies.
http://www.ibm.com/developerworks/websphere/library/techarticles/0606_zhou/0606_zhou.html

Categories

Resources