How is Spring able to notify about when an instance is destroyed? - java

I am reading the Pro Spring 2.5 book and in chapter 4 they talk about life cycle callbacks. How is Spring able to notify when an instance is destroyed (after what I read it is only available on singletons)? What mechanism is used?

No magic here, destroy callbacks are called when the BeanFactory/ApplicationContext is destroyed (close() method is called). In desktop applications this has to be done manually, in servlet environment the same mechanism that was used to start the application context (typically ContextLoaderListener) handled destroying for you.
Two notes:
destroying is important for objects requiring explicit clean-up like database connection pools (DataSource) or threads.
Beans are destroyed in the opposite order compared to creation order. This is understandable: when bean A depends on B, B has to be created first. When bean A is destroyed, B has to be destroyed afterwards, otherwise A would not be able to access its dependencies during destroy phase.
Also Spring allows you to automatically register shutdown hook to handle shutdown automatically. I wouldn't advice that, but just for the record:
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(...)
ctx.registerShutdownHook();

That depends on your environment, if you're running in a webapp, Spring is "finalized" once your servlet context is destroyed, so it can tell all of it's objects they are going to be destroyed.
BTW, Pro Spring 2.5 is really old, you should probably grab a newer book, as there is a lot of stuff that changed between 2.5 and the 3.x series.

Related

ThreadLocal usage in enterprise application

If my web application and ejb application are on the same machine (on same JVM) and all the ejb calls are local calls , will the use of ThreadLocal create any issue while passing information from web to ejb?
Any workaround if the ejb calls are remote? Will ThreadLocal information be available from web application to ejb application? Is use of ThreadLocal advisable in such scenario?
For the first question, there is no problem as long as you remove the ThreadLocal variables at the end of every call. This is important because containers (servlet or ejb) typically use threadpools and therefore reuse threads, this has two effects: one "call" may see threadlocal info coming from a previous call, and if you remove an app from the container without stopping the JVM some classes may not be garbage collected because they are still referenced by a container thread. So put data in a threadlocal in a try / finally block and remove in the finally part.
Here is a post showing one way to handle the problem: ThreadLocal in web applications
For the second question as data is threadlocal it will not come with a remote call, you have to add a parameter to your interfaces, extract threadlocal data on one side and recreate it on the other side...
When using EJB 3.1 you can pass around contextual information in the EJBContext using its context data. This is just a Map<String,Object>.
ThreadLocal shouldn't be used in EJB contexts. One cannot guarantee that the EJB method invocations are all on the same thread (of course the should be).
In EJB there is a different approach call TransactionSyncrhonizationRegistry. See Explanation/Usage for further details.
all the ejb calls are local calls , will the use of ThreadLocal create
any issue while
No, you answered your question yourself. Since calls are local they are executed in the context of one thread.
Any workaround if the ejb calls are remote?
In case of remote calls, the Java EE container will be run in an other JVM, it will spawn its own threads to handle incoming RMI request, there is no way for a remote Java EE container to know about thread local variables that were declared on the other side. Pass it as a parameter object.
It depends what information you are passing! The first question it too generic. I suggest to read the JavaDoc related to ThreadLocal here.
ThreadLocal lives from the server side of the application and are used to let Thread-safe the calls of your Thread objects.
For local calls, the ThreadLocal should work fine, as long as everything is done in the same thread.
For remote calls, which can potentially run on a different server, you will need to come up with something else. Either pass all values as parameters (which will work, but introduces complexity in the code) or use something like a distributed cache, e.g. Hazelcast, which will function like a global HashMap, which all cluster nodes have access to.
ThreadLocal cannot be used with 100% certainty in web applications. You simply do not have the guarantee that one thread will be used for one session. In my point of view this can get a very hard to find security hole!
ctx.getContextData() does not work for me, it always returns null!
I also tried TransactionSynchronizationRegistry, but I get null as well.
The only thing that worked is using JAAS as a workaround.But it is not a nice solution.

Controlling timed execution in Spring-based Pojo in Java EE

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

Stateless Session Beans vs. Singleton Session Beans

The Java EE 6 Tutorial says:
To improve performance, you might choose a stateless session bean if it has any of these traits:
The bean’s state has no data for a specific client.
In a single method invocation, the bean performs a generic task for all clients. For example, you might use a stateless session bean to send an email that confirms an online order.
The bean implements a web service.
Singleton session beans are appropriate in the following circumstances:
State needs to be shared across the application.
A single enterprise bean needs to be accessed by multiple threads concurrently.
The application needs an enterprise bean to perform tasks upon application startup and shutdown.
The bean implements a web service.
But what to use if:
no state has to be shared across the application
a single enterprise bean could be accessed by multiple threads concurrently
no tasks on startup or shotdown need to be performed
Say for example I have a login service with the following interface:
public interface LoginService {
boolean authenticate(String user, String password);
}
Should it be annotated with #Singleton or #Stateless? What are the benefits of the one and the other? What if LoginService needs to get injected an EntityManager (which would be used concurrently)?
Addition: I'm thinking about the Java EE counterpart of Spring service beans, which are stateless singletons. If I understand that correctly the Java EE counterpart are #Stateless session beans and #Singleton Beans are used to configure the application at startup or cleanup at shutdown or to hold application wide objects. Is this correct?
I would go for Stateless - the server can generate many instances of the bean and process incoming requests in parallel.
Singleton sounds like a potential bottleneck - the default #Lock value is #Lock(WRITE) but may be changed to #Lock(READ) for the bean or individual methods.
according to the ejb 3.1 spec, page 110, chapter 4.8.5 "Singleton Concurrency":
It is legal to store Java EE objects that do not support concurrent access (e.g. Entity Managers, Stateful Session Bean references) within Singleton bean instance state. However, it is the responsibility of the Bean Developer to ensure such objects are not accessed by more than one thread at a time.
and furthermore, according to the hibernate entitymanager documentation
An EntityManager is an inexpensive, non-threadsafe object that should be used once, for a single business process, a single unit of work, and then discarded.
For me, this means, that you should never inject an EntityManager into a singleton EJB. I would use a singleton EJB as a replacement for a stateless EJB only if EVERYTHING I need to implement in this class supports concurrency without the need to do additional locking / synchronization. As you or other programmers might lose this issue sooner or later from your focus, I personally prefer to not use singleton EJBs except for startup-related issues or features that can be implemented as self-contained units - independently of other beans. In that sense, it doesn't seem to be advisable to inject for example Stateless EJBs into Singletons. Doing so raises the question about the point in time, when the container actually performs the injection of the SLSB into the Singleton? According to the EJB 3.1 Spec, chapter 4.8, the dependency injection gets done before the singleton bean instance can be accessed by clients. So the singleton would obviously stick to the same instance of the SLSB, which seems to become a singleton implicitly, but there doesn't seem to be any guarantee for that. At least I couldn't find anything in the specs, so the behavior might be unpredictable or in the best case container-specific, which is not what most people will want.
Thus, I would only inject Singletons into Singletons or Singletons into SLSBs but not vice versa. For the case of an injection of a Singleton into a Singleton, the Spec offers you the opportunity to define the dependencies between the singletons so that the container can initialize them in the correct order (see the ejb 3.1 spec, chapter 4.8.1 concerning the #DependsOn annotation).
#Stateless will allow you to have multiple copies ready for processing within a JVM (as much as memory and pool size allows) where-as #Singleton there's only one copy in a JVM, even if the single one can support multiple concurrent threads running against it.
In terms of performance #Singleton would be better, provided that the resources it uses allow long running access. However, in a distributed environment sometimes bad things occur, e.g. database or network links may fail.
With a #Stateless bean, the access is more short lived. In addition, should there be a failure it will just respawn and try to establish a new connection to the resource. If something happens like that on a singleton, then it's up the the singleton to handle it without requiring an application restart because the #PostConstruct is only called once per JVM.
I would prefer a bit of fault tolerance vs performance for most situations especially on systems I have no control over.
I think Singleton in concurrency usage will not perform worse than SLSB Pool, it might be even better. The only problem is if you want to share something between threads, you need lock it, and that could be a big problem of performance. So in that case, a SLSB Pool perform much better, because it's not 100% singleton, there are more instances, one got locked, the other one comes up. Anyway if the lock is on some resource sharing by all SLSBs, the pool won't help neither.
In short, I think singleton is better than SLSB Pool, you should use it if you can. It's also the default scope for Spring Beans.
I'm not a JavaEE expert, that's just my feeling, please correct me if I'm wrong.
I think you should use Singleton session bean. Because a login service should be a global service and it does not need to store any state for a concrete user or invocation.
If you're sure you're not sharing state between threads, then a Singleton will be fine in which case you should also annotate the class with #ConcurrencyManagement( ConcurrencyManagementType.BEAN ) which will allow multiple threads running at the same time.
you should go for Singleton if you have any resource that is going to remain constant across the application. Like loading some data from some file or reference data which would not change across the application lifecycle. otherwise, go for SLSB. The drawback of SLSB is that multiple objects would be created hence more memory would be occupied.
Imho I would answer like that:
"no state has to be shared across the application" leads me to stateless bean because of the sentence "To improve performance, you might choose a stateless session bean...".
Considering "a single enterprise bean could be accessed by multiple threads concurrently" you would have to use singleton. If I got it right it is not even possible to access a stateless bean's concurrently when properly used.
"no tasks on startup or shotdown need to be performed" would not matter to me. If tasks have to be done to properly setup a bean then they have to be invoked by a #PostActivate method.
I would logically conclude your question what to use to #Singleton since you asked for concurrent access. Of course you will have to manually control snychronisation of accesses on any further resources (which are not EJBs).

java ejb3 #PostConstruct

I am experimenting with EJB3 on JBoss, developing a stateless bean. Basically once the module has been deployed I need to perform some actions related to load application settings.
To do this I've annotated a method as #PostConstruct, which as far as I know from the API instructs the container to invoke it once the bean has been deployed and before get in service. (correct?)
Now, I am confused, because from the log on that method looks like is not simply called after has been deployed but before each exposed method is called.
I only need to call that method once, not every time it receives a call. What would be the best approach?
Thanks in advance
Alessandro Ilardo
A stateless bean should be just that - stateless. Meaning that in use, you should neither be able to tell or to care if the bean was pulled from a pool or constructed on demand for your request. I'm hard-put to envision how a PostConstruct could apply to a stateless environment, since I always use that function to finish building a bean's state.
Apparently, JBoss is either forgoing the pooling of stateless beans and constructing them fresh each time, or, if it is using pooling, treating them like they were reconstructed each time (since they shouldn't be carrying state information). I'm actually a little surprised that it invokes the PostConstruct at all.
First of all PostConstruct is called before first method will be invoked on the bean. If no method will be invoked no post construct ever be called.
Secondly you can execute inverse actions in PreDestory method to remove side effects.
Anyway which kind of action you have to perform?
It is up to the app server to manage the lifecycle of EJBs. It may decide to construct, initialise and tear down beans whenever it sees fit. It may be that each call to your stateless bean is on a fresh instance of the your bean class, although that does seem like an off thing to do.
Is the app server calling the #PostConstruct method multiple times on the same object instance, or on a different instance each time? Try sticking log statements inside the constructor and the #PostConstruct method.
How many SLSB do you have in your pool? Depending on the container the #PostConstruct may not be called until the first client accesses it (not sure about JBoss) so this may be why it looks like it is on every access. It would be interesting to see if it stopped calling your post-construct method after calling your method the number of times equalling your pool size.
If you are performing some expensive actions in your post-construct method then maybe do these in a SFSB at startup and "inject" that SFSB into your SLSB in the post-construct.
PostConstruct gets called before the client runs a biz method. This means that if the bean isn't pooled the container will instantiate the bean, do injection, call the #PostConstruct method, then allow the biz method to run.
In the case of a pooled be then the #PostConstruct method will be run every time the bean is pulled from the pool. With Stateless beans this will be between every method call. With Stateful beans this will be after client lookup or injection.
If you need to run something on application deployment your options will depend on the version of Java EE you have.
For Java EE 6 you can use #Startup on a #Singleton EJB which contains a #PostConstruct method.
For Java EE 5 and previous you'll have to use a ServletContextListener in a web archive. You can have the ServletContextListener call an EJB if you want.
However what might be a more important question is where do you want to load these application settings to? If you are dealing with a non-clustered single JVM configuration then you probably going to want to load them into a Singleton of some type. In Java EE 5- you'll have to implement the singleton design pattern yourself or in EE 6 use the #Singleton EJB type.

Service References in OSGi

Once an instance of an OSGi service is retrieved from the bundle context does it become invalidated when the service is stopped?
My initial tests show that the service instance can be used even after the service bundle is stopped, which contradicts my understanding of the dynamic nature of OSGi.
I suppose this boils down to what retrieving a service (via ServiceTracker) from another bundle in the OSGi container actually does, does it create a new instance or does it give you a pointer to the instance that is registered in the container?
Are there any dangers in using the service instance after the service has been stopped?
This is a very good question so I digged into the specification in search for a definitive answer. It turns out that there is a whole section talking about this problem - see section 5.4 Stale References starting on page 132 of OSGi Service Platform Core Specification, Release 4, Version 4.2.
To answer your question according to the specification:
The behavior of a service that becomes unregistered is undefined. Such services
may continue to work properly or throw an exception at their discretion.
And to prevent potential problems:
Bundles must listen to events generated by the Framework to clean up and remove stale
references.
The specification also gives some tips how to minimize the consequences of stale references.
You are right in that it is contradictory to the dynamic nature of OSGi. I believe that there is no guarantee that the service will be available, although different implementations of OSGi containers and services themselves may behave differently.
For example, if the service was created and registered with Spring DM, then the service retrieved is actually a Spring based proxy to the underlying implementation, and the implementation can still disappear. Thus a service reference that refers directly to an implementation may keep that object from being removed, whereas the proxy based reference will not.
The OSGi specification says:
Bundles are entities that are visible
in normal application programming. For
example, when a bundle is stopped, all
its services will be unregistered.
So you shouldn't be able to get a service from a stopped bundle. But technically it may be possible to use it, at least as long as you hold a reference to the service object (nobody can take it away from you and it will not be GC'd). But I don't think that it is save to use the service. It may depend on other bundle resources, that are not available after the bundle has stopped.
Once an instance of an OSGi service is
retrieved from the bundle context does
it become invalidated when the service
is stopped?
No, the reference itself does not become invalidated. As long as something within the container is holding it, it can also not be GC'ed.
However, whether or not it will be still useful, depends only on the service implementation itself, not the container.
My initial tests show that the service instance can be used even after the service bundle >is stopped, which contradicts my understanding of the dynamic nature of OSGi.
The specifications itself indicate that such references shouldn't be held, but it's up to the implementer to take care for implementing the specifications correctly; means there is no contradiction, there is only the fact that you can implement and deploy bundles which don't behave correctly according to the specifications.
I suppose this boils down to what retrieving a service (via ServiceTracker) from another bundle
in the OSGi container actually does, does it create a new instance or does it give you a pointer
to the instance that is registered in the container?
The container does not create new instances of services, except if there is a ServiceFactory involved (see specs). Looking up a service should always give you a pointer to the registered instance in the container.
Are there any dangers in using the service instance after the service has been stopped?
That only depends on the service implementation; however, by doing so in a bundle, you automatically create a bundle that is not conform with the specs.
In practice, many services are implemented to release resources and references and will not respond properly any longer.
Regarding your question whether it is dangerous to use a service instance after the service has been stopped. To cite from the 4.2 core spec (5.4 Stale References):
The behavior of a service that becomes
unregistered is undefined. Such
services may continue to work properly
or throw an exception at their
discretion.
I dont want to cite the whole section of the spec here, but the following sentences are a good discussion about the danger of using stale references:
A stale reference is a reference to a Java object that belongs
to the class loader of a bundle that is stopped or is associated
with a service object that is unregistered. Standard Java does not
provide any generic means to clean up stale references, and bundle
developers must analyze their code carefully to ensure that stale
references are deleted.
Stale references are potentially harmful because they hinder the Java
garbage collector from harvesting the classes, and possibly the instances,
of stopped bundles. This may result in significantly increased memory
usage and can cause updating native code libraries to fail. Bundles using
services are strongly recommended to use either the Service Tracker or
Declarative Services.
A service reference should never be kept as a reference. You should always look up a service at runtime. This ties you to the OSGI api however, whihc is not always wanted.
Have a look at
- OSGI serviceTracker
- OSGI declarative services
- OSGI BluePrint
- Spring DM
- Peaberry
- iPojo
which all take care of the dynamism for you, most of them with no OSGI api to use.
Regards,
Leen Toelen

Categories

Resources