EJB 学习阶段总结:JBoss下发布一个Toy企业应用

 

 

 解释题目:为什么叫Toy企业应用,因为接下来全文将要描述的应用(home-test-all.ear)没有任何实际应用价值,之所以发布他,只是为了应用EJB相关技术;

解释企业应用:

      一个企业应用是指按照JavaEE标准开发出来比较大型的企业级应用;

      一般这样的应用以.ear结尾命名,可以运行在任何JavaEE容器中;

      一般一个应用中包括很多模块,如业务处理EJB,Web Client war,描述XML文件等。

关键字:EJB, JMS, JPA, Oracle10g, Ant,  Hibernate,Jboss ear中发布war

开发工具:Eclipse 3.6,jboss-eap-4.3,apache-ant-1.6.5,Oracle 10g

应用设计思路描述:通过两幅图来说明设计思路

在Jboss中发布完成时Jboss Deploy目录结构:


EJB 学习阶段总结:JBoss下发布一个Toy企业应用_第1张图片
 通过此图可以得到如下信息:

      发布应用的J2EE容器是JBoss     

      该应用名叫home-test-all.ear

      该应用中包括六个大模块

设计思路图:


EJB 学习阶段总结:JBoss下发布一个Toy企业应用_第2张图片
 图中有向箭头代表调运关系,中间大矩形框表示EJB容器,说明每个模块的作用和调运关系:

 

Http Web Client 前台界面,指一些浏览器,本例子中设计可以通过浏览器访问我们的应用查看相关信息(查看应用运行日志记录,查看数据库操作记录)
Entry Web War 包括一个处理核心业务的Servlet(ControllerServlet),所有前台请求都被此Servlet受理,此Servlet处理完后将结果转发会前台
CommonUtil 包括应用运行中所需的工具类,该应用中的TimerUtil就是记录一次数据库操作(一次Transaction 过程)所需的时间,将所需时间发布到我们定义的JMS Queue中,发布过程是异步处理,在线程中完成
Persistence Entity EJB 定义了所有实体Bean,这些Bean分为两类,一类是User相关实体,而另一类是记录日志相关的实体,这些实体分别在处理日志的LoggerService Session Bean,UserService Session Bean,监听日志Queue的Audit Message Driven Bean运用
loggerService EJB 无状态Session Bean,核心业务处理都是在这里完成的,Web Client调运它查看相关日志记录,命令行Client调运它向数据库中插入数据,它调运UserService Bean处理对User对象的增删改查,调运TimeUtil工具类记录时间日志,与数据库交互获取日志信息
UserService EJB 无状态Session Bean,仅仅负责对User对象持久化维护,包括一些增删改查操作,被LoggerService Session Bean调运
JMS Queue 保存日志信息的Queue,此应用中TimerUtil是他的消息发送者,Audit Message Driven Bean是他消息订阅者
Audit Messaging EJB 是一个消息驱动Bean,主要功能是监听日志消失Queue,将受到消息内容提取,保存到数据库
Oracle 10g 该应用中用到数据存储的数据库
Command line Client java Client,用来向数据库中插入数据

总结设计思路:

      设计的目的主要是用来测试在EJB Session Bean中通过JPA小数据库中插入数据和读取数据所需时间,插入数据包括插入单个数据,插入批量数据,读取单个和读取批量数据;

      设计过程:业务核心为处理日志的loggerService EJB,通过loggerService EJB完成相关设计,设计消息Queue的目的是让日志中记录时间更加准确;

分模块说明各模块的设计

1 描述XML文件META-INF模块,如下图,该模块中包括两个XML描述文件:



 application.xml应用全局描述文件,通过application.xml我们定义了home-test-all.ear中所有的模块,如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN" "http://java.sun.com/dtd/application_1_3.dtd">
<application>
  <display-name>home test all</display-name>
  <module>
    <web>
      <web-uri>home-test.war</web-uri>
      <context-root>home</context-root>
    </web>
  </module>
  <module>
      <ejb>userServiceBean.jar</ejb>
  </module>
  <module>
      <ejb>loggerServiceBean.jar</ejb>
  </module>
  <module>
      <java>CommonUtil.jar</java>
  </module>
  <module>
      <java>PersistUnit.jar</java>
  </module>
