package opm;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.*;
@SuppressWarnings("serial")
public class OpmServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
if (req.getParameter("test") == null) {
resp.sendRedirect("http://www.google.com/");
} else {
resp.getWriter().printf("Hello Opera Mini Server! Fuck GFW!");
}
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
try {
URL url = new URL("http://server4.operamini.com");
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/xml");
connection.setRequestProperty("User-Agent", "Java/1.6.0_15");
connection.setRequestProperty("Connection", "keep-alive");
int length;
byte[] buffer = new byte[1024];
ServletInputStream req_in = req.getInputStream();
OutputStream con_out = connection.getOutputStream();
while ((length = req_in.read(buffer)) != -1) {
con_out.write(buffer, 0, length);
}
con_out.flush();
con_out.close();
req_in.close();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
resp.setHeader("Content-Type", "application/octet-stream");
resp.setHeader("Cache-Control", "priavte, no-cache");
InputStream con_in = connection.getInputStream();
ServletOutputStream resp_out = resp.getOutputStream();
while ((length = con_in.read(buffer)) != -1) {
resp_out.write(buffer, 0, length);
}
} else {
resp.sendError(connection.getResponseCode());
}
} catch (Exception e) {
resp.sendError(HttpURLConnection.HTTP_UNAVAILABLE);
}
}
}
2009年12月2日星期三
2009年10月29日星期四
IOC 的手工实现与Guice 实现
IOC 的手工实现与Guice 实现
1. 服务类与实现类
public interface Service {
void go();
}
public class ServiceImpl implements Service {
public void go() {
logger.info("ServiceImpl.class");
}
}
public class MockService implements Service {
public void go() {
logger.info("MockService.class");
}
}
2. 客户类,调用服务类,最原始的实现
public class Client {
public void test(boolean args){
Service service = null;
if(args){
service = new ServiceImpl();
service.go();
}else{
service = new MockService();
service.go();
}
}
}
3. 测试类,但使用了工厂模式
public class ServiceFactory {
private ServiceFactory() {}
private static Service instance = new ServiceImpl();
public static Service getInstance() {
return instance;
}
public static void setInstance(Service service) {
instance = service;
}
}
4. 使用了工厂模式后,测试类的实现
public class Client {
public void test(){
Service service = ServiceFactory.getInstance();
service.go();
//跟上面有什么不同?
}
}
5. 对客户类进行测试的类
public void testClient() {
Service previous = ServiceFactory.getInstance();
try {
Client client = new Client();
client.test();
//what be printed?
final MockService mock = new MockService();
ServiceFactory.setInstance(mock);
client = new Client();
client.test();
//what be printed?
}
finally {
//must exists?
ServiceFactory.setInstance(previous);
}
}
6. 手工方式注入客户类,以及对客户类的测试
public class Client {
private final Service service;
public Client(Service service) {
this.service = service;
}
public void test() {
service.go();
}
}
public void testClient() {
MockService mock = new MockService();
Client client = new Client(mock);
client.test();
}
7. Guice 的实现方式
首先实现 Module,将服务类与要注入的测试类绑定
public class MyModule implements Module {
public void configure(Binder binder) {
binder.bind(Service.class)
.to(ServiceImpl.class)
.in(Scopes.SINGLETON);
}
}
//客户类中需要表明哪里需要注入
public class Client {
private final Service service;
@Inject
public Client(Service service) {
this.service = service;
}
public void test() {
service.go();
}
}
8. 测试类
public void testClient() {
Injector injector = Guice.createInjector(new MyModule());
Client client= injector.getInstance(Client.class);
client.test();
}
1. 服务类与实现类
public interface Service {
void go();
}
public class ServiceImpl implements Service {
public void go() {
logger.info("ServiceImpl.class");
}
}
public class MockService implements Service {
public void go() {
logger.info("MockService.class");
}
}
2. 客户类,调用服务类,最原始的实现
public class Client {
public void test(boolean args){
Service service = null;
if(args){
service = new ServiceImpl();
service.go();
}else{
service = new MockService();
service.go();
}
}
}
3. 测试类,但使用了工厂模式
public class ServiceFactory {
private ServiceFactory() {}
private static Service instance = new ServiceImpl();
public static Service getInstance() {
return instance;
}
public static void setInstance(Service service) {
instance = service;
}
}
4. 使用了工厂模式后,测试类的实现
public class Client {
public void test(){
Service service = ServiceFactory.getInstance();
service.go();
//跟上面有什么不同?
}
}
5. 对客户类进行测试的类
public void testClient() {
Service previous = ServiceFactory.getInstance();
try {
Client client = new Client();
client.test();
//what be printed?
final MockService mock = new MockService();
ServiceFactory.setInstance(mock);
client = new Client();
client.test();
//what be printed?
}
finally {
//must exists?
ServiceFactory.setInstance(previous);
}
}
6. 手工方式注入客户类,以及对客户类的测试
public class Client {
private final Service service;
public Client(Service service) {
this.service = service;
}
public void test() {
service.go();
}
}
public void testClient() {
MockService mock = new MockService();
Client client = new Client(mock);
client.test();
}
7. Guice 的实现方式
首先实现 Module,将服务类与要注入的测试类绑定
public class MyModule implements Module {
public void configure(Binder binder) {
binder.bind(Service.class)
.to(ServiceImpl.class)
.in(Scopes.SINGLETON);
}
}
//客户类中需要表明哪里需要注入
public class Client {
private final Service service;
@Inject
public Client(Service service) {
this.service = service;
}
public void test() {
service.go();
}
}
8. 测试类
public void testClient() {
Injector injector = Guice.createInjector(new MyModule());
Client client= injector.getInstance(Client.class);
client.test();
}
2009年10月28日星期三
Guice 使用
本文有两个例子,一个是对接口类的实现类的使用者注入,另一个是对接口实现类直接注入.
1. 创建接口与实现
public interface MyService {
void sayHello();
}
public class MyServiceImpl implements MyService {
@Override
public void sayHello() {
System.out.println("hello,Guice.");
}
}
2. 测试实现类
定义测试类,表明这个类是需要注入的
import com.google.inject.Inject;
public class MyServiceTest {
@Inject
MyService service;
public void sayHello(){
System.out.println("MyServiceTest...");
service.sayHello();
}
}
3. 定义注射规则
实现 Module,表明运行时将哪个实现类赋给接口
import com.google.inject.Binder;
import com.google.inject.Module;
public class MyServiceModule implements Module {
@Override
public void configure(Binder binder) {
binder.bind(MyService.class).to(MyServiceImpl.class).in(Scopes.SINGLETON);
}
}
4. 测试
Guice 根据 Module 创建注射者
从注射者获取接口类实例
调用接口方法
import junit.framework.TestCase;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class TestMyService extends TestCase{
public void testS(){
Injector inj = Guice.createInjector(new MyServiceModule());
MyServiceTest m = inj.getInstance(MyServiceTest.class);
m.sayHello();
/**
* 也可以换成以下代码
* Injector inj = Guice.createInjector(new MyServiceModule());
* MyServiceTest m = new MyServiceTest();
* inj.injectMembers(m);
* m.sayHello();
*/
}
}
-------------------------------------------
下面这个例子跟上面相似,只是没有定义测试类(接口实现类使用者,直接对接口实现类进行注入)
1. 创建接口与实现
同上
2. 测试实现类
定义测试类,表明这个类是需要注入的
此步省略,没有定义测试类,后面直接注射实现类
3. 定义注射规则
实现 Module,表明运行时将哪个实现类赋给接口
同上
4. 测试
Guice 根据 Module 创建注射者
从注射者获取接口类实例
调用接口方法
import junit.framework.TestCase;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class TestMyService extends TestCase{
public void testS(){
Injector inj = Guice.createInjector(new MyServiceModule());
//此类与上面的例子不同之处,只是传入的参数不同,此处传入的是实现类
MyServiceTest m = inj.getInstance(MyServiceImpl.class);
m.sayHello();
}
}
1. 创建接口与实现
public interface MyService {
void sayHello();
}
public class MyServiceImpl implements MyService {
@Override
public void sayHello() {
System.out.println("hello,Guice.");
}
}
2. 测试实现类
定义测试类,表明这个类是需要注入的
import com.google.inject.Inject;
public class MyServiceTest {
@Inject
MyService service;
public void sayHello(){
System.out.println("MyServiceTest...");
service.sayHello();
}
}
3. 定义注射规则
实现 Module,表明运行时将哪个实现类赋给接口
import com.google.inject.Binder;
import com.google.inject.Module;
public class MyServiceModule implements Module {
@Override
public void configure(Binder binder) {
binder.bind(MyService.class).to(MyServiceImpl.class).in(Scopes.SINGLETON);
}
}
4. 测试
Guice 根据 Module 创建注射者
从注射者获取接口类实例
调用接口方法
import junit.framework.TestCase;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class TestMyService extends TestCase{
public void testS(){
Injector inj = Guice.createInjector(new MyServiceModule());
MyServiceTest m = inj.getInstance(MyServiceTest.class);
m.sayHello();
/**
* 也可以换成以下代码
* Injector inj = Guice.createInjector(new MyServiceModule());
* MyServiceTest m = new MyServiceTest();
* inj.injectMembers(m);
* m.sayHello();
*/
}
}
-------------------------------------------
下面这个例子跟上面相似,只是没有定义测试类(接口实现类使用者,直接对接口实现类进行注入)
1. 创建接口与实现
同上
2. 测试实现类
定义测试类,表明这个类是需要注入的
此步省略,没有定义测试类,后面直接注射实现类
3. 定义注射规则
实现 Module,表明运行时将哪个实现类赋给接口
同上
4. 测试
Guice 根据 Module 创建注射者
从注射者获取接口类实例
调用接口方法
import junit.framework.TestCase;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class TestMyService extends TestCase{
public void testS(){
Injector inj = Guice.createInjector(new MyServiceModule());
//此类与上面的例子不同之处,只是传入的参数不同,此处传入的是实现类
MyServiceTest m = inj.getInstance(MyServiceImpl.class);
m.sayHello();
}
}
2009年7月17日星期五
Java Performance Tuning and Troubleshooting
1. Jconsole
两种监控方法:
1) Local Monitor : 在 JDK6 以前,需要增加 java 启动参数 com.sun.management.jmxremote
ex: Java -Dcom.sun.management.jmxremote -jar test.jar
2) Remote Monitor: java -Dcom.sun.management.jmxremote.port=portNum -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
注意:如果不用 ssl 访问,应该增加参数 -Dcom.sun.management.jmxremote.ssl=false,刚开始我没有加这个参数的,远程连接总是不成功
3) 此外,远程监控还可以通过用户名/口令进行安全设置,也可以通过 SSL 来加密访问,以增加安全性
Jconsole 可以做什么?
1) 主要是总体观察,以大体确定问题在哪里。比如内存是否持续增长(内存泄漏?),CPU时间是否持续升高?
2) 检测线程是否有死锁,以及线程的堆栈查看。只有线程发生死锁的时候才会检测出来,而不是检测所有可能发生死锁的代码
3) 可以查看 load 的类是否持续在增加
4) VM 参数
2. JPS
类似于 unix 的 ps,列出所有进程,这个是列出所有 Java 进程
-q
Suppress the output of the class name, JAR file name, and arguments passed to the main method, producing only a list of local VM identifiers.
-m
Output the arguments passed to the main method. The output may be null for embedded JVMs.
-l
Output the full package name for the application's main class or the full path name to the application's JAR file.
-v
Output the arguments passed to the JVM.
-V
Output the arguments passed to the JVM through the flags file (the .hotspotrc file or the file specified by the -XX:Flags= argument).
-Joption
Pass option to the java launcher called by jps. For example, -J-Xms48m sets the startup memory to 48 megabytes. It is a common convention for -J to pass options to the underlying VM executing applications written in Java.
3. Jstat - Java VM stastics Monitor Tool
The jstat tool displays performance statistics for an instrumented HotSpot Java virtual machine (JVM).
-statOption
Determines the statistics information that jstat displays. The following table lists the available options. Use the -options general option to display the list of options for a particular platform installation.
Option Displays...
class Statistics on the behavior of the class loader.
compiler Statistics of the behavior of the HotSpot Just-in-Time compiler.
gc Statistics of the behavior of the garbage collected heap.
gccapacity Statistics of the capacities of the generations and their corresponding spaces.
gccause Summary of garbage collection statistics (same as -gcutil), with the cause of the last and current (if applicable) garbage collection events.
gcnew Statistics of the behavior of the new generation.
gcnewcapacity Statistics of the sizes of the new generations and its corresponding spaces.
gcold Statistics of the behavior of the old and permanent generations.
gcoldcapacity Statistics of the sizes of the old generation.
gcpermcapacity Statistics of the sizes of the permanent generation.
gcutil Summary of garbage collection statistics.
printcompilation HotSpot compilation method statistics.
-h n
Display a column header every n samples (output rows), where n is a positive integer. Default value is 0, which displays the column header above the first row of data.
-t n
Display a timestamp column as the first column of output. The timestamp is the the time since the start time of the target JVM.
-JjavaOption
Pass javaOption to the java application launcher. For example, -J-Xms48m sets the startup memory to 48 megabytes. For a complete list of options, see java - the Java application launcher
举例:
>jps
3672
2884 PluginMain
2648 LauncherServlet
2312
5800 Jps
>jstat -compiler 2648 5s 3
4. Jinfo
显示 Java 配置信息
prints Java configuration information for a given Java process or core file or a remote debug server. Configuration information includes Java System properties and Java virtual machine command line flags.
注意:目前 不支持 linux/Windows
5. Jstack
Statck Trace
jstack prints Java stack traces of Java threads for a given Java process or core file or a remote debug server
ex. jstatck -l 2648
6. HPROF - a heap/cpu Profilling Tool
hprof usage: java -agentlib:hprof=[help]|[
两种监控方法:
1) Local Monitor : 在 JDK6 以前,需要增加 java 启动参数 com.sun.management.jmxremote
ex: Java -Dcom.sun.management.jmxremote -jar test.jar
2) Remote Monitor: java -Dcom.sun.management.jmxremote.port=portNum -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
注意:如果不用 ssl 访问,应该增加参数 -Dcom.sun.management.jmxremote.ssl=false,刚开始我没有加这个参数的,远程连接总是不成功
3) 此外,远程监控还可以通过用户名/口令进行安全设置,也可以通过 SSL 来加密访问,以增加安全性
Jconsole 可以做什么?
1) 主要是总体观察,以大体确定问题在哪里。比如内存是否持续增长(内存泄漏?),CPU时间是否持续升高?
2) 检测线程是否有死锁,以及线程的堆栈查看。只有线程发生死锁的时候才会检测出来,而不是检测所有可能发生死锁的代码
3) 可以查看 load 的类是否持续在增加
4) VM 参数
2. JPS
类似于 unix 的 ps,列出所有进程,这个是列出所有 Java 进程
-q
Suppress the output of the class name, JAR file name, and arguments passed to the main method, producing only a list of local VM identifiers.
-m
Output the arguments passed to the main method. The output may be null for embedded JVMs.
-l
Output the full package name for the application's main class or the full path name to the application's JAR file.
-v
Output the arguments passed to the JVM.
-V
Output the arguments passed to the JVM through the flags file (the .hotspotrc file or the file specified by the -XX:Flags=
-Joption
Pass option to the java launcher called by jps. For example, -J-Xms48m sets the startup memory to 48 megabytes. It is a common convention for -J to pass options to the underlying VM executing applications written in Java.
3. Jstat - Java VM stastics Monitor Tool
The jstat tool displays performance statistics for an instrumented HotSpot Java virtual machine (JVM).
-statOption
Determines the statistics information that jstat displays. The following table lists the available options. Use the -options general option to display the list of options for a particular platform installation.
Option Displays...
class Statistics on the behavior of the class loader.
compiler Statistics of the behavior of the HotSpot Just-in-Time compiler.
gc Statistics of the behavior of the garbage collected heap.
gccapacity Statistics of the capacities of the generations and their corresponding spaces.
gccause Summary of garbage collection statistics (same as -gcutil), with the cause of the last and current (if applicable) garbage collection events.
gcnew Statistics of the behavior of the new generation.
gcnewcapacity Statistics of the sizes of the new generations and its corresponding spaces.
gcold Statistics of the behavior of the old and permanent generations.
gcoldcapacity Statistics of the sizes of the old generation.
gcpermcapacity Statistics of the sizes of the permanent generation.
gcutil Summary of garbage collection statistics.
printcompilation HotSpot compilation method statistics.
-h n
Display a column header every n samples (output rows), where n is a positive integer. Default value is 0, which displays the column header above the first row of data.
-t n
Display a timestamp column as the first column of output. The timestamp is the the time since the start time of the target JVM.
-JjavaOption
Pass javaOption to the java application launcher. For example, -J-Xms48m sets the startup memory to 48 megabytes. For a complete list of options, see java - the Java application launcher
举例:
>jps
3672
2884 PluginMain
2648 LauncherServlet
2312
5800 Jps
>jstat -compiler 2648 5s 3
4. Jinfo
显示 Java 配置信息
prints Java configuration information for a given Java process or core file or a remote debug server. Configuration information includes Java System properties and Java virtual machine command line flags.
注意:目前 不支持 linux/Windows
5. Jstack
Statck Trace
jstack prints Java stack traces of Java threads for a given Java process or core file or a remote debug server
ex. jstatck -l 2648
6. HPROF - a heap/cpu Profilling Tool
hprof usage: java -agentlib:hprof=[help]|[
2009年5月27日星期三
yahoo placemaker
试了一下 yahoo placemaker,挺好玩的,可以分析语句,生成跟语句中的地点相关的信息
< form action="http://wherein.yahooapis.com/v1/document" method="post" >
< input type=hidden name='documentContent' value='I+live+in+New+York+City' / >
< input type=hidden name='documentType' value='text/plain' / >
< input type=hidden name='appid' value='ySOQPlDV34Ea0e1nhi3ZyHD1nooglUzN01Vu4lrco757yLobAR3CYWq_uoTljNRdcw--' / >
< input type=hidden name='outputType' value='rss' / >
< input type='submit' value='click' / >
< /form >
此外,还有一个第三方的js 库 jsplacemaker ,对 placemaker 进行了封装,返回结构化的数据
< form action="http://wherein.yahooapis.com/v1/document" method="post" >
< input type=hidden name='documentContent' value='I+live+in+New+York+City' / >
< input type=hidden name='documentType' value='text/plain' / >
< input type=hidden name='appid' value='ySOQPlDV34Ea0e1nhi3ZyHD1nooglUzN01Vu4lrco757yLobAR3CYWq_uoTljNRdcw--' / >
< input type=hidden name='outputType' value='rss' / >
< input type='submit' value='click' / >
< /form >
此外,还有一个第三方的js 库 jsplacemaker ,对 placemaker 进行了封装,返回结构化的数据
签名jar 或生成证书
keytool -genkey -dname "cn=BeanSoft Studio, ou=Java Software, o=BeanSoft Studio, c=China" -alias beansoft -keypass beansoft -storepass beansoft -validity 365 -keystore .\beansoft
keytool -export -alias secfox -file d:\test\mycerts.cer -storepass secfox
1. 生成 keystore(keytool -genkey)
ex. keytool -genkey -dname "cn=BeanSoft Studio, ou=Java Software, o=BeanSoft Studio, c=China" -alias beansoft -keypass beansoft -storepass beansoft -validity 365 -keystore .\beansoft
注:必须指定 alias ,否则无法对 jar 进行签名
2. 导出证书(给 applet 签名不需要这一步,如果时需要提供 ssl 访问时,则需要导出证书,放入 web 服务器)
ex. keytool -export -keystore .\beansoft -storepass beansoft -file beansoft.cer -alias beansoft
3. 对 jar 进行签名
ex. jarsigner -verbose -keystore .\beansoft applets.jar beansoft
这样,签名后的 jar 就可以直接作为 applet 使用了
keytool -export -alias secfox -file d:\test\mycerts.cer -storepass secfox
1. 生成 keystore(keytool -genkey)
ex. keytool -genkey -dname "cn=BeanSoft Studio, ou=Java Software, o=BeanSoft Studio, c=China" -alias beansoft -keypass beansoft -storepass beansoft -validity 365 -keystore .\beansoft
注:必须指定 alias ,否则无法对 jar 进行签名
2. 导出证书(给 applet 签名不需要这一步,如果时需要提供 ssl 访问时,则需要导出证书,放入 web 服务器)
ex. keytool -export -keystore .\beansoft -storepass beansoft -file beansoft.cer -alias beansoft
3. 对 jar 进行签名
ex. jarsigner -verbose -keystore .\beansoft applets.jar beansoft
这样,签名后的 jar 就可以直接作为 applet 使用了
2009年2月27日星期五
安装盘制作工具调研报告
注:这是 2004 年写的一篇老文了,现在我们用 innosetup ,用起来也比较顺手,主要是通过脚本,但可以先生成一个样例脚本,然后再在上面修改,以适合自己的需求。
目的
在目前可以获得的资料的基础上,对目前市场上的各种安装工具进行比较,并最终选出一个或两个适合我们的产品使用的安装工具。
参考的工具有:InstallAnywhere V6(Zero G), InstallShield X (InstallShield) , EasySetUp V3.04(Bersoft Inc.),小颖安装程序制作专家V5
概述
目前市场占有率最高的产品应该是InstallShield,但InstallShield提供的例子或模板更多的是针对Windows平台的,不过最新的版本X也提供了对别的平台的支持。Install Anywhere 由于它本身是用Java开发的,它提供的例子主要是基于Java的,另外由于众所周知的Java程序的跨平台性,所以它声称可以支持各种平台。在Java应用的安装程序方面,Install Anywhere应该是市场占有率最高的产品。另外,还有一些别的产品,比如Bersoft公司的EasySetup,非常简洁易用,但功能似乎又不够强。以上这些都是国外的产品,国内的产品应该也有一些,但目前我看到的一些都是大同小异,所以只列出一个“小颖安装制作程序”。
另外,大多数安装软件都有一些共有的功能,比如最基本的文件拷贝功能,反安装程序的生成等等,对于需求简单的安装制作,这些基本功能就可以满足。
各种产品的功能特点
1、InstallShield
InstallShield是著名的专业的安装程序制作软件,使用非常广泛。它包含Windows Installer(MSI)支持、可视化对话框编辑器(Visual Dialog Editor)、源代码控制等。还可以与Visual Studio .NET结合、可以创建补丁、支持修改Autoexec.bat, config.sys、注册表、加入产品的注册码,自动生成反安装程序等,功能非常强大。
主要功能列表如下:
¨ 平台相关的功能
运行时:Windows 95/98/NT 4/2000/Win ME/XP/AIX
设计时:Windows 98/NT4/2000/Me/XP
支持所有Palm OSR 装置及所有Windows Mobile 装置
支持64位应用
支持多种语言
¨ 自定义功能
全新视觉对话框编辑器(Visual Dialog Editor)
可以增加新对话框或自定义对话框中的文本与位图
轻松建立自定义事件(Custom Events)
可以通过InstallScript加入自定义的逻辑
提供VB Script 及JScript Code 编辑器
¨ 其它
支持JVM Handling,XML及Apache Ant Target处理
提供一系列安装选择
整合的Add-In 管理员
完整的Windows安装支持(MSI)
在执行之前会检验及安装前提(Installation Prerequisites)
自动查找与包含安装依赖的文件。
轻松建立Patches及更新
可以创建不同发布版本间的更新版本
自动修复、按需安装
支持SQL 服务器 -
支持IIS Web 服务器,可以容易地发布与安装Web程序
可以创建.net安装程序与分发.net框架。
在同一系统上安装一个应用的多份拷贝
可视化的注册表\shell编辑
可以运行外部程序(e.g.,EXE,DLL,VBScript)
内置包含第三方的技术模块
动态文件链接
可以创建可重用的组件
提供命令行编译工具
可以发布自解压程序及自定义卸载程序
可以通过Internet分发
2、Install Anywhere
InstallAnywhere由Zero G公司开发。Zero G在多平台软件部署和维护领域是佼佼者。其代表产品有InstallAnywhere和PowerUpdate。InstallAnywhere使用简单、高效,并在提供跨平台支持的同时支持29种语言(包括简体中文)赢得了很多客户的青睐。
InstallAnywhere是多平台软件配置的业界领先者,数以千万计的软件采用它来安装和配置。软件的创新者,例如Adobe, Borland, HP, i2, IBM, Intel, 朗讯, 北电, Sun和TIBCO,这些业界的领先者采用InstallAnywhere来实现快速、强大、直观的安装。事实上,由<软件杂志>评选出的全球25大软件厂商都使用了InstallAnywhere。
主要功能列表如下:
¨ 平台相关:
已经扩大了对于Red Hat Enterprise Server, SUSE Linux, z/OS 和 OS/390. 平台的支持。其他支持的平台还有Windows Server 2003 以至整个Windows 家族, Solaris, AIX, HP-UX, Linux, NetWare, Mac OS X, IRIX, Tru64, FreeBSD,和所有其他JAVA能够运行的平台。 InstallAnywhere与所有的JAVA版本兼容,包括Sun、IBM、Apple和其他公司最新发布的JAVA执行器。
¨ 针对平台的功能
Windows 注册:检索、设置并检验现有的主键和数据
Windows 快捷键:Mac aliases (with Dock support), UNIX 链接
Windows 服务:安装、启动、停止、暂停任何服务
本地化的Windows, Mac OS, UNIX 使用效果
设置Windows和UNIX环境下的系统环境变量
集成 Linux RPM
Windows 卸载工具支持注册表的重新运行以及新增/移除程序
自动修改起始的脚本文件和 UNIX daemons文件
¨ 针对 Java 应用程序配置的功能
自动安装Java VM。
完全支持所有的Java1.3版本,甚至包括Java 1.4 和J2EE 1.3 甚至J2SE1.5
安装EJBs, servlets, JSPs, JAR, WAR, 和EAR archives
创建 LaunchAnywhere (Zero G的Java应用程序发布技术) ,终端用户只需双击 Windows或Mac上的图标,或是在Solaris和Linux上输入简单的命令,就可以启动Java 程序。
Java Classpath 和主类的自动检测。
完全支持所有的Java运行选项。
针对服务器、 Web Services 和J2EE 配置的功能
¨ 内置功能
内置安装步骤列表,突出安装的每一阶段
内置安装器面板:介绍、要点、协议、选择安装文件、用户输入、密码、序列号、功能集、部件、安装摘要,等等。
内置的命令行控制台的交互以匹配图象化的面板
内置动作:创建快捷键、释放归档文件、使用搜索和替代功能修改文本文件,安装并控制Windows Services、设置注册表录入、设置环境变量执行命令和脚本,等等。
内置规则:检验平台、对比变量、验证用户输入、检验位置、确认文件/文件夹的属性
¨ 扩展性
用户可使用Java和基于JavaBeans的开放API,扩展设计自定义的动作、面板和控制台
插入行为(Pluggable Actions):可定制用户自己设计器中调色板的编码行为和面板
项目模板(Project Templates):创建能够多次统一重复使用的项目模板。
¨ 其它主要功能
通用的安装、配置和客户化功能
可以在终端用户的系统上,将文件和文件夹安装于任何位置
在Read Me, License Agreement和其他的安装面板中完全支持HTML格式的文本。
完全的鼠标拖动支持,上下文右击菜单可以快速地获取常用的功能。
使用GIF, JPEG, 和PNG文件,并借助透明和动作功能完全客户化图形、公告牌、主题和品牌的显示。
合并模块技术可以方便地创建"整套"安装程序,子安装程序和模板。可以在你的开发团队甚至是整个企业内部,将安装程序的可重用性由一个项目传递到另一个项目也可源自于第三方的供应商。
卸载工具可以实现部分或全部的卸载功能
使用高级的搜索和替代功能修改服务器属性文件。
Magic Folders技术:为桌面、系统、主页、性能、字体以及其他位置提供的专用文件夹
Media Spanning: 媒体分割:在多张CD 或者 DVD中创建安装包,此功能对软件套件和集成项目同样有效
Localized Designer: 本地化设计器:法国,德国和日本的开发人员能够使用本地的语言创建安装包,更容易创建29种语言的安装包。
Customizable Uninstaller: 定制反安装包:在凡安装程序中,增加自己的面板,控制台和行为。 完美的完成多控件套件。
Native Package Installations: 本地包安装:作为InstallAnywhere安装程序的一部分,轻松的安装Linux RPMs,Solaris包和HP-UX库文件。
针对数据库注册选项的用户自定义面板
创建过程集成(Build Process Integration):使用Apache Ant来控制InstallAnywhere的创建过程
¨ 无论应用程序是用Java, C++, PERL, C#编写的,还是用EJB 或.NET Web services配置的,InstallAnywhere都可以将你的桌面、企业或多层Web services软件配置到你的平台上。
¨ InstallAnywhere是软件管理周期执行的第一步。 当与PowerUpdate连用时,Zero G会发布、更新解决方案,InstallAnywhere可以在任何平台上发布、安装、配置你的应用程序和软件升级程序。
3、EasySetup
EasySetup是一个简单的windows安装程序制作工具,它不仅能用来为应用创建安装程序,也可以为各种文件创建安装程序,比如word、Excel、PowerPoint、Acrobat或HTML文档。
主要特点如下:
¨ 支持32位的操作系统 Windows 95/98/2000/Me/XP/NT4
¨ 支持多语言但不支持多字节的语言,也就是说不支持中文。(不过我简单测试了一下,还是支持的)
¨ 可以对安装过程中的对话框中的内容进行修改
¨ 它制作的安装与卸载程序体积较小而且快
¨ 支持Exe安装文件的创建,也支持简单的在线发布
¨ 可以比较文件版本信息、替换正在使用的文件,注册DLL/OCX控件,安装字体
¨ 可以创建快捷方式
¨ 可以创建口令保护
4、小颖安装制作程序
这是国产的一款个人制作的软件,界面很简单,可以完成一些简单的但常用的功能。主要包括以下功能:
¨ 开发环境及运行环境只能是在windows上
¨ 支持简体中文、繁体中文、英文
¨ 可以设置安装程序的安装路径
¨ 可以更改图标及界面显示内容
¨ 可以在安装运行前运行别的程序
¨ 可以显示协议、注册信息等对话框
¨ 包含了程序附加组件(BDE、MDAC2.6、Microsoft SQL Server Client)
¨ 可以操作注册表、安装字体
¨ 可以制作卸载程序
结论及建议
综上所述,EasySetup与小颖安装程序都太过简单,不太适宜用于比较复杂的大型应用程序的安装。InstallShield功能强劲,但自定义的使用相对比较繁琐,必须重新学习并使用其自带的InstallScript脚本语言。而且,其一贯对跨平台的支持不是太令人满意,对Java的支持也是其较弱的部分。
InstallAnywhere由于其一贯的对跨平台支持良好,而且其本身是用Java开发的,对其进行扩展也是通过通用的JavaBean标准,学习起来也比较容易。所以,对于用Java应用来说,个人觉得使用InstallAnywhere来做安装程序更合适。
目的
在目前可以获得的资料的基础上,对目前市场上的各种安装工具进行比较,并最终选出一个或两个适合我们的产品使用的安装工具。
参考的工具有:InstallAnywhere V6(Zero G), InstallShield X (InstallShield) , EasySetUp V3.04(Bersoft Inc.),小颖安装程序制作专家V5
概述
目前市场占有率最高的产品应该是InstallShield,但InstallShield提供的例子或模板更多的是针对Windows平台的,不过最新的版本X也提供了对别的平台的支持。Install Anywhere 由于它本身是用Java开发的,它提供的例子主要是基于Java的,另外由于众所周知的Java程序的跨平台性,所以它声称可以支持各种平台。在Java应用的安装程序方面,Install Anywhere应该是市场占有率最高的产品。另外,还有一些别的产品,比如Bersoft公司的EasySetup,非常简洁易用,但功能似乎又不够强。以上这些都是国外的产品,国内的产品应该也有一些,但目前我看到的一些都是大同小异,所以只列出一个“小颖安装制作程序”。
另外,大多数安装软件都有一些共有的功能,比如最基本的文件拷贝功能,反安装程序的生成等等,对于需求简单的安装制作,这些基本功能就可以满足。
各种产品的功能特点
1、InstallShield
InstallShield是著名的专业的安装程序制作软件,使用非常广泛。它包含Windows Installer(MSI)支持、可视化对话框编辑器(Visual Dialog Editor)、源代码控制等。还可以与Visual Studio .NET结合、可以创建补丁、支持修改Autoexec.bat, config.sys、注册表、加入产品的注册码,自动生成反安装程序等,功能非常强大。
主要功能列表如下:
¨ 平台相关的功能
运行时:Windows 95/98/NT 4/2000/Win ME/XP/AIX
设计时:Windows 98/NT4/2000/Me/XP
支持所有Palm OSR 装置及所有Windows Mobile 装置
支持64位应用
支持多种语言
¨ 自定义功能
全新视觉对话框编辑器(Visual Dialog Editor)
可以增加新对话框或自定义对话框中的文本与位图
轻松建立自定义事件(Custom Events)
可以通过InstallScript加入自定义的逻辑
提供VB Script 及JScript Code 编辑器
¨ 其它
支持JVM Handling,XML及Apache Ant Target处理
提供一系列安装选择
整合的Add-In 管理员
完整的Windows安装支持(MSI)
在执行之前会检验及安装前提(Installation Prerequisites)
自动查找与包含安装依赖的文件。
轻松建立Patches及更新
可以创建不同发布版本间的更新版本
自动修复、按需安装
支持SQL 服务器 -
支持IIS Web 服务器,可以容易地发布与安装Web程序
可以创建.net安装程序与分发.net框架。
在同一系统上安装一个应用的多份拷贝
可视化的注册表\shell编辑
可以运行外部程序(e.g.,EXE,DLL,VBScript)
内置包含第三方的技术模块
动态文件链接
可以创建可重用的组件
提供命令行编译工具
可以发布自解压程序及自定义卸载程序
可以通过Internet分发
2、Install Anywhere
InstallAnywhere由Zero G公司开发。Zero G在多平台软件部署和维护领域是佼佼者。其代表产品有InstallAnywhere和PowerUpdate。InstallAnywhere使用简单、高效,并在提供跨平台支持的同时支持29种语言(包括简体中文)赢得了很多客户的青睐。
InstallAnywhere是多平台软件配置的业界领先者,数以千万计的软件采用它来安装和配置。软件的创新者,例如Adobe, Borland, HP, i2, IBM, Intel, 朗讯, 北电, Sun和TIBCO,这些业界的领先者采用InstallAnywhere来实现快速、强大、直观的安装。事实上,由<软件杂志>评选出的全球25大软件厂商都使用了InstallAnywhere。
主要功能列表如下:
¨ 平台相关:
已经扩大了对于Red Hat Enterprise Server, SUSE Linux, z/OS 和 OS/390. 平台的支持。其他支持的平台还有Windows Server 2003 以至整个Windows 家族, Solaris, AIX, HP-UX, Linux, NetWare, Mac OS X, IRIX, Tru64, FreeBSD,和所有其他JAVA能够运行的平台。 InstallAnywhere与所有的JAVA版本兼容,包括Sun、IBM、Apple和其他公司最新发布的JAVA执行器。
¨ 针对平台的功能
Windows 注册:检索、设置并检验现有的主键和数据
Windows 快捷键:Mac aliases (with Dock support), UNIX 链接
Windows 服务:安装、启动、停止、暂停任何服务
本地化的Windows, Mac OS, UNIX 使用效果
设置Windows和UNIX环境下的系统环境变量
集成 Linux RPM
Windows 卸载工具支持注册表的重新运行以及新增/移除程序
自动修改起始的脚本文件和 UNIX daemons文件
¨ 针对 Java 应用程序配置的功能
自动安装Java VM。
完全支持所有的Java1.3版本,甚至包括Java 1.4 和J2EE 1.3 甚至J2SE1.5
安装EJBs, servlets, JSPs, JAR, WAR, 和EAR archives
创建 LaunchAnywhere (Zero G的Java应用程序发布技术) ,终端用户只需双击 Windows或Mac上的图标,或是在Solaris和Linux上输入简单的命令,就可以启动Java 程序。
Java Classpath 和主类的自动检测。
完全支持所有的Java运行选项。
针对服务器、 Web Services 和J2EE 配置的功能
¨ 内置功能
内置安装步骤列表,突出安装的每一阶段
内置安装器面板:介绍、要点、协议、选择安装文件、用户输入、密码、序列号、功能集、部件、安装摘要,等等。
内置的命令行控制台的交互以匹配图象化的面板
内置动作:创建快捷键、释放归档文件、使用搜索和替代功能修改文本文件,安装并控制Windows Services、设置注册表录入、设置环境变量执行命令和脚本,等等。
内置规则:检验平台、对比变量、验证用户输入、检验位置、确认文件/文件夹的属性
¨ 扩展性
用户可使用Java和基于JavaBeans的开放API,扩展设计自定义的动作、面板和控制台
插入行为(Pluggable Actions):可定制用户自己设计器中调色板的编码行为和面板
项目模板(Project Templates):创建能够多次统一重复使用的项目模板。
¨ 其它主要功能
通用的安装、配置和客户化功能
可以在终端用户的系统上,将文件和文件夹安装于任何位置
在Read Me, License Agreement和其他的安装面板中完全支持HTML格式的文本。
完全的鼠标拖动支持,上下文右击菜单可以快速地获取常用的功能。
使用GIF, JPEG, 和PNG文件,并借助透明和动作功能完全客户化图形、公告牌、主题和品牌的显示。
合并模块技术可以方便地创建"整套"安装程序,子安装程序和模板。可以在你的开发团队甚至是整个企业内部,将安装程序的可重用性由一个项目传递到另一个项目也可源自于第三方的供应商。
卸载工具可以实现部分或全部的卸载功能
使用高级的搜索和替代功能修改服务器属性文件。
Magic Folders技术:为桌面、系统、主页、性能、字体以及其他位置提供的专用文件夹
Media Spanning: 媒体分割:在多张CD 或者 DVD中创建安装包,此功能对软件套件和集成项目同样有效
Localized Designer: 本地化设计器:法国,德国和日本的开发人员能够使用本地的语言创建安装包,更容易创建29种语言的安装包。
Customizable Uninstaller: 定制反安装包:在凡安装程序中,增加自己的面板,控制台和行为。 完美的完成多控件套件。
Native Package Installations: 本地包安装:作为InstallAnywhere安装程序的一部分,轻松的安装Linux RPMs,Solaris包和HP-UX库文件。
针对数据库注册选项的用户自定义面板
创建过程集成(Build Process Integration):使用Apache Ant来控制InstallAnywhere的创建过程
¨ 无论应用程序是用Java, C++, PERL, C#编写的,还是用EJB 或.NET Web services配置的,InstallAnywhere都可以将你的桌面、企业或多层Web services软件配置到你的平台上。
¨ InstallAnywhere是软件管理周期执行的第一步。 当与PowerUpdate连用时,Zero G会发布、更新解决方案,InstallAnywhere可以在任何平台上发布、安装、配置你的应用程序和软件升级程序。
3、EasySetup
EasySetup是一个简单的windows安装程序制作工具,它不仅能用来为应用创建安装程序,也可以为各种文件创建安装程序,比如word、Excel、PowerPoint、Acrobat或HTML文档。
主要特点如下:
¨ 支持32位的操作系统 Windows 95/98/2000/Me/XP/NT4
¨ 支持多语言但不支持多字节的语言,也就是说不支持中文。(不过我简单测试了一下,还是支持的)
¨ 可以对安装过程中的对话框中的内容进行修改
¨ 它制作的安装与卸载程序体积较小而且快
¨ 支持Exe安装文件的创建,也支持简单的在线发布
¨ 可以比较文件版本信息、替换正在使用的文件,注册DLL/OCX控件,安装字体
¨ 可以创建快捷方式
¨ 可以创建口令保护
4、小颖安装制作程序
这是国产的一款个人制作的软件,界面很简单,可以完成一些简单的但常用的功能。主要包括以下功能:
¨ 开发环境及运行环境只能是在windows上
¨ 支持简体中文、繁体中文、英文
¨ 可以设置安装程序的安装路径
¨ 可以更改图标及界面显示内容
¨ 可以在安装运行前运行别的程序
¨ 可以显示协议、注册信息等对话框
¨ 包含了程序附加组件(BDE、MDAC2.6、Microsoft SQL Server Client)
¨ 可以操作注册表、安装字体
¨ 可以制作卸载程序
结论及建议
综上所述,EasySetup与小颖安装程序都太过简单,不太适宜用于比较复杂的大型应用程序的安装。InstallShield功能强劲,但自定义的使用相对比较繁琐,必须重新学习并使用其自带的InstallScript脚本语言。而且,其一贯对跨平台的支持不是太令人满意,对Java的支持也是其较弱的部分。
InstallAnywhere由于其一贯的对跨平台支持良好,而且其本身是用Java开发的,对其进行扩展也是通过通用的JavaBean标准,学习起来也比较容易。所以,对于用Java应用来说,个人觉得使用InstallAnywhere来做安装程序更合适。
2009年2月18日星期三
关于tomcat6+1.6服务无法启动的问题
关于tomcat6+1.6服务无法启动的问题:
安装为服务后,服务无法启动,据说只影响 Windows2003
过程:
在我本地安装,起动没有任何问题(windowsXP ,设置了 JAVA_HOME)
在同事的机器上安装,也没有问题(windowsXP ,未设置 JAVA_HOME)
客户现场安装,当时的机器是一台是 windows2003,一台是 XP,据说都没有正常启动
找了一台 windows2003 虚拟机, Enterprise sp1(R),安装无法启动,经多次测试,只需要在 service.bat 增加 JAVA_HOME 变量设置即可
另,发现 secfoxSNI的安装文件中的 service.bat 中,没有增加启动参数,应该增加,类似下面的代码最后的参数
"%EXECUTABLE%" //US//%SERVICE_NAME% ++JvmOptions "-Djava.io.tmpdir=%CATALINA_BASE%\temp" --JvmMs 512 --JvmMx 1024 --JvmSs 64
安装为服务后,服务无法启动,据说只影响 Windows2003
过程:
在我本地安装,起动没有任何问题(windowsXP ,设置了 JAVA_HOME)
在同事的机器上安装,也没有问题(windowsXP ,未设置 JAVA_HOME)
客户现场安装,当时的机器是一台是 windows2003,一台是 XP,据说都没有正常启动
找了一台 windows2003 虚拟机, Enterprise sp1(R),安装无法启动,经多次测试,只需要在 service.bat 增加 JAVA_HOME 变量设置即可
另,发现 secfoxSNI的安装文件中的 service.bat 中,没有增加启动参数,应该增加,类似下面的代码最后的参数
"%EXECUTABLE%" //US//%SERVICE_NAME% ++JvmOptions "-Djava.io.tmpdir=%CATALINA_BASE%\temp" --JvmMs 512 --JvmMx 1024 --JvmSs 64
订阅:
博文 (Atom)