-
1. Re: Accessing app_1's spring beans in app_2's config file
mr_belowski2 Jun 20, 2007 12:33 PM (in response to mr_belowski2)Oops, I'll try the code stuff again...
server_app.spring
->someClasses
->META-INF
- ->jboss-spring.xml
client_app.ear
->webapp.war
->WEB-INF
- ->applicationContext.xml
jboss-spring.xml defines some beans, and I'm trying to access these in the webapp.
jboss-spring.xml contains<description>BeanFactory=(server_app)</description>
then the beans
webapp's applicationContext.xml contains<description>BeanFactory=(webapp) ParentBeanFactory=(server_app)</description>
the some webapp specific bean definitions.
Some of the webapp bean definitions reference beans defined in the server app - e.g.<bean id="someWebAppBean" class="..." > <property name="someServerBean"><ref bean="someServerBean"/></property>
... -
2. Re: Accessing app_1's spring beans in app_2's config file
alesj Jun 20, 2007 6:13 PM (in response to mr_belowski2)Only BeanFactories that are constructed by SpringDeployer can reference beans from parent BeanFactories.
In your case parent BF is constructed by SpringDeployer, but your child BF is constructed by regular Spring ContextLoader.
And only SpringDeployer knows about parent=(<some_parent>) notion.
You can use something like this:public abstract class AbstractJndiContextLoader extends ContextLoader { protected String getJndiName(ServletContext servletContext) { String jndiName = DEFAULT_ROOT_APP_CONTEXT_JNDI_NAME; if (servletContext.getInitParameter(ROOT_JNDI_APP_CONTEXT_KEY) != null) { jndiName = servletContext.getInitParameter(ROOT_JNDI_APP_CONTEXT_KEY); } return jndiName; } protected Context createContext() throws BeansException { try { return new InitialContext(); } catch (Exception e) { throw new ApplicationContextException("Cannot create naming context!", e); } } } public abstract class JndiContextSaver extends AbstractJndiContextLoader { @Override protected WebApplicationContext createWebApplicationContext(ServletContext servletContext, ApplicationContext parent) throws BeansException { try { WebApplicationContext wac = super.createWebApplicationContext(servletContext, parent); bindApplicationContext(getJndiName(servletContext), wac); return wac; } catch (Exception e) { throw new ApplicationContextException("Cannot bind application context.", e); } } protected abstract void bindApplicationContext(String jndiName, ApplicationContext applicationContext) throws Exception; @Override public void closeWebApplicationContext(ServletContext servletContext) { unbindApplicationContext(getJndiName(servletContext)); super.closeWebApplicationContext(servletContext); } protected abstract void unbindApplicationContext(String jndiName); } public class JBossJndiContextSaver extends JndiContextSaver { protected void bindApplicationContext(String jndiName, ApplicationContext applicationContext) throws Exception { NonSerializableFactory.bind(createContext(), jndiName, applicationContext); } protected void unbindApplicationContext(String jndiName) { try { NonSerializableFactory.unbind(createContext(), jndiName); } catch (NamingException e) { LogFactory.getLog(getClass()).warn("Exception unbinding application context.", e); } } } public class JndiContextSaverListener extends InitializerContextLoaderListener { @Override protected ContextLoader createContextLoader() { return new JBossJndiContextSaver(); } } <listener> <listener-class>com.alesj.acme.webcommon.context.JndiContextSaverListener</listener-class> </listener>
HTH,
Ales -
3. Re: Accessing app_1's spring beans in app_2's config file
mr_belowski2 Jun 21, 2007 6:58 AM (in response to mr_belowski2)Ahhhhhh, now it makes sense. I guess i was trying something a little silly :)
Thanks for the info and the code - it's really helped to clarify things -
4. Re: Accessing app_1's spring beans in app_2's config file
gumnaam Mar 12, 2008 9:03 AM (in response to mr_belowski2)Where can I find the class InitializerContextLoaderListener ?
I tried to follow the above code, but I couldn't find InitializerContextLoaderListener anywhere, so I assumed that you were refering to ContextLoaderListener , and substituting InitializerContextLoaderListener with ContextLoaderListener made the code compile, but it doesn't run.
The problem is as per the code for JndiContextSaver, the WebApplicationContext is created by calling super method. And here if the web context's applicationContext.xml has any bean definitions, that refer to a parent bean defi. (in bean factory in the ejb context), then they don't get deployed.
I get bean ref. error, and as a result the WebApplication context creation throws an error.
If the WebApplicationContext is created by a super call, how will the spring deployer make it aware of the parent application context in the ejb container. -
5. Re: Accessing app_1's spring beans in app_2's config file
alesj Mar 12, 2008 9:10 AM (in response to mr_belowski2)The missing code:
public class InitializerContextLoaderListener extends ContextLoaderListener { @Override public void contextInitialized(ServletContextEvent event) { JndiRootApplicationContextLookup.initialize(event.getServletContext()); super.contextInitialized(event); } } public class JndiRootApplicationContextLookup { private static final Log log = LogFactory.getLog(JndiRootApplicationContextLookup.class); public static final String ROOT_JNDI_APP_CONTEXT_KEY = "RootJndiApplicationContextKey"; public static final String DEFAULT_ROOT_APP_CONTEXT_JNDI_NAME = "RootJndiApplicationContextName"; private static String JNDI_NAME; public static String jndiName() { return JNDI_NAME; } public static void initialize(ServletContext servletContext) { String jndiName = DEFAULT_ROOT_APP_CONTEXT_JNDI_NAME; if (servletContext.getInitParameter(ROOT_JNDI_APP_CONTEXT_KEY) != null) { jndiName = servletContext.getInitParameter(ROOT_JNDI_APP_CONTEXT_KEY); } if (JNDI_NAME != null && !JNDI_NAME.equals(jndiName)) { log.warn("Jndi name already initialized with different name: " + JNDI_NAME + " / " + jndiName); } JNDI_NAME = jndiName; } public static Object lookup(String beanName) throws Exception { JndiTemplate jndiTemplate = new JndiTemplate(); ApplicationContext ac = (ApplicationContext) jndiTemplate.lookup(JNDI_NAME, ApplicationContext.class); return ac.getBean(beanName); } }
Try it now, and let me know. -
6. Re: Accessing app_1's spring beans in app_2's config file
gumnaam Mar 12, 2008 10:14 AM (in response to mr_belowski2)The RootJndiApplicationContextName, should that be the context name of the bean Factory in the ejb Context (i.e. parent) or the web Context (i.e. child ) ?
-
7. Re: Accessing app_1's spring beans in app_2's config file
gumnaam Mar 12, 2008 10:30 AM (in response to mr_belowski2)Still the same error. btw, I set the DEFAULT_ROOT_APP_CONTEXT_JNDI_NAME to the parent cotext name. ( I hope that the right thing to do), in both JndiRootApplicationContextLookup and AbstractJndiContextLoader .
Who calls the static lookup method of JndiRootApplicationContextLookup class ? I think the initialize method of JndiRootApplicationContextLookup is missing something. from what I can see, it only sets the value of JNDI_NAME variable . Should it not call the lookup after that ? -
8. Re: Accessing app_1's spring beans in app_2's config file
alesj Mar 12, 2008 10:31 AM (in response to mr_belowski2)The idea there is such:
You declare a root context, which is deployed by JBoss SpringDeployer.
Then you might have a child context also deployed by SpringDeployer.
But you also want to have a web context that is also a child of that root context.
e.g. having some common beans declared in the root
So, by that RootJndiApplicationContextName should be the name of the root context.
But it's been a while since I did this, so don't pull my leg if I got it wrong. :-) -
9. Re: Accessing app_1's spring beans in app_2's config file
gumnaam Mar 12, 2008 11:02 AM (in response to mr_belowski2)OK so I am on the correct path, I have decared the root context correctly, but I still can't get access to the beans defined in the root context.
As I said in my previous email, the "initialize" method of JndiRootApplicationContextLookup , should probably call the lookup method or something. As it is right now, it's doing nothing but initializing a string. and no one is calling the lookup method. -
10. Re: Accessing app_1's spring beans in app_2's config file
gumnaam Mar 12, 2008 12:13 PM (in response to mr_belowski2)OK here's an alternate approach that worked for me.
Simply extend the ContextLoader and override the loadParentContext method.
In the load parentContext method, look up the root context from JNDI and retrun it.
No need to have any more classes, no need to add description elements to any spring xml file. -
11. Re: Accessing app_1's spring beans in app_2's config file
alesj Mar 12, 2008 12:34 PM (in response to mr_belowski2)"gumnaam" wrote:
No need to have any more classes, no need to add description elements to any spring xml file.
I know I had reasons why I hacked all those classes, just can't remember them now.
I'll try an dig that code up ... it's been a while like I said ... :-)