EJB 3 Sessioncontext in Spring Beans - java

Background:
I am using programmatic authentication (basic authentication) using java security.
I have a Stateless session bean(EJB 3). I can inject the Sessioncontext to get the security Principal, to get the user name.
In the same project I am using spring beans for JDBC and Aspect. I want to get the user name in one of the aspect(Audit) which is also a spring bean.
Question:
Is it possible to access the ejb sesssioncontext in the Spring bean. If so how to do that?
If no, how can the username be accessed from the Spring bean which is also an aspect.
Thanks,
Amit

This can be done by injecting the EJB into the spring bean. You can do it through a manual JNDI lookup (like you would in any other EJB Client) or use Spring's JndiObjectFactoryBean. With Spring's JndiObjectFactoryBean:
Inject the SessionContext into the EJB
#Resource
private SessionContext ctxt;
//getter and setter
Configure the factory bean in your bean configuration file. postageService being the EJBRef we're interested in (Configuration poached from Apress Spring Recipes)
<bean id="postageService class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.initial">
org.apache.openejb.client.RemoteInitialContextFactory
</prop>
<prop key="java.naming.provider.url">
ejbd://localhost:4201
</prop>
</props>
</property>
<property name="jndiName" value="PostageServiceBeanRemote"/>
</bean>
Wire the ejb reference into your spring bean
public class PostalServiceClient{
//wired EJB
private PostageService service;
//getter and setter
private SessionContext retrieveSessionContext(){
service.getCtxt(); //get the SessionContext from the EJB injection
}
}

kolossus, Thanks for the reply.
There is another way that I could found. Following is the Link to the previous post. So basically I did exactly the same thing :
1) Added the following line to the spring-context xml
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="alwaysUseJndiLookup" value="true" />
</bean>
2) Added following line to the my spring bean to access the EJB's session context
#Resource(mappedName = "java:global/TopoServices/MessageRestService!com.myrest.MessageRestService")
private MessageRestService myBean;
Important thing is Jboss 7.1 does not support custom jndi any more unlike Jboss 5 so I used the default jndi.
I think this is more cleaner way to address my requirement.

Related

Understanding spring proxying

The Spring documentation provides the following example to show us the reason why we need to define aop:scoped-proxy explicitly in beans of scope session, reques, etc.
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
We need proxy here, because for each request to the userPreferences bean we want to delegate one to the actual session-scoped bean's instance. That's clear. But the documentation also said that this's a deafult behavior for singletone/prototype scoped beans.
Consider the following example:
<bean id="userPreferences" class="com.foo.UserPreferences" />
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
Why do we need in proxy in the case of singletone-scoped beans? Doesn't injecting and calling to proxy cause some performance overhead?
Question: For performance sakes, could we avoid injecting proxy and inject actual bean instances in the case of the singletone-scoped beans instead?

How to add Security provider in a Spring application using Javaconfig?

I'm trying to add BouncyCastle to my Spring application but I am not sure how to add the provider to the java.security.Security provider list using JavaConfig.
Using XML configuration, I can use the MethodInvokingFactoryBean similar the following:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="java.security.Security.addProvider"/>
<property name="arguments">
<list>
<bean class="org.bouncycastle.jce.provider.BouncyCastleProvider"/>
</list>
</property>
</bean>
However, I'm not sure of the right way to do this using JavaConfig. Should I still be using the MethodInvokingFactoryBean? I presumed since it is pure java, there would be a more direct approach. At the moment, I've added the directive to a #PostConstruct method in the JavaConfig object, but not too thrilled about it - it seems a little "hacky" to me:
#Configuration
public class AppConfig {
// other #Bean definitions
#PostConstruct
public void init(){
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
}
}
MethodInvokingBean will be the de facto choice for add BouncyCastleProvider to java.security.Security since you won't need any exposure to your application context.

EJB 3 injection into spring beans

I've made a mavenized web application with spring, spring security... Now, I want to add ejb module for database access, I was looking on the internet but I didn't find something clear because it's my first time with EJB.
I want to use something like #EJB in my controller
like"
#Stateless(name = "CustomerServiceImpl")
public class CustomerServiceImpl implements CustomerService
#EJB
private MyEjb myEjb;
and how can I configure it in spring context if there is a tutorial or any other help. It will be great and thank you
To inject your ejb 3 bean in spring bean you can follow below steps.
1. Create your Spring bean
2. Create your EJB with its Remote and Local Interface
3. Write Implementations class
e.g.
package com.ejb;
#Local
public interface MyEjbLocal{
public String sendMessage();
}
package com.ejb;
#Remote
public interface MyEjbRemote{
public String sendMessage();
}
#Stateless(mappedName = "ejb/MessageSender")
public class MyEjbImpl implements MyEjbLocal, MyEjbRemote{
public String sendMessage(){
return "Hello";
}
}
above is the example of EJB3 which uses both remote and local interface
Now we create the Spring bean in which we inject this ejb.
package com.ejb;
#Service
public class MyService {
private MyEjbLocal ejb;
public void setMyEjbLocal(MyEjbLocal ejb){
this.ejb = ejb;
}
public MyEjbLocal getMyEjbLocal(){
return ejb;
}
}
We have added the instance of ejb in spring however we need to inject this in spring's spring-config.xml.
There are 2 ways to inject the ejb in spring bean
First Way
<bean id ="myBean" class="org.springframework.ejb.access.LocalStetelessSessionProxyFactoryBean">
<property name="jndiName" value="ejb/MessageSender#com.ejb.MyEjb=Local />
<property name="businessInterface" value="com.ejb.MyEjbLocal" />
</bean>
Note: I have used the Local interface here you can use Remote as per your need.
Another way of injecting the ejb is
<jee:remote-slsb id="messageSender"
jndi-name="ejb/MessageSender#com.ejb.MyEjbLocal"
business-interface="com.ejb.MyEjbLocal"
home-interface="com.ejb.MyEjbLocal"
cache-home="false" lookup-home-on-startup="false"
refresh-home-on-connect-failure="true" />
So when the bean get initialized at that time the ejb will get injected in your spring bean.
Have a look here: http://docs.spring.io/spring/docs/4.1.0.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#ejb-access-local
You can inject EJB using setter injection. Configure your bean this way:
<bean id="myComponent" class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName" value="ejb/myBean"/>
<property name="businessInterface" value="com.mycom.MyComponent"/>
</bean>
<bean id="myController" class="com.mycom.myController">
<property name="myComponent" ref="myComponent"/>
</bean>
You can also use <jee:local-slsb> tag to be able to inject your EJB:
<jee:local-slsb id="myComponent" jndi-name="ejb/myBean"
business-interface="com.mycom.MyComponent"/>
<bean id="myController" class="com.mycom.myController">
<property name="myComponent" ref="myComponent"/>
</bean>

spring context jndi lookup of properties contains all props including system props, not just the one set I need

I'm using glassfish 3.1, spring 3.2 and jdk 1.7.
I have configured two custom JNDI resources in Glassfish. One is called 'config' and the other is called 'mappings'. But when I reference one of them in the code, it actually has the properties for both and all system properties (catalina.base etc). I only want the one, not all 3 sets.
I have it set so I get the properties in the spring context file:
<jee:jndi-lookup id="mappingsJndi" jndi-name="mappings" resource-ref="true" />
<bean id="propertyMappings" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="propertiesArray">
<list>
<ref bean="mappingsJndi"/>
</list>
</property>
</bean>
I reference it in the servlet. It's injected like this:
#Autowired
Properties[] propertyMappings;
The injection works, but it contains 3 properties objects instead of the one. Is there any way around this?
Looks like I figured it out. Instead of referencing the propertyMappings bean like this:
#Autowired
Properties[] propertyMappings;
I just reference the JNDI lookup directly:
#Autowired
Properties mappingsJndi;

Hibernate interceptor for contextual sessions?

I'm trying to write a Hibernate interceptor for auditing purpose, but one that will work with thread local contextual sessions (instead of me calling openSession() every time and passing it an interceptor object).
Any guidelines/sample code on how to do this would be greatly appreciated. (My main problem is to figure out a way to give interceptor object to a contextual session when it's opened for the very first time).
why not using hibernate's audit sulotion? http://docs.jboss.org/envers/docs/index.html
if you use Hibernate only, you can set Interceptor for session with two approach.
//interceptor for global, set interceptor when create sessionFactory with Configure
sessionFactory =
new AnnotationConfiguration().configure()
.setInterceptor(new AuditTrailInterceptor())
.buildSessionFactory()
//interceptor for per Session
Session session = sessionFactory.openSession(new XxxInterceptor())
if you use Spring to create SessionFactory
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="entityInterceptor">
<bean class="your.XxxInterceptor"/>
</property>
<!-- other configuration -->
</bean>
I found one blog post which would help you. http://www.sleberknight.com/blog/sleberkn/entry/using_a_hibernate_interceptor_to

Categories

Resources