Continue to load webapp even if one spring bean initialization fails - java

So if spring initialization fails in a webapp then the webapp itself does not come up. To prevent this, I can probably not re-throw any exception from my code for that specific bean initialization and the webapp will continue to load, right?
Is there any other way to tell to spring not to fail the webapp itself on particular bean initialization failure?

Continue to load webapp even if one spring bean initialization fails
AFAIK, you can't do this.
I do multiple DNS lookups on start up. I do not want the webapp to fail if one of them fails.
In that case, you need to modify your bean(s) to handle the case where the DNS lookup fails, leaving the bean instance in a state where it is essentially inactive but harmless, or where it can retry the DNS lookup later on.
In short, you have to cope with this yourself.

Have attribute lazy-init="true" in that bean and every dependant bean. Link for more details.

why would you do this? If your spring context is not correct, something is seriously wrong and there will be issues. The correct way to deal with this is to fix the application context.

Related

"A component required a bean of type", but which one?

As the title mentioned, I have a A component required a bean of type [SomeBean] error and I would like to know which component requires [SomeBean]. Is there a way to get more information on which bean requires the missing one?
Also, why do I get this error message? I am pretty sure that sometime missing beans generate a clearer message stating what beans require the missing ones.
Why I am asking:
I am trying to make a spring application that is similar to another (working) one, and use many similar beans. But I have trouble following the bean dependencies. So I removed one bean of the working application and run it in order to know where and how this component is used.
=> So, in general, I am looking for good ways to track bean dependencies in complex contexts.
Some time my IDE (intellij ultimate 2019) gives me some information, but here it doesn't. Maybe because the dependencies span a few packages, many being outside the application code, and use AutoConfiguration. Don't know...
If I use the spring diagram, it generates something that is not really readable (too meany beans). And the diagram is more a list of found beans structured by where there are provided, not the bean dependency diagram: my application list the beans it provides, and the autoConfig list the beans it provides. But It doesn't tell what bean of the autoConf is using which bean that my app provides. Or maybe I just don't understand how it works.
The default log configuration echoes messages to the console as they are written. By default, ERROR-level, WARN-level, and INFO-level messages are logged. You can also enable a “debug” mode by starting your application with a --debug flag.
So, indeed, you should enable that debug mode to see a more detailed log information about your error, which seems to be a missing required bean dependency.
See some more detailed info about in Spring Loggin

Prevent Spring from Failing if One Bean Fails

We have an application that creates beans on startup using Spring's AnnotationConfigApplicationContext. What we're trying to do is not have Spring destroy all the beans created and thus cause the app fail on startup if creation of one of the beans fails. Is there any native Spring config or way to accomplish this?
I tried overriding the AnnotationConfigApplicationContext with my own Custom AnnotationConfigApplicationContext and catching exceptions within there. What was happening though is when an exception was thrown, all remaining beans were not created.
We're using Spring 4.3.0.
easy way to deal with this is by lazy initialization of bean using attribute lazy-init="true" in your bean declaration

Is there a way to have spring run additional code at application startup failure?

We have a spring web-application running on a Tomcat server that we would like to have some additional code run ONLY if there is an issue with the webapp's startup.
However, any errors we receive will come from either Bean Creation Issues (which, hopefully we would catch before ever releasing) or a Flyway upgrade script issue. Both cases, the exceptions are caught within the spring core somewhere, and I'd like to run some additional code in those situations before the webapp failure finishes. I'm not 100% sure how to set this up though, considering where the exceptions are thrown.
I've been looking at Spring's Life Cycle configuration annotations, and while I have considered running the code in the #PreDestroy method we're providing, that means it would run our code every time we restarted the webapp, instead of just on startup failures. Is there a way to indicate the differences between a normal shutdown and a failed startup using the life cycle annotations?
You could register your own ServletContextListener instead of the Spring's one and delegate contextInitialized method invocation to the Spring implementation you use for loading Spring context (whichever one you use, for example org.springframework.web.context.ContextLoaderListener).
Then catch and handle the desired exceptions.

