I am creating a JBoss server to deploy a java application which will be a REST-like servlet taking data from requests and placing them into a SQL database.
My main question: Is it possible to set up a class on the JBoss server which is not run based on requests but is more like a main loop. I.e. just a loop which will "sleep" then check some information and either do something or sleep again.
Basically what I am trying to do is write a bunch of data to a file, once that file fills up to a certain point, write it all at once to the database to reduce connection overhead.
My best guess is that I could write any kind of class with a loop and have it run in the way I want(as long as my "sleep" technique was correct to allow for the servlet on the same JBoss time to run).
What I don't know though is how to get that main loop to run constantly; Just call it in the constructor?? The only way I know how to have things run on the server currently is to have a mapping set up in the web.xml and actively make a web page request information from the server...
Is there a better(read easier) service than JBoss and java for something like that
Thanks in advance, I have searched pretty hard for an explanation of something like this but it seems I am missing the right keyword...
Have a look at #Startup and #Singleton beans.
In short, you can write something like this:
#Startup #Singleton
public class MainLoopBean {
#PostConstruct
public void mainLoop() {
}
}
Ideally you should couple this with the timer service. When some amount of work is done and you want to pause, just schedule the method to be invoked later and return.
If the connection overhead is really affecting your performance, you can change the setting for connection pooling in JBoss. This would make the application simpler, more robust and scalable. Writing to one file does not scale up to multiple parallel connections. It also requires more IO than writing to the DB directly.
Why are you considering loops at all? Why not set up a JMS queue and a listener on it, that way whenever something happens, you're able to respond. No need for loops, no special hooks, nothing.
Alternatively, if you're actually interested in doing something more complicated, look into the Java Connector Architecture, which provides you these kinds of hooks as well.
Related
Maybe this is a very basic Java question. Forgive me if it is.
I have this Spring Boot project that needs to, for every registered user, automatically (in the background) connect periodically to a website and download many documents and/or check for changes.
The "download/check" system was externally developed. Every method was static.
Am I right thinking that it IS a problem when I want to have more than one simultaneous execution?
Even if it has all specific connection parameters through parameters?
Thinking of that, I removed the static annotation on almost every method. Now I need to create a new instance for every execution.
When I began adding it to my Spring boot project, I realized there are a bunch of services that make simultaneous connections to a web service, and there I didn't even care about concurrency.
AFAIK, each service is a singleton. Right? So there is no new instance for every connection. Right?
My question is: If I happen to have 100's of users... How should I integrate the jsoup code?
Should I create a new instance from a service?
Should I convert it to a Service itself and just #Autowire it to the service where the process is triggered?
Is it better to make it static? (this one I don't think so, but maybe I'm wrong)
Any other option?
If possible, please add a reason why I should follow your suggestion.
Thank you all for your help.
First of all I'd say if your classes are not maintaining any state then it is actually a good thing if everything is static cause this gets you rather close to functional programming. If you are then passing everything as an parameter to a method and don't have any state in the class (not the method) then everything is kept on the stack which is not shared amongst threads. Long story short: thread-safe.
If you maintain any type of state in your classes – be it services or components – then you have to make sure that they are executing in a thread safe way. One of the easiest ways is to change the #Scope of that particular bean to prototype or for instance request as you are running this as a web app.
We are using a thread local in play to provide a sort of "first level cache" for the WS (web service) library so that calls to the same URI within a given request only happen once. Currently I'm using an #Before filter to ensure that before any given request starts we clear anything in the thread local since play seems to keep a pool of them around.
Is there any better way to implement this than having to do #With(MyThreadLocalKillingFilter.class) on our base controller? It works but seems hackish.
Note that we're using plays built in server starting with play start/run
There is nothing hackish using #With this way in you controller. I think this is fairly common. It is considered better practice than extending a base controller.
You might want to be careful with using ThreadLocals though, specially if using promises which suspends the request execution thread.
I'm looking at my Vaadin app running on a local tomcat server with JProfiler. This shows that every time I start up the server and run my application, there are 3 instances of my main Application class. If I close the application in the browser or even close the browser completely, there are 2 left. I've noticed that the Application's init() method gets called 3 times during startup, even though I never explicitly call it myself. I am using the Threadlocal pattern (but with InheritableThreadlocal).
It doesn't look normal to me, is there anything that can cause this kind of behaviour?
(Copied this question from my post on the vaadin forums)
From your description, I gather that Application is a class written by you (and not something supplied by Vaadin) and that you somehow save the instances of this class in a ThreadLocal.
This would explain the behavior that you're seeing: Tomcat will start several threads to handle client requests. For each thread, a new Application instance will be saved in the ThreadLocal.
Try the (evil) Singleton pattern or (better) dependency injection with the singleton scope instead.
If you use the singleton pattern, make sure you use the code under "Construct in multi-threaded applications" or you will get odd errors in Tomcat. This article on JavaWorld explains it in depth: Simply Singleton
EDIT Based on your feedback: The behavior your see is expected and correct. Tomcat uses threads to handle requests and it will pre-spawn a couple to be ready for business (in your case, it spawns three).
I started trying to learn tdd and wanted to use it on a real project. So I decided on programming a simple file synchronization with a client and a server in java.
After more or less finishing the client part, I got stuck while writing the server part.
In order to unit test the logic without accessing external resources, I put those in separate classes, so that I could mock them. So far, so good.
Now here's my question:
This image shows how I imagined everything could look like, where green parts are finished and the yellow parts are not yet implemented.
In my case I'd have to pass RemoteServer a ConnectionManager. The ConnectionManager would a need a FileAdapter and a Communicator in order to create a ClientConnectionHandler. That sounds like a little bit too much passing for me. Is this normal for tdd'ing or am I doing something wrong in order to keep everything testable?
edit: The class ClientConnectionHandler is only responsible for the file sync logic on the server side, which means: Following my own mini protocol to receive files from a client.
It's pretty normal. If you get one class that has many dependencies, it likely has too many responsibilities as well. But having one class that depends on another class that depends on another - that's normal.
This is why IoC Container libraries like Spring are popular. They make it easier to wire up (configure and resolve) all of the dependencies.
We have a need to run a housekeeping thread in an EJB3.0 container. We currently have a "TimerService" #Stateless EJB (necessary because it has has other #EJBs injected), which creates an interval EJB Timer when it's startTimer() method is called. There should only be one instance of this timer thread. The current solution involves calling startTimer() from the init() method of one of our servlets, where the servlet is forced to load at startup using in the web.xml, but that feels like coincidental behaviour instead of the right way to do things. We've already had a problem because someone else subclassed that servlet, which meant that init() was called twice, which meant two timer threads.
This feels like it's not an unusual requirement, so what's the proper way to do this, if anything? It seems to me like there ought to be a simple way to ask the container to start a thread when it starts up, without having to tie it to other resources in the container.
For EJB < 3.1 you are going to have to get application server specific or hackish. Since you mention you are using JBoss, you can use the #Management tag which has defined lifecycle methods.
I want to suggest 2 solutions.
1 The fix to your implementation.
make your servlet final. this will avoid subclassing. But the servlet still may be deployed twice. To avoid this create static boolean variable into the servlet. The init should check this variable. If it is false it turns it to true and continues. Otherwise it throws exception.
This is fast fix that you can do now.
but it is not a "right" solution. For example this will not work in clustered environment.
2 There are 2 "right" solutions.
2.1. use quartz
2.2. Implement timer using JCA. Connector is the only place in J2EE where you can legally use threads and timers.
I mentioned JCA in other context in this article:
http://alexradzin.blogspot.com/2010/10/send-delayed-jms-messages.html
You are welcome to view it and see a short code sample that can probably help you.
Does your app server support "startup beans"? I ask because in WebSphere Application Server, there is an option in the administrative console to set the server to fire "startup beans" on server start up. We use it for certain applications we have that require a lot of "heavy loading" and initializing, so that way we can minimize start up time for the end-user experience.
Here is a link to WAS 6 documention (old, I know, but still helpful). Startup beans
I know this is specific to IBM WebSphere, but perhaps your app server (if not WebSphere) has something similar to help you kick them off?