I have an application that has the following structure
$TOMCAT_HOME/webapps/myapp
|-css
|-myapp.css
|-js
|-myapp.js
|-forum
|-index.jsp
|-list.jsp
|-users.jsp
|-Articles
|-index.jsp
|-ListArticles.jsp
|-Guestbook
|-viewGuestBook.jsp
|-AddnewEntry.jsp
|-WEB-INF
|-classes
com
|-myapp
|-forum
|-DisplayForum.class
|-ListUsers.class
|-article
|-ArticleList.class
|-AddArticle.class
|-guestbk
|-LoadGuestBook.class
|-ProcessGuestBook.class
The application is delivered as a war file (i.e. myapp.war) and is deployed into the $TOMCAT_HOME/webapps folder. If any of the files change (either the jsp, css, js or java files) i have to always rebuild the whole war file. This means i deploy every single file on every release.
I am wondering if there is a way to deploy specific areas of the application. I am particularly interested if it is possible to separate the application into multiple war files. i.e. myapp.war, articles.war and forum.war. I would like to still access the application via the same context i.e. http://0.0.0.0/myapp even though multiple war files are used.
Using this approach, i will be able to deliver just the module that was affected by the change. Is this at all possible?
I dont mind having to restart the container after each war file is deployed.
I don't remember how you do this is Tomcat exactly, you'll probably have to do some manual configuration (in context.xml or something like that) but I'm fairly certain you can deploy your three applications (.wars) with the following context paths:
myapp.war -> /myapp
articles.war -> /myapp/articles
forum.war -> /myapp/forum
I've found a bit of information specific to Tomcat here:
http://tomcat.apache.org/tomcat-6.0-doc/config/context.html
Specifically:
In individual files (with a ".xml" extension) in the
$CATALINA_BASE/conf/[enginename]/[hostname]/ directory. The name of
the file (less the .xml extension) will be used as the context path.
Multi-level context paths may be defined using #, e.g. foo#bar.xml for
a context path of /foo/bar. The default web application may be defined
by using a file called ROOT.xml.
Alternatively, you may want to do something like:
myapp.war -> / (by calling it ROOT.war)
articles.war -> /articles
forum.war -> /forum
Having said that, keep in mind that if you do this, you'll not be able to have shared state (session information) between the three applications without some effort. For instance, if "forum.war" requires authentication, that authentication information will not be available to myapp.war or articles.war.
Related
I am facing a little strange issue while deploying web service to WAR file.
If I deploy the application via Netbeans IDE it is going under \standalone\deployments directory.
However, if I deploy the war file from Admin Console it is always getting deployed at \standalone\tmp directory.
Please guide on this issue. The deployment should go under \standalone\deployments directory only.
The deployment should go under \standalone\deployments directory only
You are quite not right.
It is not an issue. It is what it is.
standalone/deployment folder stand there only for "hot-deployment" functionality available only with standalone mode.
So, Netbeans uses it. You can do the same just by saving EAR or WAR into standalone/deployment and server will pick it. (default scan interval is 5 sec.)
but Admin console or CLI is only (and standard) way to deploy application on domain. In domain mode deployment folder is not in use and there is no deployment scanner.
Then when you use console it goes common way - deploys as on domain regardless is it domain or standalone server.
Updated / follow-up:
In general it is better to keep .properties file(s) out of deployment, in separate location. It is main idea behind them - to be able to change properties without application rebuilding and redeploying. Usually properties are different in different environments (DEV/UAT/PROD)
So there are 2 most popular solutions:
store properties in different location add that location to class path and access them through ClassLoader.getResourceAsStream() mechanism
store properties in different location, pass that location through system (or -D) variable and access them as file. for JBoss you can place your .properties under configuration directory. there is already JBoss variable. Kind of jboss.config.dir (or such, you can find it in Admin console, I do not have JBoss right now).
But of course sometime it still needed to access resources inside WAR/EAR - in that situation it is pretty much the same as first solution above.
Just be sure your .properties file(s) are accessible through to ClassLoader (in class path) and use them from ClassLoader.getResourceAsStream (or if you use Spring point it as "classpath:" not as "file:".
I am building a webapplication with maven. I want to change the name of the generated warfile to get a different context path.
To clarify misunderstandings: It is not about changing the name during development, it should be possible without touching any code (e.g. for customers). Also it should be possible to deploy those war on different servers (like WildFly, Tomcat etc.).
Example:
Hello.war = Hello.war -> URL: localhost:8080/Hello
stupid.war = stupid.war -> URL: localhost:8080/stupid
How can I achieve this? Is that even possible?
For popular servlet containers (JBoss, Tomcat, Jetty), WAR naming convention can drive context paths. Name of the war becomes the context path if no explicit context path is defined anywhere.
a.war > localhost:8080/a
b.war > localhost:8080/b
The problem then is just to rename the war into different names as per your clients.
https://docs.jboss.org/jbossas/guides/webguide/r2/en/html/ch06.html
https://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Naming
http://www.eclipse.org/jetty/documentation/current/configuring-contexts.html
Overriding the default finalName element within the build element to the desired filename (without extension) may archive what you wish. You will then of course need to take care with versions. eg.
<build>
<finalName>YourName</finalName>
</build>
the easy way to do this is
to rename the file extension.war to .zip and expand it (double-click it)
drag out the web.xml to desktop
make changes to web.xml accordingly
drag the modified web.xml to its original location and replace the original
rename the file extension back to .war
I have created a dynamic web project, and use Apache Tomcat as a server.
In my servlet I'm creating a text file and want to reuse that in a JSP. However they are by default created in the installation folder of Eclipse when I do something as simple as the following:
File f = new file("test.txt").
I don't know why this happens. Is there a way to create the file in the WebContent directory as I want to make that file available for download in my JSP.
Java has a concept of the "current directory". When you start an application via Eclipse, this may indeed point to your installation directory. If you don't specify any path, a file will be created in this current directory. Hence the reason why your test.txt ends up there.
The WebContent directory is a something that is specific to Eclipse. Your code should not depend on putting anything there. You only start your application via Eclipse when you're developing it, not when you're deploying it to a live server.
The content of this directory will become the root of your .war, which is a well known location independent of how you start & deploy you app, BUT you still cannot depend on writing anything to this location at run-time. You might deploy your application as a packaged .war (likely for live deployments) or you may deploy your application unpackaged but then your application server may simply not pick up any changes done at run-time.
What you can do if you are sure your application only runs on a single server is writing the files to a well known location on your file system, such as /tmp, or /var/yourapp/files, etc. The code serving up those files can then pick them up from that location.
If you want to play it 100% safe according to the Java EE rules, you'd store your files on something like an FTP server that has a configurable address. Technically your war could be shipped between nodes on a cluster and requests could end up going to different machines, so depending on a local filesystem wouldn't work then.
Executing this statement this.getServletContext().getRealPath (""), you'll obtain the path where Tomcat WebServer is pointing at at runtime. You could add a folder "MyFolder" and call this statement:
new File(this.getServletContext().getRealPath ("") + "/MyFolder/test.txt");
Anyway, the default path looks something like:
...\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\<NameOfYourProject>
Note that when you create a new file, it won't appear in your immediate workspace (check the .metadata path), unless you change the runtime location tomcat should point at.
I have java webapp under Tomcat with such sample context:
<Context path="reports" docBase="E:\generatedReports"></Context>
On unix attribute docBase different:
<Context path="reports" docBase="/usr/generatedReports"></Context>
Can I have ONE context.xml (for crossplatform and keeping simple build scripts)?
Value of docBase attribute must be parameter managed in other place?
Technically Yes, you can keep one file and parametrize it when building.
The problem with doing this via build scripts is that context.xml sits outside the webapps and is part of the conf, i.e. the Tomcat installation directory.
You ideally want minimum interference with files in the conf folder and so rather than having it as part of the build and released artifacts, I would suggest you version control it as context.xml.windows and context.xml.unix or something similar.
And yourself or your admin should manually change/edit these files ensuring all changes are justified.
Currently when I deploy a war file to Tomcat it can be downloaded from the URL via something like foo.com/myapp.war.
Most places recommend that you put an entry in a .htaccess file to prevent public access to any war files, or failing that an equivalent entry in your Apache config.
Unfortunately, my host does not provide access to the Apache config (although I can access Tomcat confs) and .htaccess files do not work for all Tomcat/Java related hosting environments. Pretty disappointing. They have been rather unhelpful in this respect.
Without resorting to something like "finding another host" (other than this issue they are fine - I'd rather stay here until my app grows too big), is there anything else I can do to prevent public users accessing my war files, yet still allow Tomcat to deploy the apps when it scans them?
For example, is it possible to specify one directory for Tomcat to scan for war files yet have it deploy the war into the public directories?
Thanks.
It is probably better to ask at https://serverfault.com/. It all boils down to how Tomcat is setup.
The vanilla setup will have a folder called webapps under CATALINE_HOME. You put your WAR archives there (they get auto-extracted and deployed). These folders will not be accessible from HTTP (you cannot download WAR archives from some URL like /webapps/my-test.war). These apps in webapps folder are deployed to some context roots. For example an application my-test.war will by default get deployed as yourhost.com/my-test/.
If you can download your WAR archives from foo.com/myapp.war maybe you can check out what does the CATALINA_HOME/webapp/ROOT app is doing. By default this is deployed under the foo.com. Ask from the host the Tomcat configuration files to figure what kind of custom configurations are they using.
You can place your .war files in any location Tomcat has access to. But you will have to tell Tomcat about it, so it picks them up. You can do this by placing a configuration XML file in
<CATALINA_HOME>/conf/Catalina/localhost/myWebapp.xml
There are samples on what to put into that file myWebapp.xml, e. g. here, step "4)". And of course, the official documentation.