Play framework 1.2.5 application slow startup - java

I am using Play framework 1.2.5 and Hibernate 3.25 for developing my web application. I am facing problems with the application startup, it is very slow :(
For any Java EE servlet-driven application, we use the ServletContextListener for initializing the session factories (which is really a time consuming job). Once the application is deployed, the session factories will be initialized and all this have to be completed before the application is ready to use for the end user. In this way, when the user triggers the first request, the response time for the first is faster.
But, for Play framework does not follow any servlet architecture. Hence not sure how to implement something similar to the ServletContextListener which will be create all the session factories before the application is ready to use to the end user.
Without this, for the first time the application is really very slow for the first request.
I am sure there might be something in Play Framework also which will do the same but I am not aware of it.
Please let me know about this.

You can use a Job to initialise you application.
For example you could have a bootstrap job annotated with #OnApplicationStart which would take care of loading your static data or initialising you cache or factories.
#OnApplicationStart
public class Bootstrap extends Job {
public void doJob() {
//Load static data
//Initialise cache
//Initialise factories
...
// ready to serve application
}
}

You're probably running the application in development mode, where everything is compiled and initialized lazily, on the first request. The production mode compiles everything before actually starting the server. See http://www.playframework.org/documentation/1.2.5/production

JB should be correct. In short you can start the server with --%prod option:
play run --%prod
or
play start --%prod

Related

Skip deploying or stop web application if servlet context initialization fails

In our project, we have several Spring-based modules which are deployed on WAS as web applications. We need to skip deployment, or stop a module if its Spring context initialization fails (i.e. ContextLoaderListener#contextInitialized or DispatcherServlet#init throws an exception). Now, if such happens, app is got deployed and starts, but returns HTTP 500 for any request.
Websphere 8.5.5
Related question: https://stackoverflow.com/a/272747/3459206
This APAR seems to be relevant:
https://www-01.ibm.com/support/docview.wss?uid=swg1PI58875
From the APAR text:
Listener exceptions typically should not stop the application
from starting up for service. However, some applications depend
on their listeners to do the necessary setup before the
application is started for service. Such applications prefer to
stop the application from starting up when there is any
exception in their listeners.
Problem conclusion
The WebContainer Container code was modified to provide an
option to stop the application when there is any listener
exception during the application starting up process.
A new WebContainer custom property needs to be set to enable the
behavior provided by this APAR:
For Full Profiles
com.ibm.ws.webcontainer.stopappstartuponlistenerexception = true
(default is false)
For Liberty Profile
stopappstartuponlistenerexception=true
The fix for this APAR is currently targeted for inclusion in
WebSphere Application Server fix packs 8.5.5.11 and 9.0.0.2,
and Liberty 16.0.0.3
See the APAR link for additional information.
You can use jenkins + maven.
Add the part you need to check under your test like junit.
Then if this module do not pass test, jenkins would not deploy it.
But I prefer fix bugs before deployment
Had a very similar issue.
The thing is - webfear - sorry could not resist ;-) does not initialize everything on startup.
To trigger a controlled request, I added a ScheduledEJB to the startup of the application. This bean itself triggered a http-request to a defined URL, which itself triggered:
any filters to get initialized in the chain
any contexts which are needed are initialized
And this itself ensured that my application (EAR or WAR) got very quickly tested after deployment. This works well with some small amout of requests per minute
If you work with high load, means tons of requests per second, you need to choose a different approach.
In this case I added a polling mechanism into the #Startup of the application, which polled every second or 250ms (depends on the load of the application).
This firing to the server ensured, that my #Startup bean was the very first which triggered the possible init issues in the application. If this happened I initialized a filter which always reported a 500 (or better fitting error) to the requestor.
Of course stop your firing bean, as soon as you get the 500, else your admins may like to kill you. (happend to me, since I produced tons or monitoring issues ;-) )
And of course on the regular operation, after your application started properly, you should also disable the polling
Look for a try-catch in the top level of your application code that is catching the Spring exception and allowing the application to continue running.
If the Spring exceptions being thrown are permitted to propagate to the top of the stack, the JVM will stop and there's no way it can keep running, far as I know.

Flyway database migration to run automatically when new war deployed

I would like Flyway to run whenever I deploy a new war to my server.
Does flyway automatically get run when a server is deployed? Do I have to always automate a script which would then the flyway migration command? Or what is the best way to do this?
Server:
The server is a Java Tomcat Server running on Elastic Beanstalk (AWS) that is connected to a MySQL database.
Deployment Process
We run our sql migration scripts on the database manually. Then we upload a new war of the server to Elastic Beanstalk.
This can be useful:
Auto-migration on startup : https://flywaydb.org/documentation/api/
So for Java all it takes is to create scripts (eg. V1__initial_schema.sql, ...), put them under /src/main/resources/db/migration/
and then:
Flyway flyway = new Flyway();
flyway.setDataSource(...);
flyway.migrate();
As the comments said, there may be multiple ways to do this.
ServletContextListener
One common way is to use the hook defined by the Java Servlet spec for being notified when your web app is launching and shutting-down. That hook is the ServletContextListener interface. Add a class to your project implementing the two methods in this interface, one for launch and one for shutdown. In the launch method, run your Flyway code.
The word “context” is the technical term meaning your web app.
contextInitializedYour web app is launching. No incoming web request has yet been handled, and will not be handled until your implementation of this method completes. Run your Flyway migrations here.
contextDestroyedYour web app is shutting down. The last remaining web request has been serviced, and no more will be accepted.
Annotating this class with #WebListener is the easiest of multiple ways to get your Servlet container to register an instance.
Pretty easy.
Your ServletContextListener is guaranteed to be called and run to completion before the first execution of any Servlet (or Filter) in your web app. So this is the perfect place to do setup work that you want finished before your servlets go to work. Flyway seems like a natural fit to me.
Search Stack Overflow for “ServletContextListener” to learn more and see examples, such as my own Question & Answer.
Handling failure
Be aware that stopping a web app’s deployment when something goes wrong (when your ServletContextListener encounters an Exception) is not well-defined in the Servlet spec.
An example might be your Flyway migrations failing for some reason, such as not able to connect to database. At that point you might want to halt deployment of your web app.
See my own Question and Answer and the group of related questions I list in that answer. Tomcat 8.0.33 halts the deployment, and un-deploys the web app, but unfortunately does not report the offending Exception (or at least I could not find any such report in the logs nor in the IDE console while in development mode). The behavior of other Servlet containers may vary.

JBPM6: How to resume a process from the last successful node after the server crash?

I'm trying to implement the failover strategy when executing jbpm6 processes. My setup is the following:
I'm using jbpm6.2.0-Final (latest stable release) with persistence enabled
I'm constructing an instance of org.kie.spring.factorybeans.RuntimeManagerFactoryBean with type SINGLETON to get KSession to start/abort processes and complete/abort work items
all beans are wired by Spring 3.2
DB2 is used a database engine
I use Tomcat 7.0.27
In the positive scenario everything is working as I expect. But I would like to know how to resume the process in the case of server crash. To reproduce it I started my process (described as BPMN2 file), got at some middle step and killed the Tomcat process. After that I see uncompleted process instance in the PROCESS_INSTANCE_INFO table and uncompleted work item in the WORK_ITEM_INFO table. Also there is a session in the SESSION_INFO table.
My question is: could you show me the example of code which would take that remaining process and resume it starting from the last node (if it is possible).
Update
I forgot to mention that i'm not using jbpm-console, but I'm embedding jbpm into my javaee application.
If you initialize your RuntimeManager on init of your application Server it should take care of reloading and resuming the processes.
You need not worry about reloading it again by yourself.

How to run a bean as a background service?

I need to be able to initiate a bean at startup and have it run constantly in the background using some kind of internal event/time loop (looking for data records to process). I was wondering what the correct Java EE 7/ JBoss EAP 6.2 method of doing this would be.
Any ideas?
Use the Quartz Scheduler framework and have the job fire up as configured.
It depends what you want to achieve. There are various ways you can achieve the stated goal. Some i can think of are :-
1)Use spring which automatically instantiate singleton beans on startup and call init method while start up
2)In terms of web app , you can use loadOnstartUp servlet configuration
3)Use quarts Job to run the background jobs
EJBs should work fine in this case (standard Java EE - no external framework needed)
I am assuming you need a 'pull' mode for the data rather than having a component to 'listen' to data events
Spin up a Singleton EJB
Write your business logic which would query the data repository
#Singleton
#Startup //container initializes the bean when it starts or when the application is deployed
public class MySingletonEJB{
#Schedule //configure this annotation as per required schedule e.g. via a Cron like syntax
public void executeJob(){
//.... search data records
}
}

Jersey initialization code after webapp is fully started

I asked this question earlier:
Jersey app-run initialization code on startup to initialize application
Is there any way to run this initialization code after the server has initialized the web app fully ? I am running into a catch-22 problem in that I need the web app fully started by Tomcat before I can run my login call once ?
There are a few considerations. First, Jersey is implemented as a servlet, and that's how it gets loaded. The simplest way to decouple servlet startup from servlet context startup is to not load it on startup. Accomplish this by omitting the load-on-startup element from the servlet descriptor in the web.xml. Setting it to a non-positive should also work.
If you must load the servlet on startup but still want to decouple it, which was my case, you'll probably have to write some custom code, which I did. I couldn't think of any other way. Use a listener of some type--a ServletContextListener or Spring ApplicationListener, depending on exactly how your app is set up--to kick off a new thread that will initialize your Jersey servlet by making an HTTP request to it. It feels a little dirty, but like I said, it's the only thing I and my team could come up with.

Categories

Resources