</application>

 如上定义home-test-all.ear中包括:home-test.war,userServiceBean.jar,loggerServiceBean.jar,CommonUtil.jar,PersistUnit.jar共五个模块;

注意:一个ear应用中可以包含多个war,这多个war是通过上面描述文件中<context-root>home</context-root>来定义的,context-root中定义的路径描述符与相应war应用中WEB-INF目录下jboss-web.xml中context-root定义的描述符对应

jboss-app.xml文档为该应用指定了类加载器,每个EAR应用的类加载器应该有一个唯一的名称。这里我们使用应用程序名作为类加载器的名称(其实我也不知道是神马作用,我的感觉是没有神马实质是作用,只是一个描述性的文件,这里如果定义了此文件,则在Jboss控制台可以看到相关描述),给出这里描述:

<jboss-app>
  <loader-repository>
    home-test-all:archive=home-test-all.ear
  </loader-repository>
</jboss-app>

 这里定义了 loader-repository描述信息问:home-test-all:archive=home-test-all.ear,会在Jboss JMX-console界面看到相应描述

2 Persistence Entity EJB

通过上面描述知道这里包括两类实体

User相关实体是在JPA dev: 几个问题总结 中开始描述的实例,他们关系图如下:


EJB 学习阶段总结:JBoss下发布一个Toy企业应用_第3张图片
 如上图所示:所有实体间对应关系都是单向的,User和Event,User和Friend,Event和Property,Wife和Pet,Pet和Property关系为一对多关系,User和UserCard,Friend和UserCard,Wife和UserCard,User和Wife之间的关系是一对一关系;

另一类实例类为日志记载类,包括一个实体类Audit,如下:

@Entity(name="Audit")
@Table(name="k_audit")
public class Audit implements Serializable {

	private Long id;	
	private String content;

	@Column
	@Id
	@GeneratedValue
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column
	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}
}

 

实体persist描述文件persistence.xml,  我们知道Persistence unit 是在persistence.xml中定义的,实体类型之所以能被EntityManager控制是因为提供了Persistence unit,根据持久化规范的要求,该描述文件是必须提供的,如果不提供这一文件,则Persistence unit也将不存在,因此应用也不能够获得和使用EntityManager,下面是persistence.xml内容:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
	version="1.0">
	<persistence-unit name="com.home.po" transaction-type="JTA">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
		<jta-data-source>java:/OracleDS</jta-data-source>   
		<properties>   
		     <property name="hibernate.hbm2ddl.auto" value="create-drop"/>   
		     <property name="hibernate.jdbc.fetch_size" value="18"/>   
		     <property name="hibernate.jdbc.batch_size" value="10"/>   
		     <!--<property name="hibernate.show_sql" value="true"/>   
		     <property name="hibernate.format_sql" value="true"/>   -->
		</properties>   
	</persistence-unit>
</persistence>

 配置文件中

      persistence-unit指定Persist Pojo的路径;

      provider说明我们用的JPA的实现是Hibernate;

      jta-data-source说明我们关联的data-source为Oracle;

     “hibernate.hbm2ddl.auto”值得容器启动时创建表,容器关闭时删除表;

     "hibernate.show_sql"在容器Console口打印SQL语句;

     "hibernate.format_sql"说明在容器Console显示的SQL语句是格式化的

说明<jta-data-source>java:/OracleDS</jta-data-source>  说明在JBoss_Home\server\production\deploy目录下存在名字为oracle-ds.xml数据源描述文件定义的数据源名为OracleDS,该描述文件的模板在JBoss_Home\docs\examples\jca可以找到,将他做相应拷贝既可以运用,这里描述文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
  <local-tx-datasource>
    <jndi-name>OracleDS</jndi-name>
    <connection-url>jdbc:oracle:thin:@192.168.1.105:1521:orcl</connection-url>
    <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
    <user-name>USERNAME</user-name>
    <password>PASSWORD</password>
    <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
      <metadata>
         <type-mapping>Oracle10g</type-mapping>
      </metadata>
  </local-tx-datasource>
