How do I know when my Vaadin 7 web app first starting/launching, so I can do some initial set-up work?
Likewise, how do I know when my web app is ending, getting shutdown/exiting?
ServletContextListener
Vaadin is built on top of Java Servlet technology. A “context” is the technical term for your web app in Servlet terms. So the answer here is not Vaadin-specific, it applies to any Servlet -- and at the end of the day, Vaadin is just one big Servlet.
Since Servlet spec version 2.3, a Servlet container such as Tomcat, Jetty, etc. must promise to be on the lookout for any Java class you define as implementing the ServletContextListener interface. That interface has two simple methods:
One that gets called when your web first launches (contextInitialized)
One that gets called when your web app is ending (contextDestroyed).
The ending could be caused by the Servlet container (ex: Tomcat) is being shutdown so all the web apps (“contexts”) are ending, or because just your Vaadin app’s context is ending (if your Servlet container supports per-context shutdown).
The contract every Servlet container must fulfill is that each of your ServletContextListener classes (you can have more than one) must have its contextInitialized invoked before any servlet or filter executes. So this is the perfect time to do initialization work that might benefit more than a single Servlet request-response cycle. If you need to startup a database such as [H2 Database), this is a good time. If you load some data into memory as a cache to be used by the servlet(s) repeatedly, this is a good time. Also a good time to test your apps resources, to be certain logging works or certain expected files are in place, for example.
Likewise, every compliant Servlet container invokes contextDestroyed only after the servlet(s) and filters have finished their last invocation. So this is a good place to shutdown your database, make backups, or do any other clean-up chore appropriate to your web app.
We are discussing the life cycle of your web app’s “context”. That context may involve one, or more than one, servlet. This life cycle of the context goes beyond the life cycle of any one of the servlets participating in this context. The context is kinda-sorta like the queen bee who gives birth to all her drones in a new hive, where she was living before them and she will outlive them all as they die off in dutiful service to her (if that is how a hive works?).
Defining your ServletContextListener
Making a ServletContextListener is quite easy: Make a class with a pair of methods plus an annotation.
Add a new Java class as part of your Vaadin app. You can name the class anything you want.
I add my context listeners in the same package as my main Vaadin app UI class (MyUI.java may have been generated by your Vaadin plugin or by Maven archetype). Seems like a natural place as the context listener is the beginning of my Vaadin app launching before any user is handled while the designated UI class will then be the first piece of my Vaadin app being run for each user.
Declare your class as implementing ServleContextListener. Add the two required methods discussed above; your IDE may assist with this chore.
One more trick: You must inform the Servlet container about this context listener. There is more than one way to do this, but I use the simplest, an annotation #WebListener on the class.
Here is an entire example class.
package com.example.amazingapp;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
*
* #author Basil Bourque
*/
#WebListener
public class WebAppListener implements ServletContextListener {
#Override
public void contextInitialized ( ServletContextEvent sce ) {
System.out.println ( "My Vaadin web app is starting. " );
}
#Override
public void contextDestroyed ( ServletContextEvent sce ) {
System.out.println ( "My Vaadin web app is shutting down." );
}
}
Related
For the current project I'm working on, I've decided to use the front controller pattern. I've always been under the impression that a front controller should (ultimately) be responsible for everything that happens in a web app. Would listeners violate this pattern?
public class MyDatabase implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
...
String driver = context.getInitParameter("driver");
}
}
This, of course, seems a lot simpler than:
public class FrontController extends HttpServlet {
public void service (....) {
MyDatabase db = new MyDatabase(context.getInitParameter("driver"));
}
}
This is a very simplified example; there would be more parameters in practice. So, which snippet would be considered more faithful to the front controller pattern – passing the config from FrontController down, or supplying the config directly to the classes?
As I am new to Java, I am trying to learn servlets without using a framework (for the time being).
Main intent for Front controller is to provide a centralized entry point for handling requests and consequently
to control navigation across a set of related pages (for instance,
multiple pages might be used in an online purchase) from a front
controller than it is to make the individual pages responsible for
navigation
Separating responsibility of initialization of resources from Front controller pattern is good, and you choose a right place for this since ServletContextListener is responsible for receiving notification events about ServletContext lifecycle. Code inside ServletContextListener class will run before the web application starts.
On Google App Engine (GAE) it is possible for frontend instances to create up to 10 threads to maximize throughput. According to this page, such multi-threading can be accomplished as follows:
Runnable myTask = new Runnable({
#Override
public void run() {
// Do whatever
}
});
ThreadFactory threadFactory = ThreadManager.currentRequestThreadFactory();
// GAE caps frontend instances to 10 worker threads per instance.
threadFactory.newRequestThread(myTask);
To hit my GAE server-side, I'll expose many servlets mapped to certain URLs, such as the FizzServlet mapped to http://myapp.com/fizz:
public class FizzServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
// Handle the request here. Somehow send it to an available
// worker thread.
}
}
I guess I'm choking on how to connect these two ideas. As far as I see it, you have 3 different mechanisms/items here:
The App Engine instance itself, whose lifecycle I can "hook" by implementing a ServletContextListener and run custom code when GAE fires up the instance; and
This ThreadFactory/ThreadManager stuff (above)
The servlets/listeners
I guess I'm wondering how to implement code such that every time a new request comes into, say, FizzServlet#doGet, how to make sure that request gets sent to an available thread (if there is one available). That way, if FizzServlet was the only servlet I was exposing, it could get called up to 10 times before it would cause a new (11th) incoming request to hang while a previous request was processing.
I'm looking for the glue code between the servlet and this thread-creating code. Thanks in advance.
I guess I'm wondering how to implement code such that every time a new request comes into, say, FizzServlet#doGet, how to make sure that request gets sent to an available thread (if there is one available). That way, if FizzServlet was the only servlet I was exposing, it could get called up to 10 times before it would cause a new (11th) incoming request to hang while a previous request was processing.
That's what the GAE servlet engine does for you. You deploy an app containing a servlet, and when a request comes in, the servlet engine uses a thread to process the request and calls your servlet. You don't have anything to do.
If your servlet's doGet() or doPost() method, invoked by GAE, needs to perform several tasks in parallel (like contacting several other web sites for example), then you'll start threads by yourself as explained in the page you linked to.
I have a large web project in Java EE 6 so far everything is working great.
Now I'm adding a new class that takes twitter information and returns a string. So far the strings have been extracted from the JSON file from twitter and are ready to be persisted in my database. My problem is I'm not sure how to pass information from the EJB that normally handles all of my database calls. I'm using JPA and have a DAO class that managers all database access. I already have a method there for updateDatabase(String). I'd like to be able to call updateDatabase(String) from the class that has the strings to add but I don't know if it's good form to instantiate a stateless bean like that. Normally you inject beans and then call just their class name to access their methods. I could also maybe try and reference the twitter string generating class from inside of the EJB but then I'd have to instantiate it there and mess with main() method calls for execution. I'm not really sure how to do this. Right now my Twitter consuming class is just a POJO with a main method. For some reason some of the library methods did not work outside of main in face IOUtils() API directly says "Instances should NOT be constructed in standard programming".
So on a higher level bottom line, I'm just asking how POJO's are normally "mixed" into a Java EE project where most of your classes are EJBs and servlets.
Edit: the above seems confusing to me after rereading so I'll try to simplify it. basically I have a class with a main method. I'd like to call my EJB class that handles database access and call it's updateDatabase(String) method and just pass in the string. How should I do this?
Edit: So it looks like a JNDI lookup and subsequence reference is the preferred way to do this rather than instantiating the EJB directly?
Edit: these classes are all in the same web project. In the same package. I could inject one or convert the POJO to an EJB. However the POJO does have a main method and some of the library files do not like to be instantiated so running it in main seems like the best option.
My main code:
public class Driver {
#EJB
static RSSbean rssbean;
public static void main(String[] args) throws Exception {
System.setProperty("http.proxyHost", "proxya..com");
System.setProperty("http.proxyPort", "8080");
/////////////auth code///////////////auth code/////////////////
String username = System.getProperty("proxy.authentication.username");
String password = System.getProperty("proxy.authentication.password");
if (username == null) {
Authenticator.setDefault(new ProxyAuthenticator("", ""));
}
///////////////end auth code/////////////////////////////////end
URL twitterSource = new URL("http://search.twitter.com/search.json?q=google");
ByteArrayOutputStream urlOutputStream = new ByteArrayOutputStream();
IOUtils.copy(twitterSource.openStream(), urlOutputStream);
String urlContents = urlOutputStream.toString();
JSONObject thisobject = new JSONObject(urlContents);
JSONArray names = thisobject.names();
JSONArray asArray = thisobject.toJSONArray(names);
JSONArray resultsArray = thisobject.getJSONArray("results");
JSONObject(urlContents.substring(urlContents.indexOf('s')));
JSONObject jsonObject = resultsArray.getJSONObject(0);
String twitterText = jsonObject.getString("text");
rssbean.updateDatabase("twitterText");
}
}
I'm also getting a java.lang.NullPointerException somewhere around rssbean.updateDatabase("twitterText");
You should use InitialContext#lookup method to obtain EJB reference from an application server.
For example:
#Stateless(name="myEJB")
public class MyEJB {
public void ejbMethod() {
// business logic
}
}
public class TestEJB {
public static void main() {
MyEJB ejbRef = (MyEJB) new InitialContext().lookup("java:comp/env/myEJB");
ejbRef.ejbMethod();
}
}
However, note that the ejb name used for lookup may be vendor-specific. Also, EJB 3.1 introduces the idea of portable JNDI names which should work for every application server.
Use the POJO as a stateless EJB, there's nothing wrong with that approach.
From the wikipedia: EJB is a server-side model that encapsulates the business logic of an application.
Your POJO class consumes a web service, so it performs a business logic for you.
EDIT > Upon reading your comment, are you trying to access an EJB from outside of the Java EE container? Because if not, then you can inject your EJB into another EJB (they HAVE to be Stateless, both of them)
If you have a stand alone program that wishes to access an EJB you have a couple of options.
One is to simply use JNDI to look up the EJB. The EJB must have a Remote interface, and you need to configure the JNDI part for you container, as well as include any specific container jars within your stand alone application.
Another technique is to use the Java EE artifact know as the "application client". Here, there is a container provider wrapper for your class, but it provides a run time environment very similar to running the class within the container, notably you get things like EJB injection.
You app still runs in a separate JVM, so you still need to reference Remote EJBs, but the app client container handles a bunch of the boiler plate in getting your app connected to the server. This, too, while a Java EE artifact, is also container dependent in how to configure and launch an app client application.
Finally, there is basically little difference in how a POJO interact with the EJB container this way in contrast to a POJO deployed within the container. The interface is still a matter of getting the EJB injected (more easily done in Java EE 6 than before) or looking up a reference via JNDI. The only significant difference being that a POJO deployed in the container can use a Local interface instead of the Remote.
Can we replace the pupose of init method to the servlet constructor?
My question is why does servlet need a separate method int(ServletConfig config) for the pupose of initialization we could have achieve the same thing by having a parameterised constructor let XServlet(ServletConfig config) and the container can invoke the same .
Probably because you cannot specify the parameter signature for constructors in an interface.
It is generally considered a bad practice to perform logic in constructor (it should only initialize the field and create object in consistent state). It also makes testing harder.
Also it is much harder to perform injection - when using init the container can create a servlet, inject dependencies and run init. With constructor you would expect to have all the dependencies already set. Wicket works around this problem by injecting Spring beans into page class from superclass constructor - because superclass constructor runs first. However modifying subclass fields from superclass constructor seems wrong.
That being said using separate init method some things simpler and easier to maintain. Also note that EJB promotes #PostConstruct annotation as well.
I guess this choice was made to simplify the coding of servlets. In the current situation, a servlet having no need for specific initialization can be coded like this:
public class MyServlet extends HttpServlet {
// doGet, doPost, etc.
}
If the servlet was initialized using the constructor, it would need to be coded like this:
public class MyServlet extends HttpServlet {
public MyServlet(ServletConfig config) {
super(config);
}
// doGet, doPost, etc.
}
BTW, they even introduced a no-arg init method that can be used to avoid being forced to call super.init(config).
Short answer: NO.
Long answer:
If a servlet contains a constructor and a init method, you will see the constructor is called first, and then the init method (try it out with sysout statements).
A servlet is a java class, so it must follow the java process, so constructor is called first and then the init method (note that the init method is called by your servlet container like tomcat because that's how servlet's are supposed to be initialized; read the servlet specification).
So, if you need to do some operation that is specific to your business need (say create an DB connection or read a set of user details etc); constructors are not the best place to put these things in.
Usually constructors should never have any complex logic/business processing. They should initialize bare minimum member variables and leave the complex things to later; in case of servlets the heavy lifting can be done by init method.
Also note that by the time the init() is called the servlet container is up and ready with it's system resources, i.e it would have initialized the JNDi name bindings, data sources so on and so forth.
So in a way it guarantees you that when you call the init(), it will have the system resources ready for you to work on.
The servlet 3 spec says this:
2.3.1 Loading and Instantiation The servlet container is responsible
for loading and instantiating servlets. The loading and instantiation
can occur when the container is started, or delayed until the
container determines the servlet is needed to service a request. When
the servlet engine is started, needed servlet classes must be located
by the servlet container. The servlet container loads the servlet
class using normal Java class loading facilities. The loading may be
from a local file system, a remote file system, or other network
services. After loading the Servlet class, the container instantiates
it for use.
2.3.2 Initialization After the servlet object is instantiated, the
container must initialize the servlet before it can handle requests
from clients. Initialization is provided so that a servlet can read
persistent configuration data, initialize costly resources (such as
JDBC APIbased connections), and perform other one-time activities. The
container initializes the servlet instance by calling the init method
of the Servlet interface with a unique (per servlet declaration)
object implementing the ServletConfig interface. This configuration
object allows the servlet to access name-value initialization
parameters from the Web application’s configuration information. The
configuration object also gives the servlet access to an object
(implementing the ServletContext interface) that describes the
servlet’s runtime environment. See Chapter 4, Servlet Context for more
information about the ServletContext interface.
Read this part:
The servlet container loads the servlet class using normal Java class loading facilities.
so, the container will have to use standard java class loading mechanism. Which means it can not do what Duncan have just suggested.
int(ServletConfig config) is a life cycle method of Servlet.and it is being called by servlet container.
We can replace the init method code in parameter constructor of super class servlet.
but we can't force the developer to call super class constructor
for example
/*If generic servlet has a constructor like this*/
public GenericServlet(ServletConfig config){
....
}
/*And Developers servlet is calling only default servlet.*/
public MyServlet(){
super();
}
So in this scenario initialization never happens for that servlet. it cause issues problem. because ServletConfig obj is not initialized.
And we cant force the user to call specifict super class constructor.
The simple answer is that you have to have a no-arg ctor and an init method because that is what the spec requires...
Why the spec is written like that is probably a matter of history. These days I think that we might defer construction until the ServletContext is available and call a ctor with that argument. But looking back there was a ServletContext.getServlet(name) method, so that one servlet could look up another on initialisation and communicate with it. For this to work they would all have had to be created up-front and then init'd.
getServlet was deprecated and now returns null (I think it was a security hole for containers that were running multiple apps).
You'll have to excuse me if I'm describing this incorrectly, but essentially I'm trying to get a service-like class to be instantiated just once at server start and to sort of "exist" in the background until it is killed off at server stop. At least from what I can tell, this is not exactly the same as a typical servlet (though I may be wrong about this). What's even more important is that I need to also be able to access this service/object later down the line.
As an example, in another project I've worked on, we used the Spring Framework to accomplish something similar. Essentially, we used the configuration XML file along with the built-in annotations to let Spring know to instantiate instances of some of our services. Later down the line, we used the annotation #Autowired to sort of "grab" the object reference of this pre-instantiated service/object.
So, though it may seem against some of the major concepts of Java itself, I'm just trying to figure out how to reinvent this wheel here. I guess sometimes I feel like these big app frameworks do too much "black-box magic" behind the scenes that I'd really like to be able to fine-tune.
Thanks for any help and/or suggestions!
Oh and I'm trying to run this all from JBoss 6
Here's one way to do it. Add a servlet context listener to your web.xml, e.g.:
<listener>
<listener-class>com.example.BackgroundServletContextListener</listener-class>
</listener>
Then create that class to manage your background service. In this example I use a single-threaded ScheduledExecutorService to schedule it to run every 5 minutes:
public class BackgroundServletContextListener implements ServletContextListener {
private ScheduledExecutorService executor;
private BackgroundService service;
public void contextInitialized(ServletContextEvent sce) {
service = new BackgroundService();
// setup single thread to run background service every 5 minutes
executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(service, 0, 5, TimeUnit.MINUTES);
// make the background service available to the servlet context
sce.getServletContext().setAttribute("service", service);
}
public void contextDestroyed(ServletContextEvent sce) {
executor.shutdown();
}
}
public class BackgroundService implements Runnable {
public void run() {
// do your background processing here
}
}
If you need to access the BackgroundService from web requests, you can access it through the ServletContext. E.g.:
ServletContext context = request.getSession().getServletContext();
BackgroundService service = (BackgroundService) context.getAttribute("service");
Have you considered using an EJB 3.1 Session bean? These can be deployed in a war file, and can be annotated with #Singleton and #Startup.
A number of annotations available with EJB 3.1 are designed to bring Spring goodies into the Java EE framework. It may be the re-invention you're considering has been done for you.
If you must roll your own, you can create a servlet and configure it start up when the application does using load-on-startup. I built a system like that a few years ago. We then used the new(ish) java.util.concurrent stuff like ExecutorService to have it process work from other servlets.
More information about what you're trying to do, and why the existing ways of doing things is insufficient, would be helpful.
You can use messaging for that. Just send message to the queue, and let the message listener do the processing asynchronously in the background.
You can use JMS for the implementation, and ActiveMQ for the message broker.
Spring has JMSTemplate, JMSGateWaySupport API to make JMS Implementation simple
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jms.html