geira
Jan 1st, 2005, 02:48 PM
I wanted to have access to my POJO's and local interfaces to ejb's from other ejb's using one single Spring application context within the Jboss container..
I have created a Spring MBean,- running a standalone MBean service....
package no.aftenposten.framework.spring;
import org.jboss.naming.NonSerializableFactory;
import org.jboss.system.ServiceMBeanSupport;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlA pplicationContext;
import javax.naming.*;
import java.io.*;
import java.util.Properties;
/**
* JMX - MBean which initiates the Spring framework by reading the spring.xml, exposing
* the Spring ApplicationContext from withing the ejb-container via jndi lookup.
* see spring-service.xml
*
* <p/>
* User: regearne
* Date: 03.des.2004
* Time: 15:02:51
*
* @author regearne
* @version $Revision: 1.2 $Date: 2005/01/01 19:31:52 $
*/
public class SpringService extends ServiceMBeanSupport implements SpringServiceMBean {
private Properties properties;
private String jndiName;
private String propertiesFile;
private boolean useProperties;
private boolean usePropertiesFile;
ApplicationContext context = null;
private static final String SPRING_CONFIG_KEY = "spring.config";
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
*
* Constructors.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
*/
public SpringService() {
usePropertiesFile = false;
propertiesFile = "";
useProperties = false;
properties = new Properties();
jndiName = "Spring";
}
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
*
* Interface.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
*/
public void setJndiName(String jndiName) throws Exception {
String oldName = this.jndiName;
this.jndiName = jndiName;
if (super.getState() == STARTED){
try {
unbind(oldName);
} catch (NamingException ne) {
log.error(captureStackTrace(ne));
throw new Exception("Failed to unbind Spring - ", ne);
}
try {
rebind();
} catch (NamingException ne) {
log.error(captureStackTrace(ne));
throw new Exception("Failed to rebind Spring - ", ne);
}
}
}
/** Getter for jndiName
*
* @return
*/
public String getJndiName() {
return jndiName;
}
/** Getter for name
*
* @return
*/
public String getName() {
return "SpringService(" + jndiName + ")";
}
/** Setter for properties, - used when assign properties via the
* spring-service.xml
*
* @param properties
*/
public void setProperties(String properties) {
if (usePropertiesFile){
log.error("Must specify only one of 'Properties' or 'PropertiesFile'");
return;
}
useProperties = true;
try {
ByteArrayInputStream bais = new ByteArrayInputStream(properties.getBytes());
this.properties = new Properties();
this.properties.load(bais);
} catch (IOException ioe) {
// should not happen
}
}
/** Get properties
*
* @return
*/
public String getProperties() {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
properties.store(baos, "");
return new String(baos.toByteArray());
} catch (IOException ioe) {
// should not happen
return "";
}
}
/** Setter for propertiesFile
*
* @param propertiesFile
*/
public void setPropertiesFile(String propertiesFile) {
if (useProperties){
log.error("Must specify only one of 'Properties' or 'PropertiesFile'");
return;
}
usePropertiesFile = true;
this.propertiesFile = propertiesFile;
}
public String getPropertiesFile() {
return propertiesFile;
}
public void createService() throws Exception {
}
public void destroyService() throws Exception {
log.info("Destroy SpringService(" + jndiName + ")...");
}
/** Starting the jmx-service
*
* @throws Exception
*/
public void startService() throws Exception {
log.info("Start SpringService(" + jndiName + ")...");
String configFile;
if ((configFile = properties.getProperty(SPRING_CONFIG_KEY)) != null){
if (new File(configFile).exists()){
log.info("Initializing Spring framework with " + configFile);
context = new FileSystemXmlApplicationContext(configFile);
log.info("Spring framework initialized");
} else {
throw new FileNotFoundException("File: "+configFile+"doesn't exist");
}
}
try {
rebind();
} catch (NamingException ne) {
log.error(captureStackTrace(ne));
throw new Exception("Failed to rebind Spring - ",
ne);
}
log.info("SpringService(" + jndiName + ") started.");
}
public void stopService() throws Exception {
log.info("Stop SpringService(" + jndiName + ")...");
log.info("Spring(" + jndiName + ") stopped.");
}
private String captureStackTrace(Throwable throwable) {
StringWriter sw = new StringWriter();
throwable.printStackTrace(new PrintWriter(sw, true));
return sw.toString();
}
private static Context createContext(Context rootCtx, Name name)
throws NamingException {
Context subctx = rootCtx;
for (int n = 0; n < name.size(); n++){
String atom = name.get(n);
try {
Object obj = subctx.lookup(atom);
subctx = (Context) obj;
} catch (NamingException e) {
// No binding exists, create a subcontext
subctx = subctx.createSubcontext(atom);
}
}
return subctx;
}
private void rebind() throws Exception {
InitialContext rootCtx = new InitialContext();
// Get the parent context into which we are to bind
Name fullName = rootCtx.getNameParser("").parse(jndiName);
Name parentName = fullName;
if (fullName.size() > 1){
parentName = fullName.getPrefix(fullName.size() - 1);
} else {
parentName = new CompositeName();
}
Context parentCtx = createContext(rootCtx, parentName);
Name atomName = fullName.getSuffix(fullName.size() - 1);
String atom = atomName.get(0);
// Scheduler scheduler = schedulerFactory.getScheduler();
NonSerializableFactory.rebind(parentCtx, atom, context);
}
private void unbind(String jndiName) throws NamingException {
Context rootCtx = new InitialContext();
Name fullName = rootCtx.getNameParser("").parse(jndiName);
Name atomName = fullName.getSuffix(fullName.size() - 1);
String atom = atomName.get(0);
rootCtx.unbind(jndiName);
NonSerializableFactory.unbind(atom);
}
}
// deployed the class within a jar into the jboss lib folder...
and a spring-service.xml into the deploy folder, firing up the the service into the Jboss....
<?xml version="1.0" encoding="UTF-8"?>
<server>
<classpath codebase="." archives="a-framework.jar"/>
<mbean code="no.aftenposten.framework.spring.SpringService"
name="user:service=SpringService,name=SpringService">
<attribute name="JndiName">Spring</attribute>
<attribute name="Properties">
spring.config=/jboss-3.2.2/server/default/deploy/spring.xml
</attribute>
</mbean>
</server>
This enables me through this static method from any ejb to access the Spring application context within the container...
public static Object getBean(String name) throws NamingException, ComponentNotAvailableException {
//Initializing the spring configuration
InitialContext jndiContext = new InitialContext();
ApplicationContext context;
if((context = (ApplicationContext) jndiContext.lookup("Spring")) != null){
return context.getBean(name);
} else {
throw new ComponentNotAvailableException("Could get Spring-bean-"+name+"," +
" due to missing BeanFactory (jndi-Spring)");
}
}
From my ejb, - the only code I need to access a Spring configured bean is:
HibernateDAO sf = (HibernateDAO) SpringBeanFactory.getBean("DAOImplementation");
sf.create(bean);
What about this way of implementing the Spring into ejb container. Have I overlooked something. I haven't found any standard Spring classes helping my to achieve the same solution, - which I would have preferred. Or should I solve it another way??
Geir
I have created a Spring MBean,- running a standalone MBean service....
package no.aftenposten.framework.spring;
import org.jboss.naming.NonSerializableFactory;
import org.jboss.system.ServiceMBeanSupport;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlA pplicationContext;
import javax.naming.*;
import java.io.*;
import java.util.Properties;
/**
* JMX - MBean which initiates the Spring framework by reading the spring.xml, exposing
* the Spring ApplicationContext from withing the ejb-container via jndi lookup.
* see spring-service.xml
*
* <p/>
* User: regearne
* Date: 03.des.2004
* Time: 15:02:51
*
* @author regearne
* @version $Revision: 1.2 $Date: 2005/01/01 19:31:52 $
*/
public class SpringService extends ServiceMBeanSupport implements SpringServiceMBean {
private Properties properties;
private String jndiName;
private String propertiesFile;
private boolean useProperties;
private boolean usePropertiesFile;
ApplicationContext context = null;
private static final String SPRING_CONFIG_KEY = "spring.config";
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
*
* Constructors.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
*/
public SpringService() {
usePropertiesFile = false;
propertiesFile = "";
useProperties = false;
properties = new Properties();
jndiName = "Spring";
}
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
*
* Interface.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
*/
public void setJndiName(String jndiName) throws Exception {
String oldName = this.jndiName;
this.jndiName = jndiName;
if (super.getState() == STARTED){
try {
unbind(oldName);
} catch (NamingException ne) {
log.error(captureStackTrace(ne));
throw new Exception("Failed to unbind Spring - ", ne);
}
try {
rebind();
} catch (NamingException ne) {
log.error(captureStackTrace(ne));
throw new Exception("Failed to rebind Spring - ", ne);
}
}
}
/** Getter for jndiName
*
* @return
*/
public String getJndiName() {
return jndiName;
}
/** Getter for name
*
* @return
*/
public String getName() {
return "SpringService(" + jndiName + ")";
}
/** Setter for properties, - used when assign properties via the
* spring-service.xml
*
* @param properties
*/
public void setProperties(String properties) {
if (usePropertiesFile){
log.error("Must specify only one of 'Properties' or 'PropertiesFile'");
return;
}
useProperties = true;
try {
ByteArrayInputStream bais = new ByteArrayInputStream(properties.getBytes());
this.properties = new Properties();
this.properties.load(bais);
} catch (IOException ioe) {
// should not happen
}
}
/** Get properties
*
* @return
*/
public String getProperties() {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
properties.store(baos, "");
return new String(baos.toByteArray());
} catch (IOException ioe) {
// should not happen
return "";
}
}
/** Setter for propertiesFile
*
* @param propertiesFile
*/
public void setPropertiesFile(String propertiesFile) {
if (useProperties){
log.error("Must specify only one of 'Properties' or 'PropertiesFile'");
return;
}
usePropertiesFile = true;
this.propertiesFile = propertiesFile;
}
public String getPropertiesFile() {
return propertiesFile;
}
public void createService() throws Exception {
}
public void destroyService() throws Exception {
log.info("Destroy SpringService(" + jndiName + ")...");
}
/** Starting the jmx-service
*
* @throws Exception
*/
public void startService() throws Exception {
log.info("Start SpringService(" + jndiName + ")...");
String configFile;
if ((configFile = properties.getProperty(SPRING_CONFIG_KEY)) != null){
if (new File(configFile).exists()){
log.info("Initializing Spring framework with " + configFile);
context = new FileSystemXmlApplicationContext(configFile);
log.info("Spring framework initialized");
} else {
throw new FileNotFoundException("File: "+configFile+"doesn't exist");
}
}
try {
rebind();
} catch (NamingException ne) {
log.error(captureStackTrace(ne));
throw new Exception("Failed to rebind Spring - ",
ne);
}
log.info("SpringService(" + jndiName + ") started.");
}
public void stopService() throws Exception {
log.info("Stop SpringService(" + jndiName + ")...");
log.info("Spring(" + jndiName + ") stopped.");
}
private String captureStackTrace(Throwable throwable) {
StringWriter sw = new StringWriter();
throwable.printStackTrace(new PrintWriter(sw, true));
return sw.toString();
}
private static Context createContext(Context rootCtx, Name name)
throws NamingException {
Context subctx = rootCtx;
for (int n = 0; n < name.size(); n++){
String atom = name.get(n);
try {
Object obj = subctx.lookup(atom);
subctx = (Context) obj;
} catch (NamingException e) {
// No binding exists, create a subcontext
subctx = subctx.createSubcontext(atom);
}
}
return subctx;
}
private void rebind() throws Exception {
InitialContext rootCtx = new InitialContext();
// Get the parent context into which we are to bind
Name fullName = rootCtx.getNameParser("").parse(jndiName);
Name parentName = fullName;
if (fullName.size() > 1){
parentName = fullName.getPrefix(fullName.size() - 1);
} else {
parentName = new CompositeName();
}
Context parentCtx = createContext(rootCtx, parentName);
Name atomName = fullName.getSuffix(fullName.size() - 1);
String atom = atomName.get(0);
// Scheduler scheduler = schedulerFactory.getScheduler();
NonSerializableFactory.rebind(parentCtx, atom, context);
}
private void unbind(String jndiName) throws NamingException {
Context rootCtx = new InitialContext();
Name fullName = rootCtx.getNameParser("").parse(jndiName);
Name atomName = fullName.getSuffix(fullName.size() - 1);
String atom = atomName.get(0);
rootCtx.unbind(jndiName);
NonSerializableFactory.unbind(atom);
}
}
// deployed the class within a jar into the jboss lib folder...
and a spring-service.xml into the deploy folder, firing up the the service into the Jboss....
<?xml version="1.0" encoding="UTF-8"?>
<server>
<classpath codebase="." archives="a-framework.jar"/>
<mbean code="no.aftenposten.framework.spring.SpringService"
name="user:service=SpringService,name=SpringService">
<attribute name="JndiName">Spring</attribute>
<attribute name="Properties">
spring.config=/jboss-3.2.2/server/default/deploy/spring.xml
</attribute>
</mbean>
</server>
This enables me through this static method from any ejb to access the Spring application context within the container...
public static Object getBean(String name) throws NamingException, ComponentNotAvailableException {
//Initializing the spring configuration
InitialContext jndiContext = new InitialContext();
ApplicationContext context;
if((context = (ApplicationContext) jndiContext.lookup("Spring")) != null){
return context.getBean(name);
} else {
throw new ComponentNotAvailableException("Could get Spring-bean-"+name+"," +
" due to missing BeanFactory (jndi-Spring)");
}
}
From my ejb, - the only code I need to access a Spring configured bean is:
HibernateDAO sf = (HibernateDAO) SpringBeanFactory.getBean("DAOImplementation");
sf.create(bean);
What about this way of implementing the Spring into ejb container. Have I overlooked something. I haven't found any standard Spring classes helping my to achieve the same solution, - which I would have preferred. Or should I solve it another way??
Geir