Injecting static references in Struts action class - spring

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.

Related

#Resource not injected sometimes in Spring

I have a Spring/Struts2 problem and I have asked in Spring forum but no response
#Resource no injected sometimes
for the ease of reading I will repeat the question here. hopefully its not considered spamming
I have a very strange issue when I use #Resource to inject beans.
I am using Struts2 2.2.3.1 with provided Spring plugin with Spring 3.0.0. (I am not able to upgrade to the newest version of Spring without knowing the proper cause because all programs are in production)
The issue or observed problem is when an Struts2 Action is created, the fields annotated with #Resource are supposed to have resources injected by Spring. However, some times and only sometimes one of the annotated resources is not inject or the value is simply null and therefore causes NullPointerException. The point where problem occurs is undetermined which mean the same set of programs running in different environment will result in different behaviors. Also the resource that is not injected is not always the same.
For example, if there are actions A, B, C, and environment E1 and E2, in E1 the A action might have this problem sometimes and in E2 it might be action B that's having the problem. One thing that's certain is that if in E2 B is having problem it will happen from time to time and A and C wont have problem or at least the problem just not observed on A and C. Moreover, if A has 5 #Resource fields, when the problem occurs the NPE may be thrown when accessing the first resource however the next time may be the second resource.
Here is what I mean by the problem only happens "sometimes". Suppose A is having this kind of problem, and I start web server (tomcat or WAS) and I go access A for the first time if the problem occurs it will occur throughout the time of this server start-up. If the problem doesn't occur the first time I access A then throughout the time of this server start-up the problem wont occur. Also if this time it's the first resource not injected then it will be the same for this start-up.
Here is a bit of my application setup:
I use XML inter-mixed with annotation scanning. Basically all Action, Service, Dao classes are defined in XML however all property definitions are left out for Spring to scan the actual class.
Sample definition:
Code:
<!-- have this in all XML files -->
<context:annotation-config/>
<!-- an action definition, all actions are scoped prototype. It will use adm.common.admBranchesManager in the action with field annotated with #Resource -->
<bean id="adm.common.chooseBranchAction" class="com.bi.wms.adm.common.web.ChooseBranchAction" scope="prototype"></bean>
<!-- all service and dao are singleton and do not have any problem, all service/Manager are annotated with #Transactional. In Action we only code against interface and not actual concrete class -->
<bean id="adm.common.admBranchesManager" class="com.bi.wms.adm.common.service.impl.AdmBranchesManagerImpl"/>
<bean id="adm.common.admBranchesDao" class="com.bi.wms.adm.common.dao.jdbc.AdmBranchesDaoImpl"/>
Also for all actions they all extends an abstract action that has a resource field that's session-scoped.
Code:
<bean id="base.wms.login" class="com.bi.wms.common.model.WmsLogin" destroy-method="logout" scope="session">
<aop:scoped-proxy />
<property name="admUserSessionsManager" ref="adm.operation.admUserSessionsManager"/>
</bean>
Here is a part of a sample action:
Code:
//this class is just a sample not the actually one thats having the problem, AbstractWmsAction is the class that have a session-scoped bean
public class AdmWmsControlAction extends AbstractWmsAction
{
#Resource(name = "adm.operation.admWmsBatchGroupsManager")
private AdmWmsBatchGroupsManager admWmsBatchGroupsManager;
#Resource(name = "adm.operation.admWmsControlManager")
private AdmWmsControlManager admWmsControlManager;
//sometimes we use setters for injecting but that doesnt stop the problem from happening
//....omit
}
Don't know if anyone had this kind of issue.
If additional information is needed, I will do my best to provide.
Thanks
I've seen similar issues before with Spring using annotations. Which is why I prefer to use #Transactional in limited situations. Which classes are annotated with #Transactional? The implementation or the interface?
I've only looked at this quickly through the debugger, but I think you may be ending up with multiple beans, one Spring proxy created with the #Transactional -- ly annotated class, and the other defined in your application context. I would suggest that if you are defining the service in the Spring configuration file, you also define the transactional proxy there as well, and inject the proxy by name with your #Resource annotation, OR remove the configuration in xml, and inject by type in your annotation. This way, you'll be notified by Spring if you have duplicate matches by type that cannot be resolved.
to make a note here
after these time I have not found the real cause and solution.
However, time has proven that upgrading to Spring 2.3.3 or later solves the problem or at least the problem has not appeared yet

Using EasyMock 3 IMockBuilder with Spring

I've been looking into using EasyMock 3's IMockBuilder as a means of generating partial mocks (I know partial mocking may suggest a design flaw, but I'm writing tests for old code). Presumably I can use the deprecated static EasyMock.createMock() methods to create beans in my Spring config, like this:
<bean id="myBean" class="org.easymock.EasyMock" factory-method="createMock">
<constructor-arg value="org.mypackage.MyClass.class" />
</bean>
When creating a partial mock using an IMockBuilder, I need to make several calls to addMockedMethod() in order to define the methods I want mocked. Is there a way I can do this in a Spring XML configuration file? Ideally I'd like all the dependencies of all my beans set by Spring, and don't want to have to override them in my test cases in order to pass in mock objects created in this way.
Thanks
No, XML config isn't capable of that sort of flexibility.
You have two options:
Write an implementation of FactoryBean which creates the mock, configures it, and returns the mock to Spring. See Customizing instantiation logic with the FactoryBean Interface.
Use #Configuration-style configuration in Java, instead of XML style configuration. This is the most flexible approach, and is generally better than XML config. See Java-based container configuration

Custom spring interceptor

I want to convert some of our internal API into a spring bean spring interceptor that we can use in other projects. This API needs some instantiation and other logic which I want to encapsulate in this bean so that we can just put the bean into our app context with necessary propoerties alone, and this will then apply the logic.
I remember having read an article on this somewhere in the past - but cant find it now.
Any pointers to something similar will be helpful
EDIT: Sorry, I meant a spring interceptor, not a bean - my bad - please see my edit. I want to apply this interceptor to another bean dealing in XML messages.
EDIT 2: ANSWER FOUND
found it!
I found the answer to this - we were looking to insert the interceptor at the point where we were calling our webservice. So I looked at the interceptor package in spring-ws and found this end point interceptor interface. We will now implement this interceptor and put our processing logic in the appropriate handle*() method.
http://static.springsource.org/spring-ws/sites/1.5/apidocs/org/springframework/ws/server/EndpointInterceptor.html
As with everything in spring, there are a million ways to implement AOP. Check out the spring doco on AOP, the section on declaring aspects in xml may be the most convenient in your situation. You can configure an aspect
<aop:aspect id="myAspect" ref="existingBean">
<aop:before pointcut="execution(* com.package.to.intercept.*(..))" method="existingMethod"/>
</aop:aspect>
Or you could create new classes that use the AspectJ annotations and use those aspects to farm off to your actual work to your existing beans.
Found it!
See this link - http://static.springsource.org/spring-flex/docs/1.0.x/reference/html/ch02s09.html
This gives the interface that you need to implement and the XML definition.
Found a more suitable answer - see the edit in main question.

Is there a spring lazy proxy factory in Spring?

Wicket has this device called a lazy proxy factory. Given:
<property name="foo" ref="beanx"/>
the idea is to auto-generate a proxy in place of 'beanx', and then only initialize beanx if and when something actually calls a method on it.
It seems as if this might be a core Spring capability. Is it there somewhere?
See LazyInitTargetSource; that might do what you want. It requires use of lazy-init="true" on the target bean as well, though.
Spring singleton beans, the closest thing to what you want, are created when the spring context is initialized: http://static.springsource.org/spring/docs/2.0.x/reference/beans.html#beans-factory-scopes. So I believe the short answer is "no." You can implement your own scope to do this by extending the Spring classes quite easily, though.
Spring session/request scope is implemented using the technique you describe, but it is only intended to handle transitions between scope cardinalities, not instance creation. So spring uses the same concepts, but you'd probably have to create your own implementation.

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