Genetrate "Event Scoped" beans out off the application scope

I am a newby with CDI and EJB and I've just created a jboss web application. Though, additionally, I also wanted this app to process rabbitmq messages. When processing these, I would like to do some persistence work, though, as I've been listening for rabbitmq messages from an application scoped bean that is started with the #Startup annotation, I've not been able to commit any transaction within this kind of scope, that is, as I am departing from the application scope, every bean that I will instatiate from this scope will be application scoped. When I try to perform em.getTransaction() and em.commit() the code blows up complaining that I cannot invoke getTransaction() under JTA transactions, and when I use User transactions, every operation seems to be put onto the same transaction until it finally is rolled back, or there errors complaining that there is a already a transaction underway...
CDI beans do not support transactions out of the box like EJBs do. So your options are to either:
Upon receiving RabbitMQ messages, call some EJBs (directly or through observers) that will do the persistence work.
Add transactions support to your existing CDI beans using one of the following - Apache DeltaSpike or Seam Persistence.
It is indeed quite hard to give you more details based on the info you provided. However, on the conceptual level, one of the approaches above would do the trick.
Also, the notion of event scope seems confusing. I would say you don't need it. One of the approaches above will do. Also, take a look at CDI events.

Can I dynamically load additional Spring configuration files into an existing WebApplicationContext?

Upon starting my webapp within Tomcat 6.0.18, I bootstrap Spring with only what is necessary to initialize the system -- namely, for now, database migrations. I do not want any part of the system to load until the migrations have successfully completed. This prevents the other beans from having to wait on the migrations to complete before operating, or even instantiating.
I have a startup-appcontext.xml configured with a dbMigrationDAO, a startupManager which is a ThreadPoolExecutor, and lastly, a FullSystemLauch bean. I pass a list of configuration locations to the FullSystemLaunch bean via setter injection. The FullSystemLaunch bean implements ServletContextAware, gets a reference to the current WebApplicationContext and thus I can have a ConfigurableListableBeanFactory. Unfortunately, this bean factory isConfigurationFrozen() returns true, so by calling beanFactory.setConfigLocations(configLocations) has no effect.
Can I accomplish this or is Spring preventing me from doing so because it's a bit out of the ordinary? It seems reasonable if understood, but also a bit dangerous. And yes, I'm willing to blow away the current context b/c the currently loaded Singletons are not needed once initialization is complete.
Thank you for the help.
My opinion would be to allow Spring to initialise your beans is it sees fit - in the order of their declared dependencies.
If you need database migrations there are a couple of patterns to have them run first:
if you're using Hibernate/JPA make your sessionFactory/persistenceManager depend-on the migration beans;
if you're using plain JDBC create a wrapper DataSource and in its init-method invoke the migrations ( code sample)
The advantage is clear: simplicity.
You could use the existing context as parent context for the other contexts, although I doubt that you could replace the existing WebApplicationContext.
If you use EAR - WAR packaging, you get this out-of-the-box (sort of) by loading an application context from the EAR and then adding one in the WAR.
Not sure whether this is applicable in your situation.
Could lazy-initialization be an alternative for what you are trying to achieve?
Possible XmlBeanDefinitionReader can help you?
you can upcat the WebApplicatonContext to ConfigurableWebApplicationContext
then use the setConfigurations method.
dont forget refresh;
There was the same task and I created two contexts: startUpContext.xml and applicationContext.xml. In startUpContext.xml there is a bean, which triggers loading of appliationContext.xml. (application context location is configured in startUpContext.xml as a property of a trigger). And finally the trigger replaces locations of the current context and refreshes it:
applicationContext.setConfigLocations(locations);
applicationContext.refresh();
(startUpContext.xml is loaded with a standard spring context loader listener)

Categories