今天把这几个星期关于Java Class文件的学习做了个总结,给Team也分享一下。
之后就慢慢看看OpenJDK的源码喽!
传到Slideshare的PPT
没事写写博客,没事拍拍照片。。。
今天把这几个星期关于Java Class文件的学习做了个总结,给Team也分享一下。
之后就慢慢看看OpenJDK的源码喽!
传到Slideshare的PPT
Java Class文件是由Java Compiler编译源文件之后产生的。Class文件里保存的就是大名鼎鼎的ByteCode(字节码)。其实在JVM Specification有对它格式的详细描述,我也因此用Python写了一个解析器PyJavap。昨天这个小工具也到了第一个Milestone,支持1.5以前的规范。我心里还是很有成就感的,同时对ByteCode也有了更深了理解,在我的GitHub上可以找到。
现在对Java技术的兴趣越来越深,继续研究吧! 🙂
作为Java深入学习的一部分,最近2-3周花了些时间好好看了一下JNI(Java Native Interface),认真思考了一下JVM的设计、内存管理等,还是很有些触动的。
对Team的同事也做了下Sharing, 贴在此
Team要使用EJB了,不再使用以前比较山寨的CGI+Google Protocol; 同时构建工具也变成了Maven。这几天做了些实验,想写一个最简单的Hello World。有一个EJB的Service,再有一个Client去使用这个服务。
几天下来有点小崩溃,相对EJB 3的教程来说,配置实在太麻烦,有太多的属性、参数、版本要做了。好在最后取得了成功,记在这里做个小结。
从Apache的网站上下载,然后把${MAVEN_HOME}/bin目录加到系统的PATH下。
我这里下载的是JBoss AS 7.1.1.Final压缩包。这里的版本非常重要,它和之后开发的其他包有依赖关系。
假设JBoss被解压到${JBOSS_HOME}下。
NOTE: 解压之后一定在JBoss的bin下运行add-user.bat,安装一个管理用户。这个很重要。
写一个简单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 |
我选择了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了
好了,这样我们写好的EJB就部署到了JBoss的容器中。
这部分的配置有点让我的崩溃,花的时间也最多。
基本步骤也是先用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!
真太不容易了!但现在的感觉很爽啊! 😀
老大走了,同时留了大约7,8千行的Perl脚本给我们维护。以前Perl没学过,这两天大概看了一下,现在做下简单的总结。
总的感觉是:Perl语言真的很简洁!
Perl的变量类型分成了几种:标量类型,数组类型,联合类型(理解成Map比较好)。
比如:
1 2 3 4 5 6 7 8 9 10 |
use strict; my $var1 = "hello, world"; #标量,整型,字符串,浮点等 my @var2 = qw(a b c d); # 数组 print $var2[0] # 取数组内容 my %var3 = ("i1"=>123, "i2"=>456, "i3"=>789); # Map print $var3{"i1"} # 取Map里的内容 |
NOTE:其实还有引用类型,只是现在还没有用到,先不总结了。
这个部分和其他语言很像,但有些地方会再简洁,Larry果然真的确实”很懒”。
1 2 3 4 5 6 7 |
if (expression) { ... } if (expression) { ... } else { ... } if (expression) { ... } elsif (expression) { ... } else { ... } # 你还可以 statement if expression; statement unless expression; |
和C很像,就是有的地方别忘了加上$, 如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 如果使用了use strict, 要加上 # my $i; for ($i = 0; $i < 10; $i++) { ... } # foreach foreach $i (@array) { ... } # for, foreach还可以混着用 for $i (0 .. 10) { ... } # 也有while和do while ($i < 10) { ... } do { ... } while (expression); # break和continue 变成了 last和next while (...) { next if ($i == 5); last unless ($i > 10); } |
基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
sub hello { # 不用写parameter list my $i; foreach $i (@_) { # @_就是传入的参数 print $i . ", "; } } hello("abc", "def"); # 还有常见写法 sub readName { my $firstName = shift; # 用shift从@_读入第一个参数 my $lastName = shift; # 读第二个 ... } |
用package定义一个包,如:
1 2 3 4 5 6 7 8 9 |
use strict; package foo; # 声明了一个包 sub fun1 { print 'Hello'; } 1; # 相当于return 1; 非常重要,包文件一定要返回True |
最后的”1;”非常重要,不然别的脚本就无法使用这个包。Perl里的True/False很像Python里定义的。
那如何使用呢,也很简单。
1 2 3 4 5 |
use strict; require foo; # 这里就直接去找foo.pm的文件, 如果定义的是.pl, 那就换成require "foo.pl"; foo:my_fun1(); # 用::来调用函数 |
有几个小问题:
1 |
push @INC, "/pacakge/path/" |
这些就是Perl的基本内容,再把正则表达式看一下就可以开始读代码的了。