tomcat7, spring 3.0.5, errors, contexts - spring

org.springframework.web.context.ContextLoader, in the event of an exception, does:
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
which looks quite useful, except the servlet context object it is making this call on is not connected, in any way that I can find, to the return value from Tomcat.addWebapp. So when I go looking for this attribute to see whether the startup worked right, I'm thwarted.
Is there a way to connect these two contexts?

Tomcat's documentation says you can get ServletContext from web-app's Context:
ServletContext getServletContext()
See JavaDoc on Context.

Related

How to make SmartLifeCycle bean start before SpringCamelContext?

I'm using camel in my application and I want to create a SmartLifeCycle bean which starts before the CamelContext.
In order to do that, I implemented a custom SmartLifeCycle bean with a phase of : Integer.MAX_VALUE - 101.
SpringCamelContext has a phase of : Ordered.LOWEST_PRECEDENCE
On my computer its working great, my bean is started before the SpringCamelContext bean.
But once I deploy on my servers, the SpringCamelContext is started before.
Any idea why ? And how can I make sure my bean is started before ?
Thanks
Edit
Seems like SpringCamelContext is a "LifeCycle" bean and not a "SmartLifeCycle" bean. According to the documentation :
<p>Any {#code Lifecycle} components within the context that do not also
implement {#code SmartLifecycle} will be treated as if they have a phase
value of 0. That way a {#code SmartLifecycle} implementation may start
before those {#code Lifecycle} components if it has a negative phase value,
or it may start after those components if it has a positive phase value.
But I still don't know how to fix this (how can I know if using a negative value would not create some sort of side effects ?) And why is it working on my local computer ?
Edit 2:
The difference was in the management configuration.
If I'm using a different port for the management port, and this use another configuration : DifferentManagementContextConfiguration.
On startup, the method "afterSingletonsInstantiated()" is called on the Configuration and it creates a managementContext which is refreshed immediatly.
This context is refreshed before the main ApplicationContext refresh and before the LifeCycleProcessor is started.
This refresh is initializing SpringCamelContext due to the ContextRefreshedEvent listener in it.
I'm still looking for something to fix this ...
This is a known bug which has been fixed in 2.24.1 camel version

Spring Boot classpath: vs relative path

In Spring Boot, to access a resource, say myresource.json, I can use both classpath: or a relative path, like ./myresource.json
What is the difference? Which one should I use?
When you call getResource() on a specific application context, and the location path specified doesn't have a specific prefix like ./myresource.json, you will get back a Resource type that is appropriate to that particular application context.
If getResource() was executed against a ClassPathXmlApplicationContext instance it will return a ClassPathResource.If the same method was executed against a FileSystemXmlApplicationContext instance, you'd get back a FileSystemResource. For a WebApplicationContext, you'd get back a ServletContextResource, and so on.
As such, you can load resources in a fashion appropriate to the particular application context.
On the other hand, you may also force ClassPathResource to be used, regardless of the application context type, by specifying the special classpath: prefix.
See this doc

Exception BeanFactory must be set on AnnotationAsyncExecutionAspect to access qualified executor

I created a public method with #Async and I also have a bean for that class in which this method is created. But when I am calling it , it is not behaving async and getting blocked. Then I created a executor in application-bean and used #Async(value = “executorname”), even this is not working and on every call I am getting “beanFactory must be set on AnnotationasyncExecutionAspect to access qualified executor”.
in my application bean.xml I have
there are then few executors and schedulers and I want to use one new executor.
Please tell me how to get away with this error and get async behaviour
Thanks in advance
I was experiencing exactly the same issue and find out a solution I hope works for you (https://jira.spring.io/browse/SPR-10276).
Apparently if you unabled Spring's AspectJ aspects into your project (by using aspectj-maven-plugin, for instance), Spring's Async mechanism can be placed twice in your bean, one by aspectj and other by proxy. But, since it doesn't know it, AnnotationAsyncExecutionAspect will not be injected with a BeanFactory and you will see the assertion exception you had.
To fix it, you must instruct Spring's Async mechanism to use the AspectJ support. Do this incluing this in your Application Context.
<task:annotation-driven mode="aspectj"/>
I hope I could be of any help.
For annotation based configuration you can use #EnableAsync(mode = AdviceMode.ASPECTJ)

java.lang.IllegalStateException: getWriter() has already been called for this response

I am doing training about CXF and Spring, so I wrote a very simple CXF demo which only has the interface "HelloWorld" and its implementor "HelloWorldWs".
I want to publish it with Tomcat. I wrote a web.xml and applicationContext.xml(Spring profile. Though i can publish the WSDL .But the console list a problem:
Servlet.service() for servlet [CXFServlet] in context with path [/cxf_spring] threw exception java.lang.IllegalStateException: getWriter() has already been called for this response
I did not use or write any io function, just a "sayhi" function. I am stumped.
This is actually a bug and is fixed as part of https://issues.apache.org/jira/browse/CXF-5620,
CXF 2.7.11 (released)

How to refresh the Spring context when using CXF?

We have a web application that uses Spring (3.0.5) and CXF (currently 2.4.2 for various reasons but upgrading is an option if that makes any difference) and is deployed on Tomcat.
The application is initialized using the org.springframework.web.context.ContextLoaderListener.
Starting and shutting the application down works like a charm but if I try to refresh the Spring application context, using
((ConfigurableApplicationContext)applicationContext).refresh();
I run into problems. The application context first destroys all its beans (including CXFBusImpl, or rather its subclass SpringBus). SpringBus however calls close() on its application context - leading to a NullPointerException when the application context shortly after tries to close its bean factory:
java.lang.NullPointerException
at org.springframework.context.support.AbstractRefreshableApplicationContext.closeBeanFactory(AbstractRefreshableApplicationContext.java:152)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:124)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:467)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:397)
Is there anything I can do to avoid this (other than modifying CXF)? If I skip CXF everything works.
I don't think you can tell CXF not to work that way. What you could do though is to isolate the parts of your application that need restarting into their own context that you build and and tear down as you choose without involving the main context over much. Perhaps you'd do that with a ClassPathXmlApplicationContext, though there are a few choices. I think you'll be setting the outer context as the parent of the inner, and referring to outer beans with XML-config syntax like:
<ref parent="foo" />
You'll then need to create some way of proxying the activity with CXF in the outer context to the beans in the inner context. This is the tricky part, as it is usually considered bad form for references to go that way round. You'll probably have to have some kind of registry/proxy in the outer context that (relevant) inner beans connect to as part of their creation/init process (and deregister from at tear-down). You'll also have to decide how to handle the case where a request needs to be served when there is no inner context. Tricky, especially if you want to do it elegantly...

Resources