I have a Java EE application that has two components: First is a service that scrapes some information from internet and fills it into database. Second is a web interface (deployed on tomcat) from where user can browse that information.
What could be the best approach to implement the first component? Should it be run as a background Daemon/Service or a thread within the container?
I would personally separate them into different processes. Aside from anything else, it means you can restart one without worrying about the other. It also means you can really easily deploy them on different machines without pointlessly installing Tomcat for a service which doesn't actually need a web interface.
Depending on the type of application framework, Spring lets you use Quartz or the java.util.concurrent framework. Spring has a TaskExecutor abstraction (see the Spring documentation) which simplifies a lot of this, but check to see which fits best with your design.
Spring or Quartz (managed by Spring) then controls the creation and starting/stopping of Threads or Executors or Jobs, along with their frequency/period and other scheduling parameters, and also manages any pooling of jobs you might require.
I use these for all my background tasks and batch jobs in any Java EE applications I write with no problems. Since the jobs are Spring managed POJOs, they have access to the full dependency injection framework and so on that that Spring entails, and of course you can switch between scheduler frameworks with a simple change to you application configuration XML file as your needs change or scale.
There is nothing wrong with having background jobs inside a web container, but you MUST let the web container know about it so it can be stopped and started properly.
Have a look at the load-on-startup tag in web.xml. There are some advice on http://wiki.metawerx.net/wiki/Web.xml.LoadOnStartup
Related
Hi folks need some opinions here.
I already have a spring boot application holding all my rest APIs running on tomcat that ships in with spring-boot-starter-web.
I would like to set up jobs using spring batch that will be schedule via kubernetes. The idea is to share the same business logic instead of creating a standalone batch project which i need to maintain double business logic.
Question, scheduling via kubernetes meaning i will be firing java -jar someJar --spring.batch.jobNames=xxx in container, doing that it will also start up all my RestApis right? which in turn unnecessary and waste of resources. Anyway to mitigate this or my understanding is wrong?
The way I would implement this is by extracting the common business logic in a separate module, and make the batch app and the webapp depend on that module.
I have a java web application which is running on Glassfish server. Using war file i use to deploy the application in various servers. Now to keep my application's database updated, i want to run some class (inside from application)periodically without any user interaction (should not depends on application is running or not/current users/session). i have seen that using some Timer and TimerTask class i can run any job periodically. But how to initialize it for the first time?
Please put your thoughts on how to complete this process.
Use a Job scheduler. Consider Quartz http://quartz-scheduler.org/ and start it when the program starts. The good part about using a scheduler is your program is more maintainable and you can easily create other new jobs
Create a servlet and make it load on startup. There you can initialize your task, I think.
Quartz is a good solution like already suggested. But if you need something more lite weight, I would have a look at the scheduled executor:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html
It is less flexible than Quartz, but you don't need to add any dependency and it might be that it is good enough for your needs.
About starting up; I normally use Spring to wire up my application and its dependencies. So starting schedulers and running scheduled tasks is then a no brainer.
The answer changes depending on the version of Java EE you are using. In Java EE 5 and previous versions you would use a ServletContextListener to run code (call an EJB) at deployment time that used the Timer API. In Java EE 6+ you can use the #Schedule annotation which uses annotations and a cron-type syntax to schedule your task at deployment time.
Of course if you don't need automatic deployment time scheduling then you'd just create some web form that calls a EJB when submitted which in turn calls the Timer API programmatically.
For more see the Java EE tutorial
Okay. This is again a question of industry practice.
Tomcat = Web Container
JBoss, WebLogic, etc = Application Servers that have Web Container within (for JBoss, its forked Tomcat)
Spring does not need Application Server like JBoss. If we use enterprise services like JMS, etc we can use independent systems like RabbitMQ, ApacheMQ, etc.
Question is why do people still use JBoss and other Application Serves for purely spring based applications?
What are the advantages Spring can make use of, by using Application Servers? Like object pooling? What specific advantages does Application Server offers? How are those configured?
If not for spring, for what other purposes Application Servers are used for Spring/Hibernate, etc stack? (Use cases)
Actually I would say listening for JMS is probably the best reason for an application server. A stand alone message broker does not fix the problem since you still need a component that's listening for messages. The best way to do this is to use a MDB. In theory you can use Springs MessageListenerContainer. However this has several disadvantages like JMS only supports blocking reads and Spring therefore needs to spin up it's own threads which is totally unsupported (even in Tomcat) and can break transactions, security, naming (JNDI) and class loading (which in turn can break remoting). A JCA resource adapter is free to do whatever it wants including spinning up threads via WorkManager. Likely a database is used besides JMS (or another destination) at which point you need XA-transactions and JTA, in other words an application server. Yes you can patch this into servlet container but that this point it becomes indistinguishable from an application server.
IMHO the biggest reason against application servers is that it takes years after a spec is published (which in turn takes years as well) until severs implement the spec and have ironed out the worst bugs. Only now, right before EE 7 is about to be published do we have are EE 6 servers starting to appear that are not totally riddled with bugs. It gets comical to the point where some vendors do no longer fix bugs in their EE 6 line because they're already busy with the upcoming EE 7 line.
Edit
Long explanation of the last paragraph:
Java EE in a lot of places relies on what's called contextual information. Information that's not explicitly passed as an argument from the server/container to the application but implicitly "there". For example the current user for security checks. The current transaction or connection. The current application for looking up classes to lazily load code or deserialize objects. Or the current component (servlet, EJB, …) for doing JNDI look ups. All this information is in thread locals that the server/container sets before calling a component (servlet, EJB, …). If you create your own threads then the server/container doesn't know about them and all the features relying on this information don't work anymore. You might get away with this by just not using any of those features in threads you spawn.
Some links
http://www.oracle.com/technetwork/java/restrictions-142267.html#threads
http://www.ibm.com/developerworks/websphere/techjournal/0609_alcott/0609_alcott.html#spring-4
If we check the Servlet 3.0 specification we find:
2.3.3.3 Asynchronous processing
Java Enterprise Edition features such as Section 15.2.2, “Web Application Environment” on page 15-174 and Section 15.3.1, “Propagation of Security Identity in EJBTM Calls” on page 15-176 are available only to threads executing the initial request or when the request is dispatched to the container via the AsyncContext.dispatch method. Java Enterprise Edition features may be available to other threads operating directly on the response object via the AsyncContext.start(Runnable) method.
This is about asynchronous processing but the same restrictions apply for custom threads.
public void start(Runnable r) - This method causes the container to dispatch a thread, possibly from a managed thread pool, to run the specified Runnable. The container may propagate appropriate contextual information to the Runnable.
Again, asynchronous processing but the same restrictions apply for custom threads.
15.2.2 Web Application Environment
This type of servlet container should support this behavior when performed on threads created by the developer, but are not currently required to do so. Such a requirement will be added in the next version of this specification. Developers are cautioned that depending on this capability for application-created threads is not recommended, as it is non-portable.
Non-portable means it can may in one server but not in an other.
When you want do receive messages with JMS outside of an MDB you can use four methods on javax.jms.MessageConsumer:
#receiveNoWait() you can to this in a container thread, it doesn't block, but it's like peeking. If no message is present it just returns null. This isn't very well suited for listening to messages.
#receive(long) you can to this in a container thread, it does block. You generally don't wan't to do blocking waits in a container thread. Again not very well suited for listening to messages.
#receive(), this blocks possibly indefinitely. Again not very well suited for listening to messages.
#setMessageListener() this is what you want, your get a callback when a message arrives. However unless the library can hook into the application server this won't be a container thread. The hooks into the application server are only available via JCA to resource adapters.
So yes, it may work, but it's not guaranteed and there are a lot of things that may break.
You are right that you don't really need a true application server (implementing all Java EE specs) to use Spring. The biggest reason people don't use true Java EE apps like JBoss is that then have been slow as #$##% on cold start up time making development a pain (hot deploy still doesn't work that well).
You see there are two camps:
Java EE
Spring Framework.
One of the camps believes in the spec/committee process and the other believes in benevolent dictator / organic OSS process. Both have people with their "agendas".
Your probably not going to get a very good unbiased answer as these two camps are much like the Emacs vs VIM war.
Answer your questions w/ a Spring bias
Because it in theory buys your less vendor lock-in (albeit I have found this to be the opposite).
Spring's biggest advantage is AspectJ AOP. By far.
I guess see Philippe's answer.
(start of rant)
Since #PhilippeMarschall defended Java EE I will say that I have done the Tomcat+RabbitMQ+Spring route and it works quite well. #PhilippeMarschall discussion is valid if you want proper JTA+JMS but with proper setup with Sprig AMQP and an a good transactional database like Postgresql this is less of an issue. Also he is incorrect about the message queue transactions not being bound/synchronized to the platform transactions as Spring supports this (and IMHO much more elegantly with #Transactional AOP). Also AMQP is just plain superior to JMS.
(end of rant)
We are using JBoss over tomcat for the JNDI data sources and pooling.. It makes it so the programmer don't have to know anything about the database but its JNDI name
I'd like to have a Spring-managed bean schedule execution of itself (or some other bean, simple factoring) if certain conditions are met (i.e. checking successul startup etc.)
I'd also like to be able to see and control the timer from within the application, which will be running on a Java EE 5-compliant container.
Not sure how best to do this - I know about the dangers of doing thread management myself in an EE environment.
You could have a base class that is a wrapper to schedule background tasks (could be e.g. an Executor or TimerTask) and be parameterized by the timing intervals or even the task to schedule and you could derive more specific classes specialized on certain tasks.
These you would configure/instantiate via Spring configuration and of course your app could modify these via the properties of the classes/beans.
Concerning thread management, I also had concerns regarding threads since JavaEE specs (I believe specifically EJB specs) disallow it but this perhaps depends on the container. For example in Tomcat which of course is not a fully EE container, I never had issue with my own threads.
You don't mention which container you are interested in.
Also (friends here can correct if I am wrong) my understanding is that threads are disallowed e.g. in EJB containers etc if you access various resources handled by the container threads.
So if you only want to do some e.g. sanity checks (checking succesful startup) and similar, I don't think that this would be an issue. But this is MHO. I am not sure to be honest
I want to be able to :
define different jobs and triggers.
modify the expirations dates and intervals on demand
pause or cancel an execution (trigger)
the jobs would be ejbs or call ejbs and i would want to manage everything from the website (the user will have to define the executions)
So i looked at the timerservice, timerobjects, timer and timerhandle. But i think it can't answer to all my needs
Quartz, on the other hand, allows me to do every thing that i want, but i haven't the slightest clue on how to integrate this into my jboss.
I read that quartz uses its own threadpool, and i don't know how to handle all this.
I use Jboss Seam in my project, but the seam/quartz integration is very limited (or the documentation is) and not 100% safe (seen on their forum : 'run forever' tasks end after only a few weeks)
If someone managed to integrate a good scheduler into his application server (jboss is a plus) and could give me directions, advices, or even code snippets, i would be thrilled.
Thanks in advance.
I have some experience integrating Quartz into a Weblogic (no jboss experience, sorry) application server. Quartz has a built in listener class that will be called upon server startup (per J2EE specs) that automatically configure the Quartz scheduler. Then in another startup class you can retrieve that scheduler, add jobs and begin serving those jobs.
You generally don't need to worry about the threadpool, Quartz can handle all this itself if you want it too. It gets its information from a properties files on startup that you can define or use the default one that comes with quartz. I have been using the default because it works for my purposes.
As far as defining jobs, you create your job classes and call your ejbs from there. It is rather very simple.
For your reading pleasure:
All Quartz documentation
Quartz JavaDoc
Cookbook containing lots of code snippets
Hope that's enough to get you started!
Great news! JBoss has a built-in scheduler already.
Since the EJB 2.0 specification included running stateless session beans and MDBs at scheduled intervals, all application servers have included this capability for some time now.
Here is an example of configuring JBoss to run a class using its built-in scheduler:
http://www.jboss.org/community/wiki/Scheduler
The best part about JBoss' implementation is that it is based on the MBean specification, which means that you can create/update/delete scheduled tasks at runtime.
Ok, i am sorry, i found in the sources of Jboss Seam just what i needed :
QuartzDispatcher to create QuartzTriggerHandle wich fires seam event at specified time and date and is manually pausable, resumable and stoppable. I use an #observer on the method i wanted to execute.
It's simple, and it works so far.
As pointed out by Poindexter, the Quartz documentation has nice starting points: Tutorial for Developing with Quartz, Examples of Usage, Cook Book (Quick How-Tos in the form of code examples), etc.
The What Is Quartz article is really good too (even if a bit old now).
For integration with JBoss, maybe have a look at How to configure a Quartz service on JBoss Wiki.