-
Notifications
You must be signed in to change notification settings - Fork 38.5k
Support for EAR Parent Context Loader in Spring Framework 5.0 [SPR-16258] #20805
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I am hitting the same issue. there must be some alternative, no? |
Same problem here and no solution so far. |
Hitting the same issue, Any alternative found? |
Why isn't this mentioned in the 4 to 5 migration guide? |
Same blocking constraint here ... if a solution could be found, it would be great. |
Same problem we are facing. Any fix or alternate solution? |
We created a POC shim where we pulled into Spring5 the missing parent context loader. It worked on simple issues but we never got past that, we were pulled onto other projects. It specifically pulled the classes required to restore the BeanFactoryLocator.class. |
facing the same issue. I badly need to upgrade spring from 4 to 5. When can we expect the solution? |
The mechanism was removed in #19720. But maybe @jhoeller could provide some insights how parent context loading should be achieved in Spring Framework 5.x? |
Hi Team, Any help here? |
Im also looking for the solution atleast alternate solution (instead of pulling 4.x classes and putting in our application) .. this is stopping us migrating to 5.x .. our infosec not allowing to use 4.x as its EOL ended 2yrs ago.. :( |
I have currently done the spring migration by adding spring 4 classes in our own application. |
The usage of custom ContextLoaderListeners suggested before in https://stackoverflow.com/questions/54085902/sharing-parent-spring-context-with-child-in-spring-5/54087660#54087660 works fine for us in an EAR project with Spring 5. Imagine a project with the following structure:
fooWeb1.war and fooWeb2.war should both use the same parent context, defined in fooLogic.jarbeanRefContext.xmlcontaining the XML Bean Factory: <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="fooParentContext" class="org.springframework.context.annotation.AnnotationConfigApplicationContext">
<constructor-arg>
<list>
<value type="java.lang.Class">FooParentContextConfiguration</value>
</list>
</constructor-arg>
</bean>
</beans> FooParentContextConfigurationIn this class, a static variable for the BeanFactory was added: @Configuration
//...
public class FooParentContextConfiguration {
//...
public static final BeanFactory FOO_BEAN_FACTORY = new ClassPathXmlApplicationContext("beanRefContext.xml");
//... fooWeb1.warRequired in both wars each: FooContextLoaderListener1.javapublic class FooContextLoaderListener1 extends ContextLoaderListener{
@Override
protected ApplicationContext loadParentContext(ServletContext servletContext) {
ApplicationContext parentContext = (ApplicationContext) FooParentContextConfiguration.FOO_BEAN_FACTORY.getBean("fooParentContext");
return parentContext;
}
} FooWebInitializer1.javapublic class FooWebAppInitializer1 implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext myctx = new AnnotationConfigWebApplicationContext();
//Register your WebConfiguration, if required
myctx.register(FooWebContextConfig2.class);
myctx.setServletContext(servletContext);
// Spring
servletContext.addListener(new FooCustomContextLoaderListener1(myctx));
//...
}
} fooWeb2.warSame as for fooWeb1.war Maybe there's a more elegant way, but currently this seems to work for us without using and adding old Spring4 classes. |
Using a custom In any case, since the old EJB-oriented mechanism is not coming back, I'm closing this issue for good now. |
Just wanted to share some actual code for those trying to figure out how to do this. We're using vanilla Spring 5, without SpringBoot. In our case, we have two WARs sharing the same parent Spring context in an EAR. We have a simple class with two methods for leasing and releasing the shared parent. Simplified/pseudo-code: // Loaded via EAR class-loader
public class EarContextLocator {
private static AnnotationConfigApplicationContext context;
private static int leaseCount = 0;
public static synchronized ApplicationContext lease() {
if (context == null) {
context = new AnnotationConfigApplicationContext(...);
context.refresh();
}
leaseCount++
return context;
}
public static synchronized void release() {
leaseCount--;
if (leaseCount == 0) {
context.close();
}
}
} Each WAR app has a WebApplicationInitializer by extending AbstractAnnotationConfigDispatcherServletInitializer. The problem is that the default registerContextLoaderListener isn't parent-aware. So we override that as follows: public class MyAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
...
@Override
protected void registerContextLoaderListener(ServletContext servletContext) {
// create this app's context
WebApplicationContext rootAppContext = createRootApplicationContext();
// customised parent-aware context loader
ContextLoaderListener listener = new ContextLoaderListener(rootAppContext) {
private ApplicationContext parentContext;
@Override
protected ApplicationContext loadParentContext(ServletContext servletContext) {
parentContext = EarContextLocator.lease();
return parentContext;
}
@Override
public void closeWebApplicationContext(ServletContext servletContext) {
try {
super.closeWebApplicationContext(servletContext);
} finally {
if (parentContext != null) {
EarContextLocator.release();
}
}
}
};
listener.setContextInitializers(getRootApplicationContextInitializers());
servletContext.addListener(listener);
}
} This comment is also available in the discussion of the following blog post: |
sreekanth opened SPR-16258 and commented
I'm unable to upgrade our EAR project to use spring 5.0 only due to the fact that spring is no more supporting the parent context loader, the detail is same as given in the stackoverflow.
I understood it is removed intentionally from the spring core, but this decision is stopping us upgrading spring framework, though we can stick to 4.x of spring core, we were unable to upgrade the modules like spring data (elasticsearch, etc) due to the same reason.
I hope the world is still using non boot and non microservice projects with highest expectation from framework like spring. So, on behalf of all i would like to request spring team to add support for parent context loading back to spring project.
If its not possible, request someone to provide an alternative solution as a documentation or as an example on how to achieve this.
Affects: 5.0 GA
Reference URL: https://stackoverflow.com/questions/46902115/spring-framework-5-0-0-final-parent-context-not-getting-loaded
The text was updated successfully, but these errors were encountered: