Team要使用EJB了,不再使用以前比较山寨的CGI+Google Protocol; 同时构建工具也变成了Maven。这几天做了些实验,想写一个最简单的Hello World。有一个EJB的Service,再有一个Client去使用这个服务。
几天下来有点小崩溃,相对EJB 3的教程来说,配置实在太麻烦,有太多的属性、参数、版本要做了。好在最后取得了成功,记在这里做个小结。
1. 工具的安装
Maven 3
从Apache的网站上下载,然后把${MAVEN_HOME}/bin目录加到系统的PATH下。
JBoss AS
我这里下载的是JBoss AS 7.1.1.Final压缩包。这里的版本非常重要,它和之后开发的其他包有依赖关系。
假设JBoss被解压到${JBOSS_HOME}下。
NOTE: 解压之后一定在JBoss的bin下运行add-user.bat,安装一个管理用户。这个很重要。
2. 写一个EJB的服务
写一个简单EJB服务很简单,我们可以有Maven的archetype生成一个工程的框架。
1 |
mvn archetype:generate -DgroupId=org.yli.learn -DartifactId=server -Dpackaging=ejb -Dversion=1.0 -Dpackage=org.yli.learn.server |
一路回车之后,就得到了一个Server的工程文件夹结构。但删掉默认生成的App.java和AppTest.java.
然后在org.yli.learn.server中,加入两个类。一个是接口SayHello,一个是EJB Bean类SayHelloBean.
1 2 3 4 5 6 7 |
package org.yli.learn.server; public interface SayHello { String sayHello(String name); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package org.yli.learn10.server; import javax.ejb.Remote; import javax.ejb.Stateless; @Stateless @Remote(SayHello.class) public class SayHelloBean implements SayHello { public String sayHello(String name) { return "Hello, " + name + "!"; } } |
里面用到一些EJB 3的Annonation,大家自己查查书吧。
下一步就是修改pom.xml文件了,这里我们只要加入一些编译的依赖就行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.yli.learn10</groupId> <artifactId>server-side</artifactId> <version>1.0</version> <packaging>ejb</packaging> <!-- 注意: 这里是ejb类型的,为了使Cargo可以直接部署 --> <name>JBoss AS Learn Server Side</name> <!-- 这里用到了依赖管理,为了统一依赖之间的版本 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.jboss.spec</groupId> <artifactId>jboss-javaee-6.0</artifactId> <version>3.0.0.Final</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.jboss.spec.javax.annotation</groupId> <artifactId>jboss-annotations-api_1.1_spec</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.spec.javax.ejb</groupId> <artifactId>jboss-ejb-api_3.1_spec</artifactId> <scope>provided</scope> </dependency> </dependencies> <build> <!-- 最终部署到Jboss container里的app name --> <finalName>yli_learn_ejb_server_app</finalName> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.1</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-ejb-plugin</artifactId> <version>2.3</version> <configuration> <ejbVersion>3.1</ejbVersion> <generateClient>true</generateClient> </configuration> </plugin> </plugins> </build> </project> |
然后你可以编译安装了。
1 |
mvn clean install |
3. EJB Bean的部署
我选择了Cargo来部署Bean到JBoss里,好像有一个plugin叫jboss-as的,也可以做一样的事情。
我们只要在pom.xml加上:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
... <build> <plugins> ... <plugin> <groupId>org.codehaus.cargo</groupId> <artifactId>cargo-maven2-plugin</artifactId> <version>1.2.1</version> <configuration> <container> <containerId>jboss71x</containerId> <!-- Jboss 的安装目录 --> <home>E:/my_code/jboss-as-7.1.1.Final</home> </container> <configuration> <type>existing</type> <!-- Jboss下standalone目录,其实就是部署的目录 --> <home>E:/my_code/jboss-as-7.1.1.Final/standalone</home> </configuration> <deployer> <deployables> <deployable> <!-- 告诉cargo要部署哪个artifact --> <groupId>org.yli.learn</groupId> <artifactId>server</artifactId> </deployable> </deployables> </deployer> </configuration> </plugin> ... </plugins> </build> |
然后就可以用mvn的goal来部署和运行JBoss了
- 部署: mvn cargo:deployer-deploy
- 运行: mvn cargo:run或cargo:start
好了,这样我们写好的EJB就部署到了JBoss的容器中。
4. EJB的Client
这部分的配置有点让我的崩溃,花的时间也最多。
基本步骤也是先用maven建立一个框架,比如我们的工程是org.yli.learn:client:jar:1.0, 包名是org.yli.learn.client.
我们在包里有一个Client,它会去向JBoss获取service并使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package org.yli.learn10.client; import org.jboss.sasl.JBossSaslProvider; import org.yli.learn10.server.SayHello; import org.yli.learn10.server.SayHelloBean; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import java.security.Security; import java.util.Hashtable; public class Client { static { Security.addProvider(new JBossSaslProvider()); } public static void main(String[] args) throws NamingException { final Hashtable jndiProperties = new Hashtable(); jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); final Context context = new InitialContext(jndiProperties); SayHello sayHello = (SayHello) context.lookup("ejb:/yli_learn_ejb_server_app//" + SayHelloBean.class.getSimpleName() + "!" + SayHello.class.getName()); System.out.println(sayHello.sayHello("Jason")); } } |
POM文件里有相关的依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>client</artifactId> <groupId>org.yli.learn10</groupId> <version>1.0</version> <name>JBoss AS Learn Client</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.jboss.spec</groupId> <artifactId>jboss-javaee-6.0</artifactId> <version>3.0.0.Final</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.jboss.spec.javax.transaction</groupId> <artifactId>jboss-transaction-api_1.1_spec</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.jboss.spec.javax.ejb</groupId> <artifactId>jboss-ejb-api_3.1_spec</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.jboss.xnio</groupId> <artifactId>xnio-api</artifactId> <version>3.0.3.GA</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.jboss.xnio</groupId> <artifactId>xnio-nio</artifactId> <version>3.0.2.GA</version> <scope>runtime</scope> </dependency> <!-- The client needs JBoss remoting to access the server --> <dependency> <groupId>org.jboss.remoting3</groupId> <artifactId>jboss-remoting</artifactId> <version>3.2.2.GA</version> <scope>runtime</scope> </dependency> <!-- Remote EJB accesses can be secured --> <dependency> <groupId>org.jboss.sasl</groupId> <artifactId>jboss-sasl</artifactId> <version>1.0.0.Final</version> </dependency> <!-- data serialization for invoking remote EJBs --> <dependency> <groupId>org.jboss.marshalling</groupId> <artifactId>jboss-marshalling-river</artifactId> <version>1.3.9.GA</version> <scope>runtime</scope> </dependency> <!-- jboss-ejb-client的依赖很重要,而且版本一定要对 --> <dependency> <groupId>org.jboss</groupId> <artifactId>jboss-ejb-client</artifactId> <version>1.0.5.Final</version> </dependency> <dependency> <groupId>org.yli.learn10</groupId> <artifactId>server-side</artifactId> <version>${project.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.1</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <goals> <goal>exec</goal> </goals> </execution> </executions> <configuration> <executable>java</executable> <workingDirectory>${project.build.directory}/exec-working-directory</workingDirectory> <arguments> <!-- automatically creates the classpath using all project dependencies, also adding the project build directory --> <argument>-classpath</argument> <classpath> </classpath> <argument>org.yli.learn.client.Client</argument> </arguments> </configuration> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>org.yli.learn.client.Client</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> </project> |
然后你可以用mvn clean package来编译打包了。
很重要的一点,就是要添加一个properties文件。在src/main下面,建立一个resources的文件夹,然后在里面新建文件jboss-ejb-client.properties. 我这里使用的是一些默认的选项,具体文档在JBoss的Confluence里有介绍。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false remote.connections=default remote.connection.default.host=localhost remote.connection.default.port = 4447 remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false remote.connection.two.host=localhost remote.connection.two.port = 4447 remote.connection.two.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false # 后面两句非常重要!记得我之前要大家建立一个Jboss的用户吗? remote.connection.default.username=abc remote.connection.default.password=123456 |
好了,可以用mvn exec:exec来运行了!
你可以顺利看到Hello, Jason!
真太不容易了!但现在的感觉很爽啊! 😀