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.
Related
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).
How can I write singleton to work through several processes? Is it possible?
For example I have code that works with Remote Service in Android. How can I write singleton for this purpose?
This thread is old, but the current accepted answer is wrong and misleading some people, so here we go.
Services in Android may run on the same process as your app, or a different process altogether.
If this is an Service defined by your own app for its internal use, it is probably running on the same process. Just don't set any of the process attributes on the Manifest. In that case, your service will run its tasks on either the main thread, or some background threads, and will share the same singleton instance with the rest of your app.
If this is a true remote Service running on a separate process, or a separate app, then what you are trying to achieve is much, much more difficult. Each process will have its own instance of the singleton, and they are in no way related to each other. This makes perfect sense, once you realise the different processes may not even be running the same version of the code.
If you really want to have a common object across processes (hint: you almost certainly don't), you'll need to create a shared memory space for its data, and implement some means of synchronisation. I'm sure there are full college lectures on that subject.
Remote Service you Create will always be singleton. You need to have an Interface to communicate between process using Android Interface Definition Language.
Android Interface Definition Language
See this Example
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html
public enum MySingleton {
SOLE;
//all class stuff
}
This one is singleton that is simply written, lazy and thread safe. You can use MySingleton.SOLE directly or put it to other variables, but they all will be only references to one only instance. You can use it in as many processes as you wish, it shall weather them all. (processes in Android are threads really)
It is not my idea, it is from Effective Java, Second Edition
As for global data using (put that requirement into the question, please), you could reach MySingleton.SOLE from everywhere. Static constants are global. Of course, names would be yours.
Of course any thing has its workaround. You can fool this singleton by classloading.
If you really want to have one instance for several different tasks, not threads, then the easy solution will be singleton build as Hybernate or other ORM object. All processes will see the same row in the same table with the same data. But I think it is the overkill for your task.
I'm going to write my first Java based web app, and I'm sort of lost how to begin.
Firstly, I would like a web app and a desktop app that do pretty much the same thing, without the hackish idea of embedding a web browser into the desktop app because that doesn't allow to easily make changes to the desktop without affecting the web app and vice versa.
Now, here my questions.
Right now, I have a bunch of POJOs and they communicate with a single class that, right now, uses a flat file as a "database", of course, in production, I would use a legitimate database and just change that single class. Is this a good idea? Will I be able to go from POJOs to a web app?
Should I use a framework? I would like to have this app written pretty soon, seeing that all the buisness logic is there, I just need to wrap it so its usable, so, I don't want to spend an extreme amount of time learning, say, Spring (which AFAIK is huge), but, I don't want to keep reinventing the wheel throughout my app either. I can always just use JSP and scriptlets...
If you said yes to the above, what framework(s) do you suggest? Please note that I would like a framework that I can start using in maybe 3-4 weeks of learning.
Will I have to start from scratch with the POJOs that I have written? They're well over 30k LOC, so, if it is like that, I'll be hesitant.
You will need:
a web framework. Since you have Swing background, JSF 2 will be your best bet (everything will be painful, of course, but JSF will get you up and going quickly and will help you avoid the most tragic mistakes). Also, wrapping business pojos into web guis is the main use-case for JSF and it's biggest focus.
a "glue framework". One thing that is much different with web applications as opposed to desktop ones is that you cannot create view components by yourself - they must be created when browser requests a page. So you have to find a way to create the view objects and deliver all the references to the pojos that represent logic, some of which may have very different lifecycles (this is not a problem on desktop, but on web you have to distinguish between pojos that live along with the whole application, along with a single user session, along with a single request, and so on).
The "glue framework" could also provide the additional benefit of managing transactions. You have three choices:
Spring. It's not half as complex as you thing; you only need to learn some basic stuff.
EJB. You would need a real application server, like Glassfish or JBoss
bare JSF has good support for dependency injection, the only drawback is the lack of automatic transaction management.
If I were in your position, I would go with bare JSF 2.0 - this way you only need to learn one new technology. At first, try to avoid libraries like PrimeFaces - they usually work worse than advertised.
edit - and addendum
or - what is "dependency injection"(abridged and simplified)
When request comes to a web application, a new task starts in a new thread (well, the thread is probably recycled, but that's not important).
The application has already been running for some time and most of the objects you are going to need are already built and should not get created again: you have your database connection pool, maybe some parts of business layer; it is also possible that the request is just one of many request made during one session, and you already have a bunch of POJOs that the user is working on. The question is - how to get references to those objects?
You could arrange your application so that resources are available through some static fields. They may be singletons themselves, or they could be acquired through a singleton locator. This tends to work, but is out of fashion (hard to test, hard to refactor, hard to reuse, lifecycles are hard coded in application). The real code could look like this:
public void doSomething() {
Customer Service cs = AppManager.getInstance().getCustomerService();
System.out.println(cs.getVersion());
}
if you need clustering and session management, you could build a special kind of broker that would know and provide to anyone all kinds of needed objects. Each type of object would be registered as a factory under a different name. This also works and is implemented in Java as JNDI. The actual client code would look like this:
public void doSomething() throws Exception {
CustomerService cs = (CustomerService)new InitialContext().lookup("some_fancy_looking_name_in_reality_just_string");
System.out.println(cs.getVersion());
}
The last way is the nicest. Since your initial object is not created by you but by the server just after http request arrives (details depend on the technology you choose, but your entry point might be a JSF managed bean or some kind of action controller), you can just advertise which references you need and let the server take care of finding them for you. This is called "Dependency Injection". Your acts as if everything is taken care of before your code is ever launched. Spring or EJB container, or CDI, or JSF take care of the rest. The code would look like this (just an example):
#EJB
CustomerService cs;
public void doSomething() {
System.out.println(cs.getVersion());
}
Note:
when you use DI, it really uses one of the two former methods under the hood. The good thing is: you do not have to know which one and in some cases you can even switch them without altering your code;
the exact means of registering components for injection differs from framework to framework. It might be a piece of Java code (like in Guice), an XML file (classic Spring) or an annotation (classic EJB 3). Most of the mentioned technologies support different kinds of configuration.
You should definitely use a framework as otherwise sooner or later you'll end up writing your own.
If you use maven then simply typing mvn archetype:generate will give you a huge list of frameworks to choose from and it'll set up all of the scaffolding for you so you can just play with a few frameworks until you find the one that works for you.
Spring has good documentation and is surprisingly easy to get started with. Don't be put off by the pages of documentation! You could use JPA to store stuff in the database. You should (in theory) just be able to annotate your existing POJO's to denote primary keys and so on and it should just work. You can also use JSP's within Spring if that makes life easier.
... I a bunch of POJOs and they communicate with a single class that, right now, uses a flat file as a "database", of course, in production, I would use a legitimate database and just change that single class. Is this a good idea? Will I be able to go from POJOs to a web app?
qualified yes. if the pojo's are sane you should not have many problems. many people use hiberbate.
Should I use a framework? I would like to have this app written pretty soon, seeing that all the buisness logic is there, I just need to wrap it so its usable, so, I don't want to spend an extreme amount of time learning, say, Spring (which AFAIK is huge), but, I don't want to keep reinventing the wheel throughout my app either. I can always just use JSP and scriptlets...
probably. spring is huge, but things like grails or roo can help.
if you want to have a responsive web app, you will need to do some kind of rich client (AJAX). this may require a lot of your code to run on the client. this means writing a lot of javascript or using gwt. this will be a pain. it probably will not be so easy to just "wrap it". if you have written a swing app, then basically that code will need to run on the client.
If you said yes to the above, what framework(s) do you suggest? Please note that I would like a framework that I can start using in maybe 3-4 weeks of learning.
i like groovy and grails - grails uses spring-mvc, spring, hibernate. but there is roo, play and others.
Will I have to start from scratch with the POJOs that I have written? They're well over 30k LOC, so, if it is like that, I'll be hesitant.
the code that will run on the server can probably be mostly left alone. the code that has to run on the client needs to be rewritten in javascript or maybe you can get some reuse out of that code by using gwt,
The Play Framework is doing great things. I would recommend it highly. Having worked with EJB apps and Tomcat/Servlet/Spring apps it's a breath of fresh air. After framework installation you get a working app in a few seconds. Reminds me of Ruby on Rails or Node.js with the type-safety of Java.
Much quicker turnaround on getting started, faster development cycles, and a clearer configuration model than previous Java web app frameworks.
http://www.playframework.com/
I am currently working on some older java code that was developed without App Servers in mind. It is basically a bunch of "black box code" with an input interface, and an output interface. Everything in the "black box" classes are static Data Structures that contain state, which are put through algorithms at timed intervals (every 10 seconds). The black box is started from a main method.
To keep this easy for myself, I am thinking of making the "black box" a Singleton. Basically, anyone who wants to access the logic inside of the black box will get the same instance. This will allow me to use Message Driven beans as input to the black box, and a JMS Publisher of some sort as the output of the black box.
How bad of an idea is this? Any tips?
One of the main concerns I have though, is there may be Threads in the "black box" code that I am unaware of.
Is there such thing as "application scoped objects" in EJB?
Note: I am using Glassfish
If you use a simple singelton, you will be facing problems once you enter a clustered environment.
In such scenario, you have multiple classloaders on multiple JVMs, and your sinlgeton pattern will break as you will have several instances of that class.
The only acceptable use for a singleton in an app server (potentially in a clustered environment) is when you the singleton is totally state-less, and is only used as a convenience to access global data/functions.
I suggest checking your application server vendor's solution for this issue. Most, if not all vendors, supply some solution for requirements of your sort.
Specifically for Glassfish, which you say you are using, check out Singleton EJB support for Glassfish. It might be as simple as adding a single annotation.
I would say that creating a singleton is actually the only viable idea. Assuming that code inside this "black box" is known to use static fields, it is absolutely unsafe to create two instances of this facade. Results are unpredictable otherwise.
Far from being a bad idea, it actually sounds to me like potentially quite a good idea.
Just from a program design point of view: if your black box is conceptually an "object" with properties and methods that work on them, then make it into an object, even if there'll only ever be one of them instantiated.
It should work, but there are some issues you may have to deal with.
Threading, as you have mentioned. An MDB is run in the EJB container where you cannot create your own threads, so you have a potential problem there. If you have access to the actual code (which it sounds like you do), you may want to do some refactoring to either eliminate the threads or use an "approved" threading method. The CommonJ TimerManager will probably work in your stated case since it is performing some task on an interval. There are implementations available for most app servers (WAS and Weblogic have it included).
Classloading - This is dependent on you configuration. If the singleton is created and manipulated from MDB's within the same EAR, you will be fine. Separate EAR's will mean different classloaders and multiple instance of you Singleton. Can't comment on whether this would be a problem in your case or not without more information.
I'm missing a point? You mentioned that the 'black box code' contains state. MDBs may be limited to 1 instance per destination but without proper configuration you will end up with a few MDBs. All of them working with your single instance of 'black box code'. For me it seems this is not a good idea, because one bean will override the 'black box code' state a other bean has created a few ticks before.
It seems to me that the artifact that better fits to your requirement is a JBoss MBean. (If you are thinking on JBoss as AS candidate).
Standard MBean Example
MBeans can also be deployed as Singletons, in case of JBoss clustering.
Clustering with JBoss
I hope that this is useful for you.
Rafa.
Fix the code to get rid of the statics as soon as possible. Singletons are not a step in the right direction - they just add extra misdirection.
Don't use Singletons where state may change.
Exposing the global instance of your black-box class doesn't seem like the way to go. Often times, singletons will seem like they will make things easier on you, and in a way they can, but it often comes back to bite you and you end up having to restructure a large chunk of your code.
In the webserver world, an object can be scoped to the request, the session, or the application. Perhaps what you need is a application-scope object.
Search the docs for "application scope object" or "application lifetime object".
Why not create a rest interface for the blank box thingy and let clients make http calls ?
IMO, it's a good idea to have an EJB container of your Singleton needs. In Java EE 6 placing a #Singleton annotation in your session bean gives you a named singleton.