Using resources from different bundle - spring

I have problems with loading files in SpringDM on Virgo. The reason is of course me, I am doing something wrong.
This is the situation:
bundleA contains a class to perform some generic initialization (fill tables with data from a generic configuration file).
bundleB contains, among others, a more specific version (extends) of the initialization class from bundleA (in spring file, I also specify that class from bundleA is parent of the more specialized class in bundleB)
bundleC is a web bundle, calls bundleB (which in turns first calls bundleA)
However, bundleB/bundleA does not seem to be able to find the configuration file. I get java.io.FileNotFound exception (file does not exist).
I defined the configuration file in bundleA as a classpath resource:
<bean id="myBeanId" class="org.springframework.core.io.ClassPathResource">
<constructor-arg>
<value>configfile.cfg</value>
</constructor-arg>
</bean>
The bean gets created and injected into the initialization class with Autowired annotation. However, as soon as I try to use the file, I get the exception.
Is there any "general" flaw in my approach? Should I be using other Resource loader? Any other suggestions?
If a part of the question is not clear, let me know, I will try to clarify...
Thanks!

Related

spring trying to load environment variable

I have a question about trying to inject an environment variable into my spring mvc controller.
I have an environment variable as follows...
POS_MANAGER_SERVER_REPORTING=myserver
In my spring application context I have ...
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:systemPropertiesModeName="SYSTEM_PROPERTIES_MODE_OVERRIDE"
p:searchSystemEnvironment="true"/>
<bean name="posManagerController"
class="com.mycompany.reporting.controller.PosManagerController"
p:posManagerServer="${POS_MANAGER_SERVER_REPORTING}" />
When I do not define the system variable in websphere the application does not start up properly. When I add the variable it does. But for some reason the value being injected into my controller is null.
Can someone help me with what might be going wrong here? i.e. Why the environment variable is not loaded properly?
Just to give you some more information, the Controller is loaded in the child context (-servlet.xml) using the #Controller annotation but in the parent context (applicationContext.xml) I also have the controller defined as appeared above. My understanding is that spring is smart enough to be able to handle this. I've listed this information just in case this might be the cause of the issue.
thanks
Quote from documentation:
Also, BeanFactoryPostProcessors are scoped per-container. This is only relevant if you are using container hierarchies. If you define a BeanFactoryPostProcessor in one container, it will only be applied to the bean definitions in that container. Bean definitions in one container will not be post-processed by BeanFactoryPostProcessors in another container, even if both containers are part of the same hierarchy.
So, you need a PropertyPlaceholderConfigurer in -servlet.xml file to make it work.

Exporting Spring Bean Service in OSGI- New Instance per Injection Call

I am trying to export a spring bean as service using Spring's application context, I need to have them exported as "prototype" scope, but this is not possible due to OSGi Service registry caching the service as singleton.
Doing some research I came upon a post suggesting to use "session" scope to get around this issue. I am following this tutorial to get this working, but I am stuck with an issue that has to do with class loader not finding an interface.
Here's how I am declaring the bean
<osgi:service id="SimulationExporter" ref="simulationService" interface="org.geppetto.core.simulation.ISimulation"/>
<bean id="simulationService" scope="session" class="org.geppetto.simulation.SimulationService">
<aop:scoped-proxy proxy-target-class="false"/>
</bean>
When exporting the bean to another bundle, I get the following error
Caused by: java.lang.IllegalArgumentException: interface org.springframework.aop.scope.ScopedObject is not visible from class loader
at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:484)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:713)
at org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:117)
The bundle importing the service bean has the dependency org.springframework.aop-3.0.0.RELEASE , and this has also being copied to the virgo repository. Any ideas why would the class loader not find that interface that it needs for scope "session"?
Does your MANIFEST.MF include import packages for aop.scope?
If you are using Apache Felix to generate it try adding something like this:
<Import-Package>org.aopalliance.aop,org.springframework.aop,org.springframework.aop.scope,org.springframework.aop.framework,*</Import-Package>

Injecting static references in Struts action class

Our application contains struts and spring. Struts action classes are also configured as spring beans in applicationContext.xml. Spring class references are wired to action classes using 'property'.
For Ex.,
applicationContext.xml
<bean id="sampleAction" class="com.arizona.sample.action.SampleAction">
<property name="sampleManager" ref="sampleManager" />
</bean>
In SampleAction, I got to write a static method where it uses 'sampleManager' reference. So, I have configured 'sampleManager' as static variable. At runtime I got a NullPointerExcpetion at the place where 'sampleManager' is used. I have concluded that 'sampleManager' ain't get initialized.
Can anyone please help me in this regard?
P.S.: I have provided setSampleManager(..) and also tried with #Autowired.
If you find yourself trying to interact with an inherently non-static object (sampleManager) from a static context (method), then your design has some fundamental flaw in it. Go back and refactor your solution to employ proper OO design, don't try to fix it with some ugly hack.

