Get ServletContext in EnvironmentPostProcessor - java

I'm trying to get ServletContext in the class which is implementing EnvironmentPostProcessor. ServletContext is required to get the war filename. Based on war file name I get properties from a database and will set to properties to user later in the applications.
I'm not using Embedded Container but WildFly Server
public class ClEnvironment implements EnvironmentPostProcessor, ServletContextAware, ServletContextInitializer
But it's not working.

You can’t get the ServletContext in an EnvironmentPostProcessor. The post-processors are loaded from spring.factories very early in the application’s lifecycle. With an embedded servlet container that happens long before the container has been started and the ServletContext is available.
This may be an XY problem. Perhaps you could ask another question that explains what you are trying to do. There may be another way to do it that does not require access to the ServletContext in an environment post-processor.

Related

ServletContext parameters: are they per instance or per server?

I have a tomcat server running a webapp. In the webapp's startup, I'm setting few context parameters using an implemented class for interface ServletContextListener. The parameter that I am initializing here are a couple of connection objects for a database running on a different machine.
The doubt that i have is whether the connection objects that I created here are one for each instance (since tomcat creates one instance per client request), or one for the entire webapp itself?.
If it is one per webapp, then can the server handle large simultaneous requests (in the order of thousand request per second) to perform the CRUD operations on the database?.
ServletContext is created one per webApp. The server reads the web.xml file from the web app and creates a ServletContext based on the configuration you provide on web.xml. Once created it is shared between the components of the web app. If you have multiple webapp installed on your server, you will have multiple ServletContext - each for the web app.
For reference please have a look here
A webapp has only one instance of ServletContext and the atributes in ServletContext are application scoped.
Regarding you database connection, it's better to use connection pooling (DataSource) instead of adding Connection objects as attributes in ServletContext.
Not sure if you mean this but the requests are handled by Servlets and not ServletContext.
If your setting an attribute on the ServletContext the attribute will be scoped for the entire application.
From the Java EE 7 Spec:
There is one instance object of the ServletContext interface
associated with each Web application deployed into a container.
only one ServletContext is loaded irrespective of the number of requests made.
This is even the advantage of servlets over CGI.
Hope it helps.

Life cycle/length of a DataSource injected with #Resource annotation

I'm far from an expert of the intricacies of Resource Injection, and of indeed DataSources in Java, but I generally understand the process of doing a lookup for a predefined JNDI resource to get a datasource from.
Using Resource Injection as an alternate method, the below syntax works:
#Resource(name="jdbc/Foo")
private javax.sql.DataSource con;
However, I am using this in a servlet and as such wondering, how long this injected connection object's value will exist? Presumably, as it's simply an object within the servlet, it will inject when the servlet is first instantiated and exist for the same duration as the servlet (assuming I don't manually change it). Is this correct? Or does the servlet re-inject the resource everytime the servlet is used?
Thanks
A servlet container only ever creates one instance of your servlet. The IoC container you're using will then instantiate and inject the DataSource, so the value in con will remain the same for the life of your servlet, ie. the life of the application.
As to the underlying connection the DataSource is trying to make will, that's up to your datasource.
it will inject when the servlet is first instantiated and exist for the same duration as the servlet
Correct.
Or does the servlet re-inject the resource everytime the servlet is used?
No, this couldn't be happening because each request is served by a different thread. It wouldn't be good if those threads would modify the fields of the servlet. Request processing methods of the servlet must not modify its fields.
Generally container managed resources are injected using #Resources annotation. And container managed resources live as long as the container is running ( unless your are not manually kill it or any exception happens). Several applications can use the same resource object, provided that they live in the same application server ecosystem (same application server or cluster or server domain). But servlets are managed by your applications and lives within the application's scope as long as your application is running! So in terms of life span, if you compare resources are longer living than servlets.
And yes you are right, if you inject resources to a servlet, the reference of the resource will remain from the creation of the servlet to the end of the servlet's life cycle. The injection is not related with, how you are using the servlet or the resource.
Hope, this answers your question, Thanks!

How to gain access to a ServletContext instance from any method?

Is there any way to get access to the ServletContext from a method without passing the ServletContext as an argument?
I need to have a generic Configuration class that can work on several environments and load the config in a way depending on the environment.
For example, when in a web app, i need to get the configuration from either web.xml or a config file stored in WEB-INF.
But in order to know if the app is running in a web app i need to gain access to the ServletContext somehow.
Any ideas?
Have a class that holds servlet context as static field initilize it from ServletContextListener

Access ServletContext resources in CDI Extension

I'm facing the following situation: I have written a CDI extension, with which I want to programatically register additional beans into the BeanManager. I've already implemented the extension and registered in in the META-INF/services folder. Everything works fine so far and I can trace the container calling this method:
public class TestCdiExtension implements Extension {
public void observeAfterBeanDiscovery(#Observes AfterBeanDiscovery event, BeanManager manager) {
// Code goes here
}
}
My problem now is this: To determine which beans should be registered, I need access to the ServletContext of the current web application in which CDI is running.
I understand that you can use CDI completely without a servlet environment, so there is no hard link. However: How can I do the job of registering additional beans depending on what's in the ServletContext?
Is using an extension the correct way at all? Is there any other (better?) solution of doing this?

What does "Context" in "ServletContext" mean?

Method getServletContextName() returns the name of the "web application". That means, "ServletContext" is nothing but "web application". Ok.
API defines:
a ServletContextListener receives notifications about changes to the servlet context of the web application they are part of.
What does "servlet context" of the "web application" mean? What actually is "Context" in "ServletContext"?
The name is indeed, IMO, very badly chosen.
We must read ServletContext as "the general context of a servlet API based web application".
Whereas we must read ServletConfig (another standard class) as "The config of a servlet".
They should IMO have named ServletContext as "WebAppContext" or "ApplicationContext",
and ServletConfig as "ServletContext".
BTW, in JSP, the scope linked to a JspPage is named "page"; the scope linked to a HttpServletRequest is named "request"; the scope named to a HttpSession is named "session", and the scope linked to a ServletContext is named ... "application".
"Context" means.. context - it has contextual information and functionality for a particular web application:
application-wide parameters
application event listeners
metadata about the application
ServletContext is the context of a Java web application (because it uses servlets)
Context means web app here.
A ServletContextListener gets notified when a Web App is started or stopped. That way you can run tasks automatically that need to be run when the web app starts or stops.
A ServletContext is the runtime representation of the web application.
ServletContext implies Context or Runtime environment of servlet. Servlets runs in Servlet containers like tomcat. Servlet container creates and provides runtime environment for the servlet to get executed and it manages its lifecycle. It also holds other information, as :-
application-wide parameters
application event listeners
metadata about the application
ServletContext is interface that contain a set of methods to communicate with its own servlet container.
Context that stand as a one per web application on per jvm .
That allow servlets to gain access to the context for various parts of the server to communicate.
Life Cycle of ServletContext
Servlet container reads the DD (Deployment Descriptor – web.xml) and creates the name/value string pair for each when web application is getting started.
Container creates the new Instance of ServletContext.
Servlet container gives the ServletContext a reference to each name/value pair of the context init parameter.
Every servlet and JSP in the same web application will now has access to this ServletContext.
ServletConfig vs ServletContext
ServletContext is available to all servlet & jsp in web application while ServletConfig will be available only specific servlet.
Servlet config is one per servlet and Servlet context is one per web application

Categories