ServletContainer reads the user defined servlet class name from web.xml file by converting web.xml file into DOM object. I don't understand how servlet container converts this and where this DOM object (web.xml data) resides inside web-app directory of server?
The Java EE specification mandates a specific directory and packaging structure (war) for web applications so that the web app can be deployed on any servlet container (Tomcat is one of them) without any modifications. Now, each servlet container can unpack it in which ever way it wants and as a developer you no need to worry about it.
Now, Tomcat places all the deployed applications in the \tomact-install-dir\webapps directory. Each web app will be in its own folder with webapp name as thefolder name.
Perhaps this is the first place to take a look at when deploying the first web application. tomcat deployment hierarchy.
web.xml should be placed inside the WEB-INF on your webapp deployment. Some servlet containers allow you to have generic or reusable web.xml files inside their configuration directories but that's not standard AFAIK (It's better for your webapp to be selfcontained most of times)
You shouldn't need to know about the parsing of the XML file since it's all handled by the servlet container under the hood. (Just place it in the right place)
Related
Let's say I have:
foo.war
bar.war
Is it possible that I deploy them both somehow to the same deployment path? E.g., to access it at:
http://localhost/baz
Are the content of the war files merged somehow? How are file conflicts handled (e.g., let's say both of them has an index.jsp file)?
Thx in advnace!
The servlet specification explicitly forbids this. Deployed web applications may not have identical or overlapping context roots. From the Servlet 3.0 specification, section 10.5:
Since the context path of an application determines the URL namespace of the contents of the Web application, Web containers must reject Web applications defining a context path that could cause potential conflicts in this URL namespace. This may occur, for example, by attempting to deploy a second Web application with the same context path.
Yes & no.
I don't think it's possible to somehow merge them into the same file system path within a servlet container like Tomcat (unless you were to write some kind of complicated, intelligent script to do so). For starters, each .war will have a WEB-INF/web.xml file, and each will rely on the contents of its own file to function -- which would win?
But you conceivably could...
Deploy to 2 different contexts (or containers, or hosts), and employ some kind of load balancer (hardware or software) to route some requests to one, other requests to the other.
Use an "overlay" strategy (such as Maven Overlays) to make a second (and final) .war that is a derivative and extension of another .war file
I understand that Servlet 3.0's enhancements have made it possible to display a .jsp from a .jar, based on Can I serve JSPs from inside a JAR in lib, or is there a workaround?
However, I don't seem to be able to connect my View (jsp in jar WEB-INF/lib Tomcat 7 and classic spring MVC context configuration in a War) with the Model and the Controller of my Web App.
Is there a good way to share the dispatcher Servlet, or perhaps create a CustomViewResolver which could scan .jsps included in external JARs, and actually plug my jar into a unique spring context?
With JSP you have the problem of compilation.
So you at least need to precompile them, to have them included. Then it should be possible, since after compilation a JSP is basically a Servlet.
If you would use another view technology like Velocity, Freemarker or JSF based on Facelets, you can very easily use a classpath based ViewResolver.
I am developing a small web application application. The objective is to create one welcome index.html page with Ajax + one servlet to handle ajax requests.
Although I thought I would be fine with a web.xml only, I don't want to deploy to /, but to /MyApp. NetBeans's project properties offers options to set a context path, which helps me deploying to /MyApp. However, it automatically adds a /META-INF/context.xml file, which is a bit confusing.
My questions are:
1) Do I really need a context.xml file do deploy to /MyApp instead of /?
2) If answer to 1) is no, how to accomplish the same with web.xml only?
3) What is exactly context.xml to web.xml?
/META-INF/context.xml is a Tomcat-specific config file. It's used to configure how your app is deployed to Tomcat, including, among other things, the context path at which it exists. Other containers have similar files that can be included in a WAR for container configuration. To answer your questions:
No. The embedded context.xml is only one way to set the context path, and as I indicated, it'll only work in Tomcat. In Tomcat, default behavior is to deploy webapps to a context that has the name of the war file, without the ".war" extension.
You can't set a context path in web.xml. That's your application's deployment descriptor. It configures your application, and the context path is external to your app. It belongs to the server/container you're deploying the app to. Configuring a context path is always done in the container's configuration.
If by "config.xml", you meant "context.xml", then I think I've already answered that. If not, clarify your question.
Is there anyway of configuring tomcat to point more than one context at a webapp?
I need to point these two urls:
http://server.com/abc
http://server.com/def
to a webapp running under the context abc.
Tomcat does not allow direct configuring of multiple <Context> elements to point to the same path.
So your options are either deploying the same web app twice with different Context (Not great idea)
or create a webapp called def that has one custom servlet filter declared in the web.xml that re-writes all requests to abc.
If your requirement is for a production app, I would recommend having an Apache Web Server before the tomcat so that you can do this and more.
I've managed to deploy a .war to the Jboss web container containing and read the pom.properties located under /META-INF/groupid-dir/artifactid-dir/
To access the file I've used the following code inside a JSP in the same war:
ServletContext servletContext = getServletConfig().getServletContext();
InputStream in = servletContext.getResourceAsStream("META-INF/maven/groupid-dir/artifactid-dir/pom.properties");
This works just fine. But I want to be able to dynamically read pom.propertes from ALL .war deployed in the container. Is this possible or do I only have access to the context for the one war holder my jsp?
-mb
Basically, your application is running on the same machine as the JBoss container, so accessing the files on the local filesystem should be possible, much in the same way you're accessing your own .properties file. I'm not familiar with anything that should prevent you from doing this.
If you want to access files within the war file, you'll need to use the java.util.zip package, as war files are of course normal zip files. Just a friendly reminder.
You will likely have to do something tricky like go through the JBoss MBeans. I realize this is vague, but consider looking into that approach. Here is a link on how to get the MBean server from an application within JBoss (add http://) www.jboss.org/community/wiki/FindMBeanServer (Stackoverflow is preventing me from pasting a link). I would imagine that you could find the Jboss Web mbean, peel off all web application mbeans, then ask each one for its classloader, then proceed to do what you already mentioned.
I don't think that reading a zip or using a jboss mbean are the right way.
I don't think it is tricky and you were on the right track by using ServletContext.getResourceAsStream.
You can probably use ServletContext.getResourcePaths, but several times it seems, to identify subdirectories groupid and artifactid.
Something like
servletContext.getResourceAsStream(servletContext.getResourcePaths(
(String) servletContext.getResourcePaths("/META-INF/maven/")
.iterator().next())
.iterator().next() + "pom.properties")
or
servletContext.getResourceAsStream(servletContext.getResourcePaths(
(String) servletContext.getResourcePaths("/META-INF/maven/")
.iterator().next())
.iterator().next() + "pom.xml")
for pom.xml
If the WAR file is exploded as folder , you should be able to use
String basePath=getServletContext().getRealPath("/");
This approach may not work if WAR file is in archive format
You can only look for resources in your current classpath. The normal operation of a web container is to create a specific classpath for each deployed artifact without access to the other artifacts deployed in the container.
This is very important to avoid artifact A which uses foo-1.0.jar to not accidentially use foo-0.9.jar which is deployed with artifact B.
Hence you will need ask the container for help. This in turn mean you need to write container specific code to do so. This will make you vendor dependent - you may not want that.