</datasources>

 

3 loggerService EJB

该模块中包括一个无状态Session Bean,和相关Service接口,如下:

public interface LoggerService {
	public void insertUser(User user);
	public void insertUserList(List<User> users);
	public List<User> getUserList();
	public List<Audit> getAuditList();
}

 

public interface LoggerServiceLocal extends LoggerService {
}

 

@Stateless
@Remote(LoggerService.class)
@Local(LoggerServiceLocal.class)
public class LoggerServiceBean implements LoggerServiceLocal {

	@PersistenceContext(unitName="com.home.po") 
	protected EntityManager em;
	
	@EJB
	protected UserServiceLocal userService;
	
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void insertUser(User user) {
		TimerUtil timer = TimerUtil.getInstance();
		timer.setTimer();
		userService.insertUser(user);
		timer.recordTimer("insertUser");
	}

	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void insertUserList(List<User> users) {
		TimerUtil timer = TimerUtil.getInstance();
		timer.setTimer();
		userService.insertUserList(users);
		timer.recordTimer("insertUserList, user number is " + users.size());
	}

	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public List<User> getUserList() {
		TimerUtil timer = TimerUtil.getInstance();
		timer.setTimer();
		List<User> users = userService.getUserList();
		timer.recordTimer("getUserList, user number is " + users.size());
		return users;
	}

	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public List<Audit> getAuditList() {
		Query query = em.createQuery("select a from Audit as a");
		return query.getResultList();
	}
}

 

如上使用标记来说明Bean属性,是EJB3规定:

@Stateless指定LoggerServiceBean 为无状态 SessionBean

@Remote指定LoggerServiceBean 是远程接口

@Local指定LoggerServiceBean 的本地接口

@PersistenceContext(unitName="com.home.po") 指定持久化的数据单元名字

@TransactionAttribute(TransactionAttributeType.REQUIRED)说明EJB容器在执行此方法时Transaction是必须的;

4 UserService EJB模块

UserService EJB同上是无状态持久类和其相关接口,如下

public interface UserService {
	public void insertUser(User user);
	public void insertUserList(List<User> users);
	public List<User> getUserList();
	public User getUserByID(Long id);
}

 

public interface UserServiceLocal extends UserService {
}

 

@Stateless
@Remote(UserService.class)
@Local(UserServiceLocal.class)
public class UserServiceBean implements UserServiceLocal {

	@PersistenceContext(unitName="com.home.po") 
	protected EntityManager em;
	
	@TransactionAttribute(TransactionAttributeType.REQUIRED) 
	public void insertUser(User user) {
		em.persist(user);
	}

	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void insertUserList(List<User> users) {
		for(User user : users) {
			em.persist(user);
		}
	}

	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public List<User> getUserList() {
		Query query = em.createQuery("select u from User as u");
		return query.getResultList();
	}

	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public User getUserByID(Long id) {
		return em.find(User.class, id);
	}
}

 5 CommonUtil模块,该模块充当JMS Queue消息发送方,主要是往消息队列中发送日志消息,如下:

public class TimerUtil {
	
	public static TimerUtil getInstance() {
		return new TimerUtil();
	}
	
	private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss");

	private  Date start = new Date();
	
	private  boolean isSet = false;
	
	public void setTimer() {
		isSet = true;
		start = new Date();
	}
	
	public void recordTimer(String key) {
		long time = 0;
		if(isSet) {
			isSet = false;
			time = new Date().getTime() - start.getTime();
		}
		record(key, time);
	}

	private  void record(final String key, final long time) {
		new Thread(new Runnable(){

			public void run() {
				Session session = null;
				Connection conn =  null;
				try {
					Context ctx = new InitialContext();
					ConnectionFactory factory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
					conn = factory.createConnection();
					Queue queue = (Queue) ctx.lookup("queue/HomeTestAuditLogQueue");
					session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
					MessageProducer sender = session.createProducer(queue);
					Long t = time;
					String text = dateFormat.format(new Date()) + " " + key + ", total time: " + time + " milliseconds";	
					TextMessage msg = session.createTextMessage(text);
					sender.send(msg);
				} catch (NamingException e) {
					e.printStackTrace();
				} catch (JMSException e) {
					e.printStackTrace();
				}finally {
					try {
						if(session != null) {
							session.close();
						}
						if(conn != null) {
							conn.close();
						}
					} catch (JMSException e) {
						e.printStackTrace();
					}
				}
				
			}}).start();
		
	}
}

 

消息向JMS Queue 发布消息描述在上篇博客http://kylinsoong.iteye.com/blog/848713中可以找到,如何在JBoss中定义一个Queue,接下来将有描述

6 Audit Messaging EJB

此模块是一个Message Driven Bean,相当于一个JMS 消息订阅者,监听与一个Queue,通过上面我们知道TimerUtil是一个消息发送者,不管是消息发送者和消息订阅者都是基于某一Queue,如何定义一个Queue?这里我是通过JBoss_Home\server\production\deploy\jboss-messaging.sar目录下home-service.xml描述文件定义的,文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<server>
	<mbean code="org.jboss.jms.server.destination.QueueService" name="jboss.messaging.destination:service=Queue,name=HomeTestAuditLogQueue" xmbean-dd="xmdesc/Queue-xmbean.xml">
		<depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
		<depends>jboss.messaging:service=PostOffice</depends>
			</mbean>
 </server>

 如上Queue是名字为HomeTestAuditLogQueue,Jboss启动后在Jboss JNDI树上可以看到Queue HomeTestAuditLogQueue;

同样Jboss消息描述文件的模板可以在JBoss_Home\docs\examples\jms下可以找到,只需做少量修改,便可以使用,使用时只需将修改完的文件拷贝到JBoss_Home\server\production\deploy\jboss-messaging.sar既可以,JBoss启动时自动创建描述文件中定义的Queue

此处Message Driven Bean的内容:

@MessageDriven(activationConfig = {
		@ActivationConfigProperty(propertyName = "acknowledgeMode"
			, propertyValue = "Auto-acknowledge"),
		@ActivationConfigProperty(propertyName = "destination"
				, propertyValue = "queue/HomeTestAuditLogQueue"),
		@ActivationConfigProperty(propertyName = "destinationType"
			, propertyValue = "javax.jms.Queue") })
public class AuditLoggerMsgBean implements MessageListener {

	@PersistenceContext(unitName="com.home.po") 
	protected EntityManager em;
	
	public void onMessage(Message msg) {
		try {
			if(msg instanceof TextMessage) {
				System.out.println(((TextMessage) msg).getText());
				Audit audit = new Audit();
				audit.setContent(((TextMessage) msg).getText());
				em.persist(audit);
			} else {
				Audit audit = new Audit();
				audit.setContent("Error msg Type passed," + msg.getClass());
				em.persist(audit);
			}
		} catch (JMSException e) {
			Audit audit = new Audit();
			audit.setContent(e.getMessage());
			em.persist(audit);
		}
	}

}

 

7 Entry Web War模块

如下图描述了Web模块结构:

 

 Web模块的名字为home-test.war,前台界面仅有一个index.jsp,WEB-INF文件下是Web模块的描述文件

WEB-INF内容如下:


EJB 学习阶段总结:JBoss下发布一个Toy企业应用_第4张图片
 jboss-web.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.3V2//EN" "http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd">
<jboss-web>
   <context-root>home</context-root>
</jboss-web>

 此处定义是context-root与JBoss_Home\server\production\deploy\home-test-all.ear\META-INF下application.xml文件中Web模块定义的context-root相对应

web.xml为Web描述文件如下:

<web-app >

   <servlet>
      <servlet-name>ControllerServlet</servlet-name>
      <display-name>Controller Servlet</display-name>
     <servlet-class>com.home.servlet.ControllerServlet</servlet-class>

      <load-on-startup>1</load-on-startup>

   </servlet>

   <servlet-mapping>
      <servlet-name>ControllerServlet</servlet-name>
      <url-pattern>/controller</url-pattern>
   </servlet-mapping>
   
	<welcome-file-list>
		<welcome-file>/index.jsp</welcome-file>
	</welcome-file-list>
   
</web-app>

 

如上Web模块中只有一个Servlet,名字为:com.home.servlet.ControllerServlet,默认欢迎页面为:index.jsp

ControllerServlet内容:

public class ControllerServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		handlerRequest(req, resp);
	}

	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		handlerRequest(req, resp);
	}

	private void handlerRequest(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		Properties properties = new Properties();
		LoggerService service = null;
		try {
			Context ctx = new InitialContext(properties);
			service = (LoggerService) ctx.lookup("home-test-all/LoggerServiceBean/remote");
		} catch (NamingException e) {
			e.printStackTrace();
		}
		String action = req.getParameter("action");
		if(action.compareTo("user") == 0) {
			List<User> users = service.getUserList();
			req.getSession().getServletContext().setAttribute("action", "user");
			req.getSession().getServletContext().setAttribute("value", users);
		} else if(action.compareTo("audit") == 0) {
			List<Audit> audits = service.getAuditList();
			req.getSession().getServletContext().setAttribute("action", "audit");
			req.getSession().getServletContext().setAttribute("value", audits);
		}
		resp.sendRedirect("index.jsp");
	}

}

 

index.jsp内容:

<%@ page language="java" import="java.util.*, com.home.po.*" pageEncoding="ISO-8859-1"%>
<%
String action = (String) request.getSession().getServletContext().getAttribute("action");
Object obj = request.getSession().getServletContext().getAttribute("value");
%>

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
	<title>Home-Test</title>
	<link rel="SHORTCUT ICON" href="favicon.ico">
</head>

<body>
		<h2>
			<form  method="post" action="controller">
				<input type="hidden" name="action" value="user">
				<input type="submit" name="submit" value="View All User">
			</form>	
    </h2>
    <h2>
			<form  method="post" action="controller">
				<input type="hidden" name="action" value="audit">
				<input type="submit" name="submit" value="View All Audit">
			</form>	
    </h2>
		<hr>
<%
if(action != null && action.equals("user")) {
			List<User> users = (List<User>) obj;
			for(User u : users) {
%>
<p><%=u.getId() + "&nbsp;&nbsp;&nbsp;&nbsp;" + u.getName() + "&nbsp;&nbsp;&nbsp;&nbsp;" + u.getWife().getName() + "&nbsp;&nbsp;&nbsp;&nbsp;" + u.getCreatedDate().getTime() %></p>
<%
}			
}

if(action != null && action.equals("audit")) {
			List<Audit> audits = (List<Audit>) obj;
			for(Audit a : audits) {
%>
<p><%=a.getContent() %></p>
<%
}		
}
%>
		
</body>

</html>

 结果分析:

部署成功后在JMX-console控制页面http://localhost:8080/jmx-console/JMX Agent View可以看到我们home-test-all.ear应用的描述:



 此处显示是在JBoss_Home\server\production\deploy\home-test-all.ear\META-INF下的jboss-app.xml中定义的

同样在JMX Agent View的jboss.jca模块可以看到Oracle数据源相关描述



此处显示是在JBoss_Home\server\production\deploy\下的oracle-ds.xml中定义的

查看JNDI View树:http://localhost:8080/jmx-console/HtmlAdaptor,在JMX MBean Operation Result list()中可以看到我们应用定义的War,Queue,EJB等

home-test-all.ear描述如下:


EJB 学习阶段总结:JBoss下发布一个Toy企业应用_第5张图片
 在Global JNDI Namespace可以看到Queue和EJB相关描述:


EJB 学习阶段总结:JBoss下发布一个Toy企业应用_第6张图片
 加粗红线指出我们定义的Queue

Session Bean树如下:



 结果测试:

通过Command Line向数据库中插入1个User,并取出,插入100个User,然后取出所有User,再插入1000个User,后取出,完成后我们到前台看数据库操作日志:

http://localhost:8080/home/

点击后可以看到如下界面:


EJB 学习阶段总结:JBoss下发布一个Toy企业应用_第7张图片
 点击View All Audit Button可以看到如下信息:

2010-12-25T13:23:16 insertUser, total time: 250 milliseconds

2010-12-25T13:23:16 getUserList, user number is 1, total time: 781 milliseconds

2010-12-25T13:24:08 insertUserList, user number is 1000, total time: 20468 milliseconds

2010-12-25T13:24:24 getUserList, user number is 1101, total time: 2719 milliseconds

2010-12-25T13:23:36 insertUserList, user number is 100, total time: 2953 milliseconds

2010-12-25T13:23:38 getUserList, user number is 101, total time: 360 milliseconds

 

点击View All User,可以看到如下信息:

6491    Kylin Soong    Bitch Soong    Sat Dec 25 00:00:00 CST 2010

6514    Kylin Soong    Bitch Soong    Sat Dec 25 00:00:00 CST 2010

……

 补充1:全部工程已经上传,运行下面build.xml可以将应用部署到Jboss上,build.xml内容:

<?xml version="1.0"?>
<project name="com.home.ear" default="compile" basedir="..">
               <property environment="env" />
	<property name="app.dir" value="${basedir}\com.home.ear" />
	<property name="src.dir" value="${app.dir}\src" />
	<property name="build.dir" value="${app.dir}\build" />
	<property name="deploy.resource" value="${app.dir}\resource" />
	<property name="build.classes.dir" value="${build.dir}\classes" />
	<property name="jboss.home" value="${env.JBOSS_HOME}" />
	<property name="jboss.server.config" value="${jboss.home}\server\production\deploy" />
	<path id="build.classpath">
		<fileset dir="${app.dir}\jars">
			<include name="*.jar" />
		</fileset>
	</path>
	<target name="clean">
		<delete dir="${build.dir}" />
		<delete file="${deploy.resource}\CommonUtil.jar" />
		<delete file="${deploy.resource}\userServiceBean.jar" />
		<delete file="${deploy.resource}\PersistUnit.jar" />
		<delete file="${deploy.resource}\loggerServiceBean.jar" />
		<delete file="${deploy.resource}\homeTestWeb.jar" />
	</target>
	<target name="prepare" depends="clean">
		<mkdir dir="${build.dir}" />
		<mkdir dir="${build.classes.dir}" />
	</target>
               <target name="compile" depends="prepare" description="compile">
		<javac srcdir="${src.dir}" destdir="${build.classes.dir}" debug="on" deprecation="on" optimize="off" includes="com/**">
			<classpath refid="build.classpath" />
		</javac>
	</target>
               <target name="ejbjar" depends="compile" description="generate all jar">
		<jar jarfile="${deploy.resource}\userServiceBean.jar">
			<fileset dir="${build.classes.dir}">
				<include name="com/home/user/session/*.class" />
			</fileset>
		</jar>
		<jar jarfile="${deploy.resource}\loggerServiceBean.jar">
			<fileset dir="${build.classes.dir}">
				<include name="com/home/logger/session/*.class" />
				<include name="com/home/audit/*.class" />
			</fileset>
		</jar>
		
		<jar jarfile="${deploy.resource}\homeTestWeb.jar">
					<fileset dir="${build.classes.dir}">
						<include name="com/home/servlet/*.class" />
					</fileset>
				</jar>
		
		<jar jarfile="${deploy.resource}\PersistUnit.jar">
			<fileset dir="${build.classes.dir}">
				<include name="com/home/po/*.class" />
			</fileset>
			<metainf dir="${deploy.resource}\META-INF">
				<include name="persistence.xml" />
			</metainf>
		</jar>
		<jar jarfile="${deploy.resource}\CommonUtil.jar">
			<fileset dir="${build.classes.dir}">
				<include name="com/home/util/*.class" />
			</fileset>
		</jar>
		
	</target>
	<target name="deploy" depends="ejbjar">
		<mkdir dir="${jboss.server.config}\home-test-all.ear" />
		<mkdir dir="${jboss.server.config}\home-test-all.ear\META-INF" />
		<mkdir dir="${jboss.server.config}\home-test-all.ear\home-test.war" />
		<mkdir dir="${jboss.server.config}\home-test-all.ear\home-test.war\WEB-INF" />
		<mkdir dir="${jboss.server.config}\home-test-all.ear\home-test.war\WEB-INF\lib" />
		<copy file="${deploy.resource}\jboss-web.xml" todir="${jboss.server.config}\home-test-all.ear\home-test.war\WEB-INF" />
		<copy file="${deploy.resource}\web.xml" todir="${jboss.server.config}\home-test-all.ear\home-test.war\WEB-INF" />
		<copy file="${deploy.resource}\homeTestWeb.jar" todir="${jboss.server.config}\home-test-all.ear\home-test.war\WEB-INF\lib" />
		<copy file="${deploy.resource}\web\index.jsp" todir="${jboss.server.config}\home-test-all.ear\home-test.war" />
		<copy file="${deploy.resource}\application.xml" todir="${jboss.server.config}\home-test-all.ear\META-INF" />
		<copy file="${deploy.resource}\jboss-app.xml" todir="${jboss.server.config}\home-test-all.ear\META-INF" />
		<copy file="${deploy.resource}\PersistUnit.jar" todir="${jboss.server.config}\home-test-all.ear" />
		<copy file="${deploy.resource}\userServiceBean.jar" todir="${jboss.server.config}\home-test-all.ear" />
		<copy file="${deploy.resource}\CommonUtil.jar" todir="${jboss.server.config}\home-test-all.ear" />
		<copy file="${deploy.resource}\loggerServiceBean.jar" todir="${jboss.server.config}\home-test-all.ear" />
	</target>
	<target name="undeploy" >
		<delete dir="${jboss.server.config}\home-test-all.ear" />
	</target>

</project>

概括上述脚步Target作用:

path 说明Ant Build过程依赖jar的位置
clean 删除已经存在的旧的Build结果,包括目录和文件
prepare 创建存放编译结果的文件夹,依赖于clean,即创建之前删除已经存在的文件夹
compile 编译应用中所有的java类,将编译结果存放在prepare创建的文件夹中,依赖于prepare
ejbjar 将上述编译的class文件和相关资源文件打包,将打包结果存放在项目的resource目录,依赖于compile
deploy

将相关jar包和描述文件部署到JBoss_Home\server\production\deploy中,主要包括两类操作:

在JBoss_Home\server\production\deploy下创建所需目录;

将ejbjar中创建的jar包和相关描述文件拷贝到JBoss中

undeploy 删除已经部署在JBoss中的应用

补充2:如何使用Eclipse远程调试部署在JBoss上的远程代码,可分两步,如下:

1 修改JBoss 启动脚本run.bat,添加如下一行脚本,实际就是设定了一个JAVA_OPTS变量,该变量包括说明Debug方式,运程Debug网络几乎协议为TCP,TCP远程连接端口8787,启动server选择Yes,挂起Server选择No

 

set JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n %JAVA_OPTS%

 上面描述的脚步已经包括在启动脚本run.bat中,只是被注释了而已,默认挂起Server选项suspend=y,实际操作中我们只需将脚本注释去掉,将默认挂起Server选项设定为suspend=n,设定完成启动JBoss,启动过程会看到如下描述信息:
EJB 学习阶段总结:JBoss下发布一个Toy企业应用_第8张图片
 

2 Eclipse Debug 设定(以调试上述应用中AuditMessageBean为例说明):

在Eclipse导航栏选择run→Debug Configuration→Remote Java Application→New,给远程调试命名,修改相关端口如下:


EJB 学习阶段总结:JBoss下发布一个Toy企业应用_第9张图片
 设定完成给AuditLoggerMsgBean中onMessage方法设定断点后运行Debug,然后用Command line Client向数据库中发送一条信息,我们会看到Eclipse执行停止到断点处,如下:


EJB 学习阶段总结:JBoss下发布一个Toy企业应用_第10张图片
 --------------------------------------------------------------------------------------------------------------

到此结束,问题还有很多,此博客太长,现在结束

 

你可能感兴趣的:(sql,jboss,server,ejb,网络应用,企业应用)