I have recently started on Java EE and having a tough time understanding it. I have read some answers here on SO but I still feel like there are some gaps in my understading. Basically, Java EE is a specification and application servers like TOMCAT, Glassfish etc., have the concrete implementations. Also, anyone can provide implementation for EE.
So, I have downloaded javax.sevlet-api-4.0.1-sources.jar from Maven repo and I can see that they are just Interfaces and I assume we just use them to build the project?
In tomcat lib folder there is a servlet-api.jar. is this the tomcat implementation of Servlet? and if it is, then is it possible to replace it with another servlet version implementation?
Now, Hibernate is the implementation of Persistence API. if i want to use Hibernate with Tomcat. I just need to add the Hibernate related jars to my application and can use them for both build and run? without actually getting the contract classes.
You need the servlet-api jar file when compiling your code, because that's where e.g. HttpServletRequest is. You don't need to include that jar with your application, because it is provided already by the Servlet Container you deploy your war file to, e.g. Tomcat.
With Tomcat, the implementation of the various servlet classes are in catalina.jar, at least for Tomcat 9, e.g. ApplicationHttpRequest is the class implementing HttpServletRequest. You don't need this to compile your code.
To be accurate, Tomcat is not a fully fledged JavaEE container, it only handles part of the JavaEE spec (mainly servlet, jsp, jndi and a few others).
And as Andreas wrote you need serlvet-api.jar to compile your code (otherwise HttpSerlvetRequest will miss), but as tomcat already provides it (as an interface) as well as an actual implementation, you should add it as a "provided" dependency in your maven file.
Related
Those days everybody talks about microservices and containerless deployments using fat-jars, and framework like Dropwizard or Springboot support you with that. With all the EE components available as separate implementations it should be possible to assemble your own jar of the required componentes (i.e. Weld, Jersey, Jetty).
When using Java EE based CDI, there is this concept of BDA (Bean Deplyoment Archive), that defines a set of CDI-enabled Beans bundled in jar, together with a beans.xml containing some additional information for the BDA, like interceptors.
How do I combine those BDAs into a single uber-jar without loosing the information of the beans.xml? The maven jar-with-dependencies just copies all files into one, overriding the previous file (or keeping the first one, don't know exactly).
Is the concept of a fat-jar compatible with EE CDI at all? Won't some CDI semantics get lost when being all merged into one BDA, i.e. scope of Alternatives.
Here's a tip from the weld guys http://weld.cdi-spec.org/documentation/#5
Basically,make sure you aggregate your extensions and include a valid beans.xml
I want to add pluggable jar i.e. the jar with web-fragment.xml after server is up-and-running. and perform the scanning of this jar and initialize servlet components defined in web-fragment.xml of newly added jar.
If this is not possible please explain the reason.
Each Java EE application is atomic. It is deployed and undeployed entirely. You can't change application without redeploy. So it is not possible.
Correct solution is differ. You should deploy independent application and provide pluggable interfaces between main application and such plugins. Technical details are depends from situation. E.g. JSF has resource-handler. You can write special class (need be registered in faces-config.xml) for loading JSF pages from nonstandard place.
Do some implemented OSGi frameworks allow me to bundle css styles and javascript as well?
Or i have to use other approaches to do this?
One way is to create a WAB (Web Application Bundle), it's a war with OSGi manifest which needs a Web-ContextPath attribute, this doesn't necessarily be a war it may also be a jar with a war like structure.
Might want to take a look at the Pax Web Framework (or Karaf wich uses it).
The Pax Web framework provides all that is needed to deploy Servlets/JSPs resources etc. also in a OSGi manner. Yes also as Services via a Whiteboard approach. Another point is Servlet 3 and CDI, all of this is also supported by Pax Web (for CDI you'll also need Pax CDI)
Best take a look at the various samples and the integration tests.
You can have any resource in a jar. This is not the question of OSGi framework, but the question of the technology you would like to use. How will it find the resource in your jar.
E.g.: If you create a WAB, that behaves similar to a WAR.
Although WABs can be used with several OSGi based web server, I personally do not like them as they are monoholitic. There are alternatives to provide resources:
https://github.com/bndtools/aQute/tree/master/aQute.webserver
An implementation by Peter Kriens that allows us to download any files that are placed into the /static/ folder of any bundle. The Servlet is registered on the /static/ path so if you have a file in your bundle at /static/css/mystyle.css, you can access it via http://foo.com/static/css/mystyle.css
https://github.com/everit-org/webresource
Similar solution but this is based on bundle capabilities. The first release is expected in the end of October 2014, but the important logic is already implemented. This library needs OSGi 6.0 and Java 8 since the latest commit that might be a limitation for a while.
JSPs are other question. If you use a WAB and an embedded Servlet container with JSP support, they should work. You can also register the JSP servlet manually into your OSGi container based on the technology you use (e.g.: with whiteboard pattern).
Amdatu has support for this in the Web Resources component. You simply add your static resources to the bundle using the -Include-Resource bnd header and add a few manifest headers to serve the files directly.
An example of this could be the following. This example can be found in the Amdatu Chat example.
Include-Resource: \
app=dist/app
X-Web-Resource-Default-Page: index.html
X-Web-Resource-Version: 1.1
X-Web-Resource: /chat;app
I need understanding about the serlvet-api.jar which is needed to compile a servlet.
I am building a simple servlet, like this:
import javax.servlet.*;
import javax.servlet.http.*;
public class FirstServlet extends HttpServlet {
// Remaining code here
}
I know that we need servlet-api.jar file to compile this simple servlet, like this:
javac -classpath /path/where/jar/is/servlet-api.jar
Now my doubts starts here:
What is servlet-api.jar?
Who provides this jar?
Does each web-container provide this jar e.g., Tomcat, Jboss, glassfish? And does each vendor provide the "same name" to the jar that is needed to build this simple Servlet.
When we download Java EE , is this jar part of download? OR do we get this file as part of web container?
Consider this situation:
Suppose we compile / build the simple servlet using Tomcat (i.e tomcat's version of jar needed to build the servlet) and create a .war file. Can we then deploy the war in some other vendor container?
What is it?
The servlet-api jar is a library which contains the interfaces and classes of the Servlet API specification. The servlet-api jar contains only the interface (the API) of the Servlet Specification, so you can use it to develop your web application.
Where can you get it?
It is provided at the link below:
http://download.oracle.com/otndocs/jcp/servlet-3.0-fr-eval-oth-JSpec/
Where it is contained/bundled
Servlet-api.jar is part of the Java EE download so you can develop your web applications (you could not compile your FirstServlet class if the Java EE would not contain it).
Servlet containers (like Tomcat, JBoss, GlassFish etc.) also contain the servlet-api.jar else they would not be able to run your web application, and moreover they also contain the implementation of the interfaces that are part of the Servlet API.
The name is not always the same though, and it might not even exist as a separate jar, the Servlet API classes might be bundled in another jar.
You can however download a separate jar file containing only the Servlet API if you just want to develop a web application for a Servlet container, or if you want to create/write your own Servlet API implementation. Look at here:
http://download.oracle.com/otndocs/jcp/servlet-3.0-fr-eval-oth-JSpec/
Portability
You can compile your web application if you have the Servlet API, no matter where it comes from. After you compiled your web app, you can optionally pack it into a WAR file (WAR=Web ARchive) which is simply a zip file containing your static files, your compiled java classes and configuration files like web.xml etc. And you will be able to run your compiled web application in any Servlet containers (but read forward).
So answer to your question #5 is:
There are multiple versions of the Servlet API, and there are more to the Java EE platform than just the Servlet API (e.g. Enterprise Java Beans). But it's safe to say that if you only use the Servlet API, all Servlet containers that implement that version of the Servlet API will be able to run your web application.
The configuration files of the different web applications might differ though (which is outside of the Servlet API scope), so you should always check the documentation of the target web application.
What is servlet-api.jar?
It is a jar that provides the necessary interfaces/classes to write Servlets.
Who provides this jar?
Any servlet container such as Jetty or Tomcat and any Java EE compliant application server like JBoss/Wildfly, GlassFish, IBM WebSphere, Oracle WebLogic, etc.
Does each web-container provide this jar e.g., Tomcat, Jboss, glassfish? And does each vendor provide the "same name" to the jar that is needed to build this simple Servlet.
Yes for the servlet api because it is a set of interfaces, which enables programming to interfaces rather than class implementations so we avoid programming to a specific application server. The name of the jar containing the implementation must not have part of this name in common.
When we download Java EE , is this jar part of download? OR do we get this file as part of web container?
Java EE download available in Oracle is just GlassFish. This is covered previously.
Suppose we compile / build the simple servlet using Tomcat (i.e tomcat's version of jar needed to build the servlet) and create a .war file. Can we then deploy the war in some other vendor container?
As long as you don't use a Tomcat specific class, library or feature, then yes, there would be no problem. Otherwise, no.
It is the server container vendor which needs to provide this servlet-api you can find it in this directory tree C:\Program Files\Apache Software Foundation\Tomcat 6.0\lib (it depends on your container download location). And of course it is provided by other containers.
A lot of things can easily be checked based on POM files.
For example, Tomcat Catalina has a reference to tomcat-servlet-api(newer version of org.apache.tomcat:servlet-api)
Notice also, and it can cause some confusion when investigating dependencies trees, that Tomcat Embed doesn't use any servlet-api jar at all and instead just specifies Servlet API contract inside itself.
I made search on subject, but didn't find anything easy to understand...
We have a tomcat (v5.5). There is many webapp deployed on it. Each webapp has all librairies in the WEB-INF/lib directory. So there is a lot of duplication.
A classic library (XXX_API) was created in order to organize some common methods. So this librairy is added in each webapp to compile but not deployed with them. This librairy is deployed in shared directory of Tomcat.
We tried to integrate some DAO using JdbcTemplate of Spring 3.1.1 in the common librairy.
So we had to deploy Spring librairies in shared directory in order to deploy our XXX_API.
Now, we can't launch all applications.
Some of them crashed with these exception : java.lang.IllegalArgumentException. Class org.springframework.jdbc.config.JdbcNamespaceHandler does not implement the NamespaceHandler interface.
For information, they are developped with Spring 2.0.6 :(
The problem seems to be localized in the applicationContext.xml.
So, here my questions :
how is working the shared directory of Tomcat ?
Is it loaded in priority compared to the lib directory of the web app ?
Is just a pb about namespace declared in applicationContext.xml ?
Is it possible to have both spring versions ?
Thank you.
What you are really asking is how the classloaders load, in what sequence, etc. This page explains all of the classloaders that are involved in a webapp's execution inside of the tomcat container quite well. It tells where they look for classes, in what sequence, and which classes can be seen by each webapp as well as the container itself. Note, changes to this are significant across tomcat versions.
http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html
The main use that i've seen for the shared lib folder is for things like jdbc drivers, jta transaction managers and other infrastructure like things that:
The container needs to have available (in the case of jdbc and jta, to create jndi datasources and the jta user transaction)
Are environment specific, like the jdbc driver, when you are going to use the OCI version of the oracle driver. In this case, you have to match the ojdbc.jar file with the version of the native oracle client library installed on that machine. Another example would be jms connectors.
Anything that uses native libraries, as loading that jar multiple times would cause issues when it tried to load the native library a second time.
I wouldn't go putting actual app libraries like spring in the shared lib folder.
Probably because one class is loaded by app classloader, another by shared classloader.
Save yourself the trouble, don't use shared directory. What for? To save some disk space?
So, i have deleted all spring jars in each web application. I imported the spring lib (3.1.1) present in shared directory. And i unchecked them (under netbeans) to not have them in the build.
I even changed the declaration in web.xml, applicationContext.xml and Spring Servlet in order to be standardized with servlet v2.5.
All seems to be fine now...