版权许可

Creative Commons LicenseThis work is licensed under a Creative Commons License.

订阅

Feed
让您不再错过每一篇文章!

2007年1月16日星期二

Java调用外部进程并拦截输入输出流--Java IDE Console解密(下篇)


几乎所有的Java 集成开发环境都需要调用外部进程进行Java程序的构建,编译,运行和调试,Eclipse,NetBeans,JBuilder和Intellij IDLE概莫例外。在执行过程中,将提示信息以黑色全部打印在控制台里,将异常和错误以红色方式打印。以非常醒目交互体验让程序员远离枯燥和乏味。


现在让我们以Eclipse为例来看看它如何工作的,以揭开它神秘面纱,探究隐藏在后面的秘密。


上篇主要介绍了JAVA IDE Console通过采用Runtime.getRuntime.exec()执行外部程序后,将返回一个Process对象. Process对象能返回三个流:


getInputStream(),对应Process程序的标准输出流。


getErrorStream(), 对应Process程序的标准错误输出流。


getOutputStream();对应Process程序的标准输入流。


函数名之所以与Process程序的方向相反,原因是站在Java Host程序的角度讲的。


现在我们应用此原理来仿真IDE 执行外部程序的过程。


列表1:ConsoleSimulator.java


package helloworld;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

/**
* Class for console simulation
*
*
@author lewhwa
*/
public class ConsoleSimulator implements Runnable {
private volatile boolean isStop = false ;

private static final int INFO = 0 ;

private static final int ERROR = 1 ;

private InputStream is;

private int type;

/** Creates a new instance of StreamInterceptor */
public ConsoleSimulator(InputStream is, int type) {
this .is = is;
this .type = type;
}

public void run() {
InputStreamReader isr
= new InputStreamReader(is);
BufferedReader reader
= new BufferedReader(isr);
String s;
try {
while (( ! isStop) && (s = reader.readLine()) != null ) {
if (s.length() != 0 ) {
if (type == INFO) {
System.out.println(
" INFO> " + s);
}
else {
System.err.println(
" ERROR> " + s);
}
try {
Thread.sleep(
10 );
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
catch (IOException ex) {
ex.printStackTrace();
}
}

public void stop() {
isStop
= true ;
}

public static void main(String[] args) throws IOException,
InterruptedException {
// Process child = Runtime.getRuntime().exec("run.bat");
Process child = Runtime.getRuntime().exec( " java -classpath bin helloworld.Test " );
OutputStream os
= child.getOutputStream();
InputStream stdin
= child.getInputStream(); //
InputStream stderr = child.getErrorStream();
Thread tIn
= new Thread( new ConsoleSimulator(stdin, INFO));
Thread tErr
= new Thread( new ConsoleSimulator(stderr, ERROR));
tIn.start();
tErr.start();
int result = child.waitFor();
tIn.join();
tErr.join();
if (result == 0 ) {
System.out.println(
" SUCCESS! " );
}
else {
System.out.println(
" FAILED! " );
}
}
}

外部Bat文件:


列表2


time / t
cmd.exe
/ C / Q copy
javac
cmd.exe
/ C tree
rem c:\Designer_v5.
1 .0_win32_x86.exe c:\Designer_v5. 1 .0_win32_x861.exe
time
/ t



测试Java类Test.java

列表3:




package helloworld;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;


/**Test Class
*
@author lewhwa
*
*/
public class Test {

public static void main(String[] args) throws IOException {

FileReader fir
= new FileReader("src/helloworld/Test1.java");
BufferedReader br
= new BufferedReader(fir);
String s;
while((s=br.readLine())!=null){
System.out.println(s);
}
fir.close();
}

}

当ConsoleSimulator程序执行外部的run.bat时,输出如图1所示:



图1


当ConsoleSimulator程序执行外部的java test正常时,输出如图2所示:




图2


当ConsoleSimulator程序执行外部的java test发生异常时,输出如图3所示:



图3


综上,虽然没有在自己的GUI里将stdout和stderr进行说明,只是用ERROR>提示符和INFO>提示符进行演示,但是完全IDE Console的原理。对ConsoleSimulator稍加修改,完全放入到自己的应用程序当中去。


在我们进行Java程序开发的过程当中,可能涉及到其它的应用程序,借助这种技术,可以很好利用它们,将它们集成到自己的应用当中,将极大地缩短开发周期,何乐而不为呢!


2006年12月24日星期日

JBuilder 2007 企业版Trial提供下载

越接近年关,Java IDE世界真是好戏连连,先是Sun在11月发布NetBeans英文版,在12月发布多国语言版。后是BEA发布workshop studio 3.3。Borland那边不见其影,先闻其声。

话说一月之前,李维先生分别在大陆的北京,上海,大连和深圳为JBuilder 2007举办产品发布会。尔后,又在台湾台北和高雄再造声势。我未参加这样的产品发布会。。

李维先生在JBuilder2007 打通任督二脉的崭新Java开发工具 的文章里说道:

“目前EJB 3和Java Persistence API(JPA)正如潮水般席卷Java开发社群,Hibernate 3.x和Oracle的TopLink都开始支持JPA,JBoss 4.x和GlassFish/AppSever 9也都支持EJB 3.0的开发,因此JBuilder 2007的成功运算式就是:完整建模能力 + 主流Java框架 + 强大EJB3/JPA开发能力 + 高生产力开发者功能。

JBuilder 2007将充分而且完美地结合第一名的Java商业开发工具和Java开源框架/程序码成为第一个打通任督二脉的崭新Java开发工具”

现在,JBuilder 2007年终于掀开面纱,以示众人。终于在当地时间本月22日提供JBuilder 2007 Enterpise Edition trial下载。

JBuilder 2007 企业版下载地址:ftp://ftpd.borland.com/download/jbuilder/JBuilder_2007/Enterprise/JBuilder2007_enttrial.zip

主要特性,参见:http://www.codegear.com/Products/JBuilder/tabid/102/Default.aspx

在JBuilder 9和JBuilder 2005,2006版本之后逐渐失去王位的Borland,能否以CodeGear 新面孔借助JBuilder 2007 在如日中天的Eclipse之上演出王者归来的当世神话。我们将拭目以待。

2006年12月20日星期三

Sun 在圣诞节前送出的最后礼物-NetBeans 5.5多国语言版释出!

JBuilder在Eclipse的穷追猛打下,节节败退.从JBuilder 2007之后的版本完完全全抛弃了原来的primetime框架, 拜倒在Eclipse的门下. 而primetime框架原来可是Borland公司多条产品线的核心:JBuilder, Together, C++ Builder X的核心.可以说,primetime, 原来的JBuilder 已随风而逝,从此销声敛迹.今天开源的Java IDE除了大名鼎鼎的Eclipse,就只剩下NetBeans了.有人说,可能还有IntelliJ 的IDLE, 不错, 但是它不是开源的, 用它可是要掏腰包的.

Java之父James Gosling 曾在一本的序言中写到:"Sun公司的同仁喜欢称我为'Java之父'.按这种逻辑,NetBeans就是我第一个技术之孙. 享受NetBeans带给我们的一切,在它开辟的世界中遨游吧!". 由此看出, Sun公司高层对NetBeans的重视.

在除了拥有dot Net的微软之外,  Java 阵营中几乎所有的大佬都加入到Eclipse基金会. 最近的新闻, 网络搜索老大也投入到Eclipse的怀抱. 而其中有个惟一的例外, 那就是Java的缔造者--Sun. NetBeans源于捷克共和国一个小公司的产品. 经过Sun 公司的倾心培养, 已不是昔日吴下阿蒙, 当刮目相看了. 自4.1开始,  已能全面开发Java平台的应用程序.


NetBeans 5.5 IDE现在提供简体中文,日文和巴西葡萄牙文多国语言包下载.
简体中文下载地址: http://www.netbeans.info/downloads/all.php?b_id=2323

简体中文的简介: http://www.netbeans.org/products/index_zh_CN.html

除此之外, NetBeans 还提供附加包:

Mobility Pack for CLDC/MIDP:使用可视工具生成功能强大的 Mobile 应用程序。
Mobility Pack for CDC:使用可视工具生成功能强大的 Mobile 应用程序。
Visual Web Pack:拖放控件以便通过可视方式构造 Web 应用程序。在 IDE 中添加了以可视方式快速生成基于标准的 Web 应用程序所需的所有功能,其中包括 AJAX 和 JSF 组件支持。
Enterprise Pack:拖放控件以便进行UML建模(双向建模)和 SOA 应用程序开发.
Profiler:查找应用程序中的性能瓶颈和内存泄漏。
C/C++ Pack :在 NetBeans IDE 中创建 C 和 C++ 应用程序。
这么多东东, 完全是开源的. 只要不购买Sun服务, 一切都是免费的. 

大约去年9月的Sun Techday 上, 当有人向James Gosling提问: "Which is the best, Eclipse , NetBeans or others ?"
James Goslings毫不犹豫地说: "NetBeans, Of course!". 但是, 许多人立即笑了起来, 当然也包括我. 在我用NetBeans的几个月时间后, 感觉Goslings 应当有那种自信的豪情. 可以说, 在开发Web 应用(特别是JSF), EJB 3和SOA时, 是相当的棒. 

如果不想东拼西凑才搞定一个能完全满足自己需要的IDE 的话, NetBeans应当是一个不错的选择!
心动不如行动, 赶紧下载试试吧!

特此申明, 我绝对没有贬低Eclipse的意思. 劳驾Eclipse 粉丝们拍砖就免了吧!

2006年12月19日星期二

Java EE 5.0 SDK Update 2 提供下载

正如Java SE 6.0的代号为Mustang(野马)一样,Java EE 5.0也有一个代号Glassfish(玻璃鱼)。此项目组在此前在他们的Blog上宣布 Java EE SDK Update 2 发布了.

Glassfish 项目组在今年5月发布了Java EE 5的SDK. Java EE 5的关注重点是简化应用开发,尤其是大量采用元数据标注(annotation)和POJO驱动的开发方式,对平台进行了重新定义。对比此前的J2EE 1.4规范,Java EE 5最重要的新增特性包括Java持久化API(即EJB 3 entity bean)、JSF、JSTL等。

这次发布的Java EE SDK Update 2, 包括的更新有:

与Java SE 6测试兼容,其绑定的JDK为Java SE 6;
SDK整合了Access Manager , 7.1 Beta版本
SDK整合了来自Open ESB 项目的 JBI Runtime with BEPL;
SDK还整合了一个测试版本的Portlet Container, 开发者可以测试JSR 168 portlets


同时还提供了更新的Java EE samples, Blueprints, 教程,API javadocs等等.

官方Blog:
http://blogs.sun.com/theaquarium/entry/java_ee_sdk_update_2

Java EE 5.0 SDK Update 2下载,有几种选择方式。推荐下载带有NetBeans 5.5 企业包的文件。NetBeans 5.5和Java EE无缝集成,可以极大第简化EJB,Web应用和Web Service的开发。

下载地址:
http://java.sun.com/javaee/downloads/index.jsp

2006年12月17日星期日

感受野马(Mustang)性情,体会Java SE 6.0的新特性之二--Web服务

在前一篇文章中,讲述了Java SE 6.0新特征的概观。本文将介绍Web服务。

Java Web 涉及到的JSR有 105,173,181,222,224,250。

由于Web服务日趋流行,利用Web服务的功能性的API特征正从最新的Java EE版本中向Java SE 6平台迁移。换言之,针对Web服务不需另外加入额外的工具,在Java EE和Java SE平台拥有相同的API。野马将大把不同的Web服务相关的API加到标准的工具柜中:以JSR 181针对Java 平台的Web服务元数据,通过JSR 224的基于XML 的Web服务Java API(JAX-WS);针对Java的带有附件的SOAP API(SAAJ)作为JSR 67

与三个Web服务API相关的包新增到Java SE 6.0里JAX-WS API 放置到javax.xml.ws包; SAAJ类在javax.xml.soap 包; Web服务的元数据类放置在javax.jws包里。

javax.jws

JSR 181 及其针对Java 平台Web服务元数据的规范提供一个在类中利用标注设计和开发Web服务的机制。标注从J2SE 5.0引入,在Java SE 6.0得到了进一步扩展。在第10章将会完整描述。但是,标注基本上允许将@tag加入到类,方法和特性来描述相关的元数据。一个解析器然后能定位标记并采取适当的行动;尽管行动什么时候发生完全依赖于标记自身。

JAX-WS 2.0 很容易使用. 本文将介绍如何使用Java SE 6。以JAX-WS如何建立一个简单的Web服务。首先建立一个建立一个将要作为Web服务发布的类,如表1所示:

Java 代码 列表1

 1 package  hello;
 2
 3 public   class  CircleFunctions  {
 4
 5     public   double  getArea( double  radius)  {
 6         return  java.lang.Math.PI  *  (r  *  r);
 7     }

 8
 9     public   double  getCircumference( double  radius)  {
10         return   2   *  java.lang.Math.PI  *  r;
11    }

12 }

13
14

 

为了输出这些方法,必需做两件事情:引入javax.jws.WebService  包;在类的前面增加@WebService  标注以告诉Java编译器将发布此类为Web服务。下面的代码显示了这种变化(以黑体显示增加的代码)。

Java 代码 列表2
 1package hello;
 2
 3import javax.jws.WebService;
 4
 5@WebService
 6
 7public class CircleFunctions {
 8   public double getArea(double r) {
 9       return java.lang.Math.PI * (r * r);
10    }

11
12   public double getCircumference(double r) {
13        return 2 * java.lang.Math.PI * r;
14    }

15
16}

17
18

在此,有两个基本的标注@WebService@WebMethod。@WebService标注指明HelloService 类作为Web服务。如果没有制定,标注的名称就是类的名称。也能制定命名空间,服务名,WSDL 位置和endpoint 接口等。在指定的上下文环境中,可以使用javax.xml.ws.Endpoint类的publish() 静态方法发布上面的类作为Web服务。代码见列表3:

Java 代码 列表3

 1import javax.xml.ws.Endpoint;
 2
 3public static void main(String[] args) {
 4
 5      Endpoint.publish(
 6         "http://localhost:8080/WebServiceExample/circlefunctions",
 7         new CircleFunctions());
 8
 9}

10
11

现在,用javac编译源代码。但是源文件能做什么呢?通过对源文件运行 javac编译器进行编译只是产生了class文件。并没有产生特殊的东西。但是在编译类之后,也需要运行wsgen 命令行工具(wsgen 是Web service generator的缩写)。编译源代码后还必需完成更多的步骤:像下面一样调用wsgen工具。

>  wsgen –cp . hello.CircleFunctions

Wsgen工具将在一个叫做wsgen子目录下产生大量的源代码,然后将这些源代码编译成class文件。尽管从未编辑这些文件,但是可以浏览这些文件。注意在使用Wsgen工具时,原始的源代码必需在相应的包里。否则将产生错误。

就这么简单。当运行应用程序时,Java SE 6平台拥有一个小的Web应用服务器,它将在地址为http://localhost:8080/WebServiceExample/circlefunctions 发布Web服务。通过显示CircleFunction的WSDL 来验证Web服务。当JVM仍然运行时,在浏览器输入:

http:  // localhost:8080/WebServiceExample/circlefunctions?WSDL    

如果在浏览器里看见大量描述Web服务的功能的XML代码,那么Web服务就成功发布了。