Spring Instantiation and 'unused beans'

I'm working on a project which means customising an existing application (JasperServer 3.7.1) which is implemented in Spring 2.5.6 (plus a host of other Spring frameworks).
The application consists of a host of applicationContext*.xml containing the bean definitions which when wired together by Spring bring the app to life - I think it's a typical Spring app configuration as although it my first experience using Spring, it seems all quite well put together and follows a lot of the examples I have seen on the web and in books..
Because I'm actually modifying an existing application, changing beans like filterChainProxy (because we have our own security model ,for example) I'm wary of changing the actual config files that come with the product - instead, where possible, I'd prefer to add extra appContext config files to the existing ones which override existing beans (ie leave the original config in tact, as much as possible).
This I've managed to do by creating beans implementing BeanFactoryPostProcessor which on pre-bean initialisation allow me to change the existing property values/bean references to custom ones. This all seems to be working fine.
My query is, say I had a bean with a property that referred to another bean, and my overrider bean changed that reference to my own version of bean, will Spring still instantiate the bean that is no longer referred to ? The reason for asking obviously is that some of these unused beans may be taking up resources, which may be an unwanted overhead.
Thanks in advance
I'm not sure I follow your example, but it might help to clarify a few things.
Generally, Spring will instantiate a bean for every non-abstract bean definition in the context (this is ignoring things like non-singleton bean scopes, but I'll ignore that for the purposes of this explanation). If multiple bean definition files are used, and some bean names are duplicated, then some definitions will be overridden by others. so far, so good, this seems to be what you wanted.
Once the bean definitions have been established, and any duplicated dealt with, then Spring will then instantiate a bean for each of those definitions. If you have changed the definition of BeanA so that it no longer refers to BeanB, but instead refers to BeanC, but the definition of BeanB still exists, then BeanB will still be instantiated, even if it's not being used.
If that example is not representative of your question, then please elaborate.

How to call a method after bean initialization is complete?

I have a use case where I need to call a (non-static) method in the bean only-once at the ApplicationContext load up. Is it ok, if I use MethodInvokingFactoryBean for this? Or we have a some better solution?
As a side note, I use ConfigContextLoaderListener to load the Application Context in web application. And want, that if bean 'A' is instantiated just call methodA() once.
How can this be done nicely?
To expand on the #PostConstruct suggestion in other answers, this really is the best solution, in my opinion.
It keeps your code decoupled from the Spring API (#PostConstruct is in javax.*)
It explicitly annotates your init method as something that needs to be called to initialize the bean
You don't need to remember to add the init-method attribute to your spring bean definition, spring will automatically call the method (assuming you register the annotation-config option somewhere else in the context, anyway).
You can use something like:
<beans>
<bean id="myBean" class="..." init-method="init"/>
</beans>
This will call the "init" method when the bean is instantiated.
There are three different approaches to consider, as described in the reference
Use init-method attribute
Pros:
Does not require bean to implement an interface.
Cons:
No immediate indication in source code that this method is required after construction to ensure the bean is correctly configured.
Implement InitializingBean
Pros:
No need to specify init-method, or turn on component scanning / annotation processing.
Appropriate for beans supplied with a library, where we don't want the application using this library to concern itself with bean lifecycle.
Cons:
More invasive than the init-method approach.
Use JSR-250 #PostConstruct lifecyle annotation
Pros:
Useful when using component scanning to autodetect beans.
Makes it clearer that a specific method is to be used for initialisation. Intent is closer to the code.
Cons:
Initialisation no longer centrally specified in configuration.
You must remember to turn on annotation processing (which can sometimes be forgotten)
Have you tried implementing InitializingBean? It sounds like exactly what you're after.
The downside is that your bean becomes Spring-aware, but in most applications that's not so bad.
You could deploy a custom BeanPostProcessor in your application context to do it. Or if you don't mind implementing a Spring interface in your bean, you could use the InitializingBean interface or the "init-method" directive (same link).
To further clear any confusion about the two approach i.e use of
#PostConstruct and
init-method="init"
From personal experience, I realized that using (1) only works in a servlet container, while (2) works in any environment, even in desktop applications. So, if you would be using Spring in a standalone application, you would have to use (2) to carry out that "call this method after initialization.

Resources