在Quartz2.0中提供支持EJB2.0的服务,下面实例为Quartz2.0中EJB2.0的支持。
EJBInvokerJob的源代码如下:
public class EJBInvokerJob implements Job {
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Constants.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
public static final String EJB_JNDI_NAME_KEY = "ejb";
public static final String EJB_METHOD_KEY = "method";
public static final String EJB_ARG_TYPES_KEY = "argTypes";
public static final String EJB_ARGS_KEY = "args";
public static final String INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial";
public static final String PROVIDER_URL = "java.naming.provider.url";
public static final String PRINCIPAL = "java.naming.security.principal";
public static final String CREDENTIALS = "java.naming.security.credentials";
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Constructors.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
public EJBInvokerJob() {
// nothing
}
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Interface.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
public void execute(JobExecutionContext context)
throws JobExecutionException {
JobDataMap dataMap = context.getMergedJobDataMap();
String ejb = dataMap.getString(EJB_JNDI_NAME_KEY);
String method = dataMap.getString(EJB_METHOD_KEY);
Object[] arguments = (Object[]) dataMap.get(EJB_ARGS_KEY);
if (arguments == null) {
arguments = new Object[0];
}
if (ejb == null) {
// must specify remote home
throw new JobExecutionException();
}
InitialContext jndiContext = null;
// get initial context
try {
jndiContext = getInitialContext(dataMap);
} catch (NamingException ne) {
throw new JobExecutionException(ne);
}
try {
Object value = null;
// locate home interface
try {
value = jndiContext.lookup(ejb);
} catch (NamingException ne) {
throw new JobExecutionException(ne);
}
// get home interface
EJBHome ejbHome = (EJBHome) PortableRemoteObject.narrow(value,
EJBHome.class);
// get meta data
EJBMetaData metaData = null;
try {
metaData = ejbHome.getEJBMetaData();
} catch (RemoteException re) {
throw new JobExecutionException(re);
}
// get home interface class
Class homeClass = metaData.getHomeInterfaceClass();
// get remote interface class
Class remoteClass = metaData.getRemoteInterfaceClass();
// get home interface
ejbHome = (EJBHome) PortableRemoteObject.narrow(ejbHome, homeClass);
Method methodCreate = null;
try {
// create method 'create()' on home interface
methodCreate = homeClass.getMethod("create", ((Class[])null));
} catch (NoSuchMethodException nsme) {
throw new JobExecutionException(nsme);
}
// create remote object
EJBObject remoteObj = null;
try {
// invoke 'create()' method on home interface
remoteObj = (EJBObject) methodCreate.invoke(ejbHome, ((Object[])null));
} catch (IllegalAccessException iae) {
throw new JobExecutionException(iae);
} catch (InvocationTargetException ite) {
throw new JobExecutionException(ite);
}
// execute user-specified method on remote object
Method methodExecute = null;
try {
// create method signature
Class[] argTypes = (Class[]) dataMap.get(EJB_ARG_TYPES_KEY);
if (argTypes == null) {
argTypes = new Class[arguments.length];
for (int i = 0; i < arguments.length; i++) {
argTypes[i] = arguments[i].getClass();
}
}
// get method on remote object
methodExecute = remoteClass.getMethod(method, argTypes);
} catch (NoSuchMethodException nsme) {
throw new JobExecutionException(nsme);
}
try {
// invoke user-specified method on remote object
Object returnObj = methodExecute.invoke(remoteObj, arguments);
// Return any result in the JobExecutionContext so it will be
// available to Job/TriggerListeners
context.setResult(returnObj);
} catch (IllegalAccessException iae) {
throw new JobExecutionException(iae);
} catch (InvocationTargetException ite) {
throw new JobExecutionException(ite);
}
} finally {
// Don't close jndiContext until after method execution because
// WebLogic requires context to be open to keep the user credentials
// available. See JIRA Issue: QUARTZ-401
if (jndiContext != null) {
try {
jndiContext.close();
} catch (NamingException e) {
// Ignore any errors closing the initial context
}
}
}
}
private InitialContext getInitialContext(JobDataMap jobDataMap)
throws NamingException {
Hashtable params = new Hashtable(2);
String initialContextFactory =
jobDataMap.getString(INITIAL_CONTEXT_FACTORY);
if (initialContextFactory != null) {
params.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
}
String providerUrl = jobDataMap.getString(PROVIDER_URL);
if (providerUrl != null) {
params.put(Context.PROVIDER_URL, providerUrl);
}
String principal = jobDataMap.getString(PRINCIPAL);
if ( principal != null ) {
params.put( Context.SECURITY_PRINCIPAL, principal );
}
String credentials = jobDataMap.getString(CREDENTIALS);
if ( credentials != null ) {
params.put( Context.SECURITY_CREDENTIALS, credentials );
}
return (params.size() == 0) ? new InitialContext() : new InitialContext(params);
}
}
自定义EJBHome接口:
package com.easyway.app.ejb;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
/**
* Home接口的方法
* @author longgangbai
*
*/
public interface HelloWorldHome extends EJBHome
{
HelloWorldRemote create() throws RemoteException, CreateException;
}
EJB远程接口:
package com.easyway.app.ejb;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
/**
* 远程接口
* @author longgangbai
*
*/
public interface HelloWorldRemote extends EJBObject
{
public String sayHello(String country,String cityName) throws RemoteException;
}
EJB的bean类:
package com.easyway.app.ejb;
import java.rmi.RemoteException;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
/**
* 會話bean的实现
*
* (必须有会话bean的5个状态,可以为空实现,和远程接口中要实现的方法,
* 把实现方法写在一个类里,每次 new一个类的对象,返回一个实现方法给Bean)
*
* @author longgangbai
*
*/
public class HelloWorldBean implements SessionBean
{
/**
*
*/
private static final long serialVersionUID = 1L;
public void setSessionContext(SessionContext arg0) throws EJBException, RemoteException
{
System.out.println("set session context");
}
public void ejbCreate() throws EJBException
{
System.out.println("ejb create");
}
public void ejbRemove() throws EJBException, RemoteException
{
System.out.println("ejb remove");
}
public void ejbActivate() throws EJBException, RemoteException
{
System.out.println("ejb activate");
}
public void ejbPassivate() throws EJBException, RemoteException
{
System.out.println("ejb passivate");
}
/**
* 自定义的EJB的方法
* @param country
* @param cityName
* @return
* @throws RemoteException
*/
public String sayHello(String country,String cityName) throws RemoteException
{
String helloworld="your are in "+country+" on "+cityName+"Welecome to ejb2.0,HXL";
System.out.println("helloworld="+helloworld);
return helloworld;
}
}
在META-INF包下的ejb-jar.xml配置如下:
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<description>ejb</description>
<display-name>quartzEJB2</display-name>
<!--
配置会话bean的信息
-->
<enterprise-beans>
<session>
<display-name>helloEJB</display-name>
<ejb-name>helloEJB</ejb-name>
<home>com.easyway.app.ejb.HelloWorldHome</home>
<remote>
com.easyway.app.ejb.HelloWorldRemote
</remote>
<ejb-class>
com.easyway.app.ejb.HelloWorldBean
</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Bean</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
jboss配置如下:
jboss.xml内容如下:
<?xml version="1.0" encoding="gb2312"?>
<!--
<jndi-name>元素的值必须在容器中唯一
-->
<jboss>
<enterprise-beans>
<session>
<ejb-name>helloEJB</ejb-name>
<jndi-name>ejb/helloEJB</jndi-name>
</session>
</enterprise-beans>
</jboss>
创建触发器和相关的job调用
package com.easyway.app.ejb;
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import java.text.ParseException;
import java.util.Date;
import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.jobs.ee.ejb.EJBInvokerJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 调用EJB2.0的定时任务
* @author longgangbai
*
*/
public class QuartzEjb2Main {
/**
*
* @param args
* @throws SchedulerException
* @throws ParseException
*/
public static void main(String[] args) throws SchedulerException, ParseException {
Logger log = LoggerFactory.getLogger(QuartzEjb2Main.class);
log.info("------- Initializing -------------------");
// First we must get a reference to a scheduler
//创建调度任务工厂
SchedulerFactory sf = new StdSchedulerFactory();
//创建调度对象
Scheduler sched = sf.getScheduler();
log.info("------- Scheduling Jobs ----------------");
// jobs can be scheduled before sched.start() has been called
// job 1 will run every 20 seconds
//创建一个定时任务
JobDetail job = newJob(EJBInvokerJob.class)
.withIdentity("job1", "group1")
.build();
//创建Cron触发器
CronTrigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.withSchedule(cronSchedule("0/20 * * * * ?"))
.build();
//创建一个初始化任务的信息
// pass initialization parameters into the job
JobDataMap jobDataMap=job.getJobDataMap();
//设置EJB的JNDI名称
jobDataMap.put(EJBInvokerJob.EJB_JNDI_NAME_KEY, "ejb/helloEJB");
//设置ejb的调用方法名称
jobDataMap.put(EJBInvokerJob.EJB_METHOD_KEY, "sayHello");
//设置ejb输入参数的类型
jobDataMap.put(EJBInvokerJob.EJB_ARG_TYPES_KEY,new Class[]{ String.class,String.class});
//设置输入类型的参数值
jobDataMap.put(EJBInvokerJob.EJB_ARGS_KEY,new Object[]{ "china","shanghai"});
//设置EJB的初始化参数
jobDataMap.put(EJBInvokerJob.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
//jobDataMap.put(EJBInvokerJob.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
//设置EBJ的uri路径
jobDataMap.put(EJBInvokerJob.PROVIDER_URL, "jnp://localhost:1099");
//设置调用相关的任务和触发器信息
Date ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " has been scheduled to run at: " + ft
+ " and repeat based on expression: "
+ trigger.getCronExpression());
//启动相关的的调度信息
sched.start();
log.info("------- Started Scheduler -----------------");
log.info("------- Waiting five minutes... ------------");
try {
// wait five minutes to show jobs
Thread.sleep(300L * 1000L);
// executing...
} catch (Exception e) {
}
log.info("------- Shutting Down ---------------------");
//关闭相关的调度
sched.shutdown(true);
log.info("------- Shutdown Complete -----------------");
SchedulerMetaData metaData = sched.getMetaData();
log.info("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");
}
}