Stateful Session Bean lifecycle - ejb-3.0

I have a "stateful session bean" that initializes a synchronizedList,i add products to the list and check the list, it works(all during the same session).
Is it normal that when I do the "undeploy" of my application and then make another"deploy" I lose all the saved data of my bean?

It is desired behavior, just imagine what might happen to created SFSB if I would change collection type from list to map and redeploy app.
Actually hot deploy feature is out scope of EJB specification, so session beans might behave differently depending of witch application server you use. For example in weblogic 8 after redeploy of any type of app module, all SFSBeans referefences are lost (stubs are discarded).
Personally I prefer to restart production server after hot deploy, as there always might be some memory leaks (caused by previous classloaders).

Related

How to debug spring boot application not starting

Spring lists SO as the only place to ask questions on their community page, which is why I ask this rather generic question here. It may not be the best fit for SO, but, according to Spring's community overview page, there's no other adequate place to ask such questions.
I have a spring boot application built on spring cloud gateway (version 2) which also uses an embedded hazelcast cluster. It runs in multiple instances, which communicate via hazelcast. Everything works fine, except under heavy load. If one instance fails, restarting it is no longer possible.
When the instance is restarted while the cluster of instances is under heavy load, it will start creating and wiring beans, up to some point, after which it will not do anything spring-related anymore. Hazelcast-generated messages are visible in the log (with root log level DEBUG), past that point, but nothing generated by spring or the application itself.
In order to restart that one instance that failed, I need to stop the load generation, wait some 10-15 minutes, then restart the failed instance. Then the new/restarted instance starts up rather quickly, with no problems at all.
The load consists of http requests which get proxied to another application, and is of such nature that it generates a lot of read accesses to hazelcast's distributed storage, but very few writes.
My problem: I have no idea how to debug this. Since the http endpoint never becomes available, there's no way I can query metrics or other actuator information.
So my question is: what tools or mechanisms can I employ to debug this problem? I.e. how can I find out exactly how the boot sequence under heavy load of the other instances of the hazelcast cluster differs from the boot sequence when there is no load at all in the cluster? Once I have this information, the problem is narrowed down enough for me to investigate it further on my own.
I didn't find a way to debug the problem, but had an idea of what might cause it, tried it, and it was a fix.
My application was running as a Kubernetes deployment. A few beans inside the application were relying on a usable CP subsystem during their initialization. Spring's bean initialization process is by necessity sequential and blocking, to account for inter-bean dependencies.
I hypothesized that under heavy load, for whatever reason, the initialization of those beans was blocking forever. As a first experiment, I made that initialization code async, so that Spring can finish bean wiring, even if, until that async part finished too, the instance was unable to perform usable work, to see if that was the problem, at least.
To my surprise, that fully fixed the problem. This way, Spring finished bean wiring, the HZ-dependant initialization also finished rather quickly, when executed async, even under high load, and the instance became usable soon after being started.
I didn't have the time to dig deeper to find out what the precise failure mechanism was. What I believe might have been the problem is the interaction between HZ and K8s. K8s-based discovery works using a K8S service. A pod/instance isn't added to the service until it becomes healthy. If a bean inside the application prevents initialization, the instance is never added to the service. As such, discovery never finds the new/restarted instance. I don't know what effect this might have on the HZ cluster's inner workings.

Bootstrapping and re-initializing application with Java-based configuration

I've been looking for someone else doing this same thing, but haven't seen a scenario that's quite like this so I thought I'd see if anyone here has any good ideas on how to accomplish this.
My group builds and maintains an open-source neuroimaging data archive tool called XNAT. Previous versions of our application have always required users to run a builder application that took in a build.properties file and used that to initialize the database server configuration, among other things. We're really trying to get down to a single installable war file that we can make available on the NeuroDebian repository. In order to do this, we need to be able to start the application WITHOUT any database configuration information, run through a configuration wizard a la Wordpress or Drupal installations that includes the user inputting the database configuration, and finally setting this configuration information SOMEWHERE and re-starting or re-initializing the application context so that it gets its data source started up, Hibernate entity scans run, all auto-wired or injected dependencies that require the data source or Hibernate transaction manager resolved, and services scanned for #Transactional annotations, and so on.
I can easily see how we can use the new Spring Framework WebApplicationInitializer to detect whether the user has already set up the database configuration and initialize the app properly based on that:
If database has not been configured, create an servlet that just supports the UI for the initialization wizard
If database has been configured, create the regular application context
The problem in the first case is what happens once the user has completed the initialization wizard? We can store the database configuration somewhere and now we're ready to go but... how do we get the regular application context working? Can we just take the code that we'd call in the already initialized scenario and call that? Will that initialize the application properly then, with component scans and so on all being handled or...?
The only solution we have currently is to have the user restart the server manually (it's usually Tomcat) or use the server manager application to restart just our application. That's not very aesthetically pleasing though.
My end goal here will be to write a simple test app that takes in the database credentials and then tries to initialize everything else afterwards, but I'm hoping to see if anyone's thought about this particular issue and/or tried it and has any advice on how to handle it. Any help would be greatly appreciated!

Can I create a transient configuration in OSGi using the ConfigAdmin?

I'd like to create a Configuration object in OSGi, but one that won't be persisted, so it won't be there when the framework is restarted. Similar to START_TRANSIENT for bundles.
Some background: I've got an OSGi (Felix) based client side application, deployed over OBR. The configuration object I'm talking about effectively boots the application. That works fine, but sometimes the content has changed while the context was stopped. In that case, it boots the application as OSGi revives all bundles and adds all configuration options. Then I inject the correct configuration, the application stops and then restarts again.
So it does actually work, but the app starts twice, and I can't get access to the framework before it reconstructs its old state.
Any ideas?
As BJ said there is no standard support for this in the Configuration Admin spec.
However the Felix implementation supports two features which may help you. First, you can set the felix.cm.dir property which configures where the configadmin saves its internal state (which by default will be somewhere under the Framework storage directory). You could set this to a location that you control and then simply wipe it every time you start OSGi (you could also wipe out the entire OSGi Framework storage directory on every start... some people do this but it has wider consequences that what you asked for).
Second, if you need a bit more control, Felix ConfigAdmin supports customising its persistence with a PersistenceManager service. You could probably implement this and return empty/doesn't-exist for the particular pids that you want to control.
The OSGi Config Admin spec does not support this. I also do not know of a non-standard means either for any of the CM impls I am familiar with.
Ok, what I did in the end was the following:
I created a special really small 'boot' bundle, which I do not provision from OBR, instead, I install it from the classpath.
That bundle controls the configuration, and I use START_TRANSIENT the moment I really want to load that configuration.
Not exactly pretty, it gets the job done. I do think transient configuration would make sense to have in OSGi.

Scope confusion regarding session beans, proxies, and singletons in a Spring 3 managed JSF app

This seems like it's basic Spring 101 stuff, but I can't seem to find the correct way to do this. The situation is as follows; in my web app there is a single entry point which is a controller that handles users coming from an outside system. The transfer is just a POST request with a bunch of associated information pertaining to that user. Apon entry, I need to create a new User bean and load it with that users information. Additionally, when the user hits a view which triggers some service, I need for that service to be able to access the appropriate User bean instance.
The first way to do this that came to mind was to have a UserManager service which would create a new instance of User, fill it w/ data, and then register it in the Spring container with the username as the bean name. Then when a service is invoked, the service would do something like Factory.getBean(username) to find the appropriate User instance. The problem I see here is that I'm losing the link between the user & which User bean belongs to them. Additionally, I'd like to avoid having the user carry the bean around in the session if at all possible. Is this where I am supposed to be using Spring AOP & proxies?
What is the typical Spring pattern for solving this type of situation?
So it is now many weeks later (since asking this question), and consequently my knowledge level has been expanding exponentially, so I figured I might as well answer my question for anyone who might find it helpful (not to mention the question wasn't very clear to begin with).
The basic answer is: use proxies. Since a singleton is only instantiate 1 time, you cant inject another class which has a shorter lifespan, eg. session scope. For those requiring more information, checkout stateful vs stateless beans. More or less what I ended up doing is this... the services contain STATELESS code for manipulating data (think verbs; RegisterUserSvc, AddPartSvc, etc). The data which these services manipulate is stateful. For instance, each user has a own copy of their own data object, lets say TodoListBean, which is in a different state for each user.
So how does a service, AddTodoItemService for instance, manipulate this data? This is where the proxy comes into play. When instantiated, the AddTodoItemService gets injected with a proxy for the TodoListBean, instead of the actual object. That way when the service needs to access the TodoListBean the container will serve up the a TodoListBean out of the current users session, and therefore the service will be operating on the correct bean (based on which user invoked the service), instead of doing something silly like having numerous copies of the service included in each users session scope.

Can remote stateless session bean references be cached in EJB3?

I am calling a remote stateless session bean from a J2SE application and would like to cache the reference to the session bean in order to reduce the cost of the lookup. Is this ok?
In EJB2 the ServiceLocator pattern was commonly used to cache lookups to remote resources, but EJB3 doesn't have separate EJB Home (which were usually cached) and Remote objects.
Googling around, a common answer to this is to use EJB3 injection, but since I am doing a call to a remote EJB server from a J2SE client, I can't use injection.
Yes, they can be cached. But I don't know if the behavior is defined what will happen should you have a cached reference and the server is rebooted underneath it. You can test that scenario, but the behavior may vary with the container.
If the server goes away, your references become invalid.
As for caching during the normal lifecycle, this should be fine. I've done this for years, both in EJB2 and EJB3, and never had an issue. Generally I just have a static 'LookupServices' class that just looks up the home, or returns the existing one if it's already there - and stores it in a map.

Resources