2006年10月12日

获得jar包存放路径的方法

zeal 2006-07-11 09:45 于 JAVA/C++ , 1371 字 |  + 0 - 0   English
Made In Zeal 转载请保留原始链接:http://www.zeali.net/entry/404
关键字: ,,

  在 java 中, System.getProperty("user.dir") 得到的是当前工作路径(对应命令行命令就是 linux 下的 pwd 、 windows 下的 cd ),而 System.getProperty("user.home") 得到的是当前用户主目录(对应于 linux 下的 ~ 目录、 windows 下的 document and settings\username );但如果你想得到所运行的 java 程序所在的路径,似乎并没有什么简单的方法。

  比如说,有一个 pathTest.jar 包放在 D:\zeal\webdev 下,这个 jar 执行的时候需要在当前目录下读写一个 test.log 文件。如果不采用绝对路径来读写 test.log 的话,不同的 jar 运行方式会带来不同的结果:

cd D:\zeal\webdev
java -jar pathTest.jar

           ( test.log 将生成在 D:\zeal\webdev 目录下 )

cd E:\sun\jre\bin
java -jar D:\zeal\webdev\pathTest.jar

           ( test.lgo 将生成在 E:\sun\jre\bin 目录下 )

  这势必造成潜在的运行错误。解决的方法是必须在程序中指定 test.log 文件的绝对路径。从本意上来讲,这里我们希望 test.log 与 pathTest.jar 位于相同的路径之下。但显然无论是 "user.dir" 还是 "user.home" 都不会返回正确的结果。

  幸好, java 允许我们定位某个 class 的 CodeSource , 通过 CodeSource 提供的 Location 信息就能够找到相关的文件路径。假设 pathTest.jar 的 main class 是 pathTest ,通过

new pathTest().getClass().getProtectionDomain().getCodeSource().getLocation();

  就可以得到 pathTest.jar 的完整路径( file:/D:/zeal/webdev/pathTest.jar ),接下来怎么做就简单了。当然,实际应用中一般我们会选择把所有与jar相关的资源文件一起打包进去,或者使用 "user.home" 这样的固定位置来存放;除非在特殊情况下才会需要通过这个迂回的方式来获取相关的路径信息。

注: CodeSource 得到的是类所在域信息,对于 jar 包返回的就是该 jar 包的完整路径文件名;如果是没有打包的 classpath 下的类,返回的则是该 classpath 的根路径。

2006年07月05日

java.lang.NoSuchMethodError: javax.servlet.jsp.tagext.TagAttributeInfo.<init>(Ljava/lang/String;ZLjava/lang/String;ZZ)V
 org.apache.jasper.compiler.TagLibraryInfoImpl.createAttribute(TagLibraryInfoImpl.java:568)
 org.apache.jasper.compiler.TagLibraryInfoImpl.createTagInfo(TagLibraryInfoImpl.java:401)
 org.apache.jasper.compiler.TagLibraryInfoImpl.parseTLD(TagLibraryInfoImpl.java:248)
 org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:162)
 org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:418)
 org.apache.jasper.compiler.Parser.parseDirective(Parser.java:483)
 org.apache.jasper.compiler.Parser.parseElements(Parser.java:1539)
 org.apache.jasper.compiler.Parser.parse(Parser.java:126)
 org.apache.jasper.compiler.ParserController.doParse(ParserController.java:220)
 org.apache.jasper.compiler.ParserController.parse(ParserController.java:101)
 org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:203)
 org.apache.jasper.compiler.Compiler.compile(Compiler.java:495)
 org.apache.jasper.compiler.Compiler.compile(Compiler.java:476)
 org.apache.jasper.compiler.Compiler.compile(Compiler.java:464)
 org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:511)
 org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:295)
 org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292)
 org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
 org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:75)

导致以上原因的是因为javax.servlet.jsp.tagext.TagAttributeInfo有冲突

当前classpath中有两个version的javax.servlet.jsp.tagext.TagAttributeInfo class,一个在servlet.jar另一个在jsp-api.jar中。 jsp-api.jar的那个是好用的,它只包含javax\servlet\jsp这个包,而servlet.jar中也包含它,同时包含servlet需要的关键包。所以在classpath中jsp-api.jar要比servlet.jar先被reference。

另外在jboss3.2.*之后的自己带的lib中已经将javax\servlet\jsp从servlet.jar中分开了,分别是javax.servlet.jar(jsp-api.jar)和javax.servlet.jsp.jar(serlvet-api.jar).

2006年06月04日

前些时候用IntelliJ IDEA开发部署一个工程,用的数据库是oracle,该加入的lib包我都加了,但我在IDEA中运行起来后老是提示下面这个信息

Cannot create JDBC driver of class ‘ ‘ for connect URL ‘null’, cause: No suitable driver

在google上搜的到的文章大部分都是说数据库驱动没有加入到lib包中,而我的classes12.jar已经放在tomcat下的common/lib下了,后来我又试着单独起tomcat,结果没有任何问题,呵呵,如果这样我就继续开发,那就痛苦死了,不能在IDEA下调试开发简直就是恶梦。

我想起了我在IDEA 4.5的时候没有碰到这个问题,而且有一个一摸一样的工程也在我现在的IDEA 5.1下没有这个问题,只是这个工程是我从4.5的时候就用,通过升级IDEA而使IDEA变成5.1的,会不会是IDEA的问题呢?重装一个IDEA4.5,同样的工程和部署过程,结果真的没有这个问题了,看来真的可能是idea的问题。

我仔细看了idea4.5和5.0的不同之处,终于在idea中的web module settings中发现不同了(其实由那个异常我也怀疑到是idea没有找到配置数据库连接池的context文件),在idea的Deployment Descriptors中,4.5没有详细要求指出context的位置,它只需要Web Module Deployment Descriptor,它默认会自己去找tomcat下的context,而5.0需要我们自己将context指出所在位置,也就是会多一个Tomcat Context Descriptor配置项,因为我的工程没有将context写在server.xml中,而是放在tomcat的conf\Catalina\localhost下,所以5.0的Tomcat Context Descriptor就应该指定到那里context的xml文件。

经过这样的配置,就可以用idea5来开发部署我的这个工程了,也没有再抛那个错误了。

2006年05月11日
ssl.ca-0.1生成的证书有效期是从当前时间到一年后(365天),即有效期一年。
解决方法:
编辑sign-server-cert.sh
将default_days的365改为其它天数,下面显示改为3650天,即十年。
default_days  = 3650
2006年04月28日

为了五一回到女朋友家,昨天送我妹妹后就去北京站排队买票,5点到的,找了一个稍微短点的队伍排,等到了7点时,我们排到了第9位,可是7点过了好久也没看见一个人买完票出来,等到我们买票时已经过去了40分钟了,结果没了,只有站票,唉,索性就买了两个五一的站票。

今天MM不甘心,又去了东门一个售票点,结果竟然有了2号的票,立即买了,准备这两天把昨天买的票给退了。唉,要亏80多块…..

破火车,到她家竟然只有一趟,而且还经过最热门的哈尔滨,所以总是缺票,不像到我家,有10条多火车到,而且还有直达汽车。rp啊!!!

2006年04月06日

公司在很多运营点的系统经常不知怎么弄的就访问缓慢,我们登陆到系统上去看,结果用netstat看到很多tcp或udp连接处于TIME_WAIT状态,查看一下tocmat的日志,又发现了c3p0报的An attempt by a client to checkout a Connection has timed out.错误,老毛病,dns配的有问题,或dns不起作用了,重新设置一个新的好用的dns,重启tomcat,系统恢复正常。

虽然问题解决了,但是不知道原因。明明我们配置的都是ip地址,怎么还被dns所影响呢?

另外我也总结了一个经验,就是用netstat -a查看连接的时候,如果显示的很慢,这个系统肯定有问题,dns不好使了。

2006年03月30日

一直以来系统使用的都是自己生成的证书,不知为什么就有的机器的系统就是不能访问https,还非得用firefox才行,这样对客户就提出了要求,显然不合适!花了一天的时间,在本机做个几个虚拟机来重现问题,终于发现竟然是证书做的不合适的原因,更详细的原因我也不会解释。暂时把自己生成证书的步骤给弄出来,做参考。

使用的软件是ssl.ca-0.1, 下载位置是http://www.openssl.org/contrib/ssl.ca-0.1.tar.gz

[root@localhost huyd]# tar zxvf ssl.ca-0.1.tar.gz

[root@localhost huyd]# cd ssl.ca-0.1

[root@localhost ssl.ca-0.1]# ./new-root-ca.sh

No Root CA key round. Generating one

Generating RSA private key, 1024 bit long modulus

……………………….++++++

….++++++

e is 65537 (0×10001)

Enter pass phrase for ca.key:

Verifying – Enter pass phrase for ca.key:

 

 

Self-sign the root CA…

Enter pass phrase for ca.key:

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter ‘.’, the field will be left blank.

—–

Country Name (2 letter code) [MY]:CN

State or Province Name (full name) [Perak]: Beijing

Locality Name (eg, city) [Sitiawan]:Cernet

Organization Name (eg, company) [My Directory Sdn Bhd]:Cernet

Organizational Unit Name (eg, section) [Certification Services Division]:Cerne

t

Common Name (eg, MD Root CA) []:Cernet ROOT CA

Email Address []:webmaster@cernet.com

 

 

[root@localhost ssl.ca-0.1]# ./new-server-cert.sh server

No server.key round. Generating one

Generating RSA private key, 1024 bit long modulus

………………++++++

…..++++++

e is 65537 (0×10001)

 

 

Fill in certificate data

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter ‘.’, the field will be left blank.

—–

Country Name (2 letter code) [MY]:CN

State or Province Name (full name) [Perak]: Beijing

Locality Name (eg, city) [Sitiawan]:Cerent

Organization Name (eg, company) [My Directory Sdn Bhd]:Cernet

Organizational Unit Name (eg, section) [Secure Web Server]:Cernet

Common Name (eg, www.domain.com) []:www.cernet.com

Email Address []:webmaster@cernet.com

 

 

You may now run ./sign-server-cert.sh to get it signed

 

 

[root@localhost ssl.ca-0.1]# ./sign-server-cert.sh server

CA signing: server.csr -> server.crt:

Using configuration from ca.config

Enter pass phrase for ./ca.key:

Check that the request matches the signature

Signature ok

The Subject’s Distinguished Name is as follows

countryName           :P RINTABLE:’CN’

stateOrProvinceName   :P RINTABLE:’ Beijing’

localityName          :P RINTABLE:’Cerent’

organizationName      :P RINTABLE:’Cernet’

organizationalUnitName:PRINTABLE:’Cernet’

commonName            :P RINTABLE:’www.cernet.com’

emailAddress          :IA5STRING:’webmaster@cernet.com’

Certificate is to be certified until Mar 30 08:28:17 2007 GMT (365 days)

Sign the certificate? [y/n]:y

 

 

 

 

1 out of 1 certificate requests certified, commit? [y/n]y

Write out database with 1 new entries

Data Base Updated

CA verifying: server.crt <-> CA cert

server.crt: OK

 

 

[root@localhost ssl.ca-0.1]# ls

ca.crt        COPYING             random-bits  sign-server-cert.sh

ca.db.certs   new-root-ca.sh      README       sign-user-cert.sh

ca.db.index   new-server-cert.sh  server.crt   VERSION

ca.db.serial  new-user-cert.sh    server.csr

ca.key        p12.sh              server.key

生成的两个主要文件就是server.key和server.crt  然后在ssl.conf中配置证书文件为这两个:

SSLCertificateFile /home/httpd/conf/server.crt

 

 

SSLCertificateKeyFile /home/httpd/conf/server.key

这里生成的证书文件有效期只有一年,从当前时间到一年后,如果客户端时间超期,提示会说证书过期,但不会影响使用。

 

 

 

 附:网上关于ssl的介绍,其中最后一个问题的就是我现在碰到的问题,它的回答简直就是废话!!!
1、什么是SSL协议? 
答:SSL(Secure Sockets Layer:安全套接层)是一种提供INTERNET上保密性的在线协议。它允许客户/服务器应用以一种不能被偷听的方式通讯。它是INTERNET网上安全通讯与交易的标准。SSL协议使用通讯双方的证书,在通讯双方间建立一条安全的、可信任的通讯通道。
2、什么是SSL安全认证网关? 
答:SSL安全认证网关是一款用于保护应用系统、数据库系统、网站系统的安全认证产品。SSL安全认证网关需要和数字证书配合使用,它架设在受保护的服务器前,当用户需要访问这些服务器时需要访问用户提交数字证书,SSL网关将用户提交的数字证书通过网络在新疆CA中心(或用户内部的LDAP服务器)进行证书有效性验证后,只允许合法的用户访问系统,从而保证了系统的访问安全。
3、SSL安全认证网关的技术工作原理? 
答:通过使用X.509 certificates, RSA Public Key Cipher和其它额外的安全特性来进行通信和认证,IIS 5.0 为SSL提供了一个高性能的实现。SSL可以让一个客户和服务器以协商好的安全和认证级别来进行通信。当一个连接被初始化时,SSL需要协商好一个对称密钥和认证级别。这个对称的密钥是用来加密和解密数据的。在连接正在被建立的时候,还需要进行客户/服务器的认证。当协商完成后,客户和服务器可以通过加密数据,以一个安全的方式进行数据传送。
4、SSL网关的基本功能是什么?n 
答:1)对客户端身份进行有效的认证 n 
    2)与客户端建立安全加密通道,加密强度达128位 n 
    3)解密客户端所发数据 n 
    4)加密发送给客户端的所有数据 n 
    5)防止通讯数据被篡改 n 
    6)具备资源访问控制的功能 n
    7)向应用系统提供接口,使应用系统获取用户真实身份和权限属性,以便
        进行访问控制
5、用户或应用程序是如何与SSL安全认证网关交互的? 
答:B/S模式下建立安全通道的基本过程如下:
    1. SSL服务器接收来自客户端浏览器的证书,并验证其有效性;
    2. SSL服务器将自己的公钥传输给客户端浏览器;
    3. 浏览器生成一个随机的会话密钥;
    4. 浏览器用SSL服务器的公钥加密该会话密钥;
    5. 浏览器将会话密钥的加密结果发送给SSL服务器安全代理;
    6. SSL服务器安全代理用自己的私钥解密得出真正的会话密钥; 
    现在浏览器和SSL服务器安全代理都拥有同样的会话密钥,双方可以放心使用这个
会话密钥来加密通讯内容。
    安全通讯通道建立成功。
6、为什么需要SSL ? 
答:大家知道,现有的网络应用系统普遍缺乏必要的安全保障设施。近来黑客获取网络上的他人私有信息的事件时有发生。网上金融以及国家、企业、个人的重要数据在这个越来越开放的网络环境中传输的安全性得到了前所未有的重视。SSL能够提供一条点到点的安全连接。利用SSL技术,在互联网上传输的数据都是被经过加密的密文。其他人即使获取了该数据,由于没有解密密钥,也无法识别其中传输的信息。而且,每次进行SSL连接所产生的会话密钥都是临时的,也使得破解经过SSL加密的数据难上加难。SSL的功能加以扩展使其不仅仅能保护HTTP的通讯,还能保护所有的TCP通讯成为一种较为廉价的选择。这种方式同时解决了SSL连接加密强度不够的问题能够提供端到端128位的连接,这将给电子商务应用到来很大好处。所以,SSL成为保障网上信息安全的首选。
7、使用SSL 网关后,有的浏览器能够访问,有的浏览器不能访问,如何解决?
答: 存在几种情况:
    1. 在通过IE浏览器https访问过程中,并未弹出个人证书的选择框,而直接出现“该页无法显示”的情况,这种情况一般是由于客户端与SSL网关网络不通造成。若网络通畅,请通过SSL网关的日志确诊问题。
    2. 在通过IE浏览器https访问过程中,弹出选择个人证书的选择框,若用户提交了个人证书,浏览器出现“该页无法显示”的情况;这错误可以通过SSL网关的日志进行判断,一般是由于用户提交了无效的(SSL网关不认可的)个人证书造成:不是SSL网关认可的CA签发的证书、不具有“数据签名”的密钥用法、个人证书存放设备存在问题等。
    3. 如果个人证书合法,仍然出现该错误,则有可能由于SSL网关强制使用128位加密导致,而当前本身浏览器并没有128位的加密强度。解决方法一是在运行参数配置中将加密强度的设置由High改为All;二是让用户升级浏览器(请从http://www.microsoft.com/china 网站下载IE128位加密包,然后安装即可 ),使其能够支持高强度的加密,这样安全性更高。

从2月18日去看房、交定金到3月28日从销售手里接过最后的贷款发票,我的买房第一阶段结束了。

真快!这是很多人听到我们买房的经历后的第一反应,是啊,真的很顺利,虽然中间也有很多小插曲,但最终我们还是达到了目标,买下了房子!

到明年6月份就是我们买房的第二阶段,但漫漫还贷的长征才刚刚开始,后面的路还很长很长,不知何时“我们的”小屋真的变成我们的小屋,真希望这一天早点到来啊!

2006年03月23日

Merlin 的魔力: Swing 的新 JFormattedTextField 组件

学会用最少的工作创建接受格式化文本的输入域


 

 

 

 

级别: 初级

John Zukowski, 总裁, JZ Ventures, Inc

2002 9 18

使用了输入校验器和焦点侦听器,接受格式化输入就不必那么困难了。在 Merlin 的魔力的这一部分,John 向您展示了如何使用新的 JFormattedTextField 组件来提示数字输入、日期输入和格式化输入。

Java 2 标准版(J2SE),版本 1.4 为可用的 GUI 元素调色板添加了 2 个新的 Swing 组件: JSpinner JFormattedTextField 。在 Merlin 的魔力专栏的第一篇我们就介绍了 JSpinner 组件;我们现在将要探讨 JFormattedTextField

虽然 JFormattedTextField 组件看起来与 JTextField 相似,但是它的行为与 JSpinner 完全不同。在最简单的情况下,您可以为电话号码提供一个类似######-####”的输入掩码,它不会接受任何不遵循那个格式的输入。在较为复杂的情况下,既有显示格式化器,也有输入格式化器。例如:编辑时,缺省日期格式化器允许根据光标的位置在可用的月或日之间滚动。

当使用 JFormattedTextField 时,可接受的输入或者是由掩码明确指定,或者是由组件的一个值指定。在后一种情况下,组件用工厂(Factory)设计模式来查找指定值类的缺省格式化器。 DefaultFormatterFactory 组件提供预先安装的日期、数字、 java.text.Format 子类的格式化器以及其他一切包罗万象的格式化器。

让我们看看如何使用组件。

配置可接受的输入

屏蔽输入一般是通过使用 MaskFormatter 类的一个实例配置的。在 javax.swing.text 包中发现, MaskFormatter 通过使用一系列字符指定可接受的输入来工作。该系列 8 个字符中的每一个都代表输入中的一个字符,下面的列表指出了这一点:

#

一个数字

?

一个字母

A

一个字母或数字

*

任意字符

U

一个字母,小写字符映射到与它们等效的大写字符上

L

一个字母,大写字符映射到与它们等效的小写字符上

H

一个十六进制数字(A-Fa-f0-9

用来转义另外一个掩码字符

除了 MaskFormatter 之外,您还可以用来自 java.text 软件包的 DateFormat NumberFormat 类指定输入格式。清单 1 显示了一些可能的格式。


清单 1. 定义输入掩码

 

// Four-digit year, followed by month name and day of month,

// each separated by two dashes (–)

DateFormat format =

  new SimpleDateFormat("yyyy–MMMM–dd");

DateFormatter df = new DateFormatter(format);

// US Social Security number

MaskFormatter mf1 =

  new MaskFormatter("###-##-####");

// US telephone number

MaskFormatter mf2 =

  new MaskFormatter("(###) ###-####");

 

一旦您指定了输入格式,您随后就要将格式化器传入 JFormattedTextField 构造器中,如下所示:

 

JFormattedTextField ftf1 = new

      JFormattedTextField(df);

 

还有其它一些可配置的选项,它们取决于您使用的格式化器。例如:用 MaskFormatter ,您能用 setPlaceholderCharacter(char) 设置占位符字符。另外,对于日期域,如果您将域初始化为某个值使一个用户知道什么样的输入格式是可接受的,这样将会有所帮助。

 


 

全部组合在一起

创建屏蔽输入域的一切都已就绪。清单 2 通过把以前的代码片断组合在一起,为您提供了一个用于检验新性能的完整示例。图 1 展示了这个示例的显示。随便调整各个掩码来检验其他的掩码字符。


1. 活动中的 JFormattedTextField


清单 2. JFormattedTextField 示例

 

import java.awt.*;

import javax.swing.*;

import javax.swing.text.*;

import java.util.*;

import java.text.*;

public class FormattedSample {

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

    JFrame f = new JFrame("JFormattedTextField Sample");

    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Container content = f.getContentPane();

    content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));

    // Four-digit year, followed by month name and day of month,

    // each separated by two dashes (–)

    DateFormat format =

      new SimpleDateFormat("yyyy–MMMM–dd");

    DateFormatter df = new DateFormatter(format);

    JFormattedTextField ftf1 = new

      JFormattedTextField(df);

    ftf1.setValue(new Date());

    content.add(ftf1);

    // US Social Security number

    MaskFormatter mf1 =

      new MaskFormatter("###-##-####");

    mf1.setPlaceholderCharacter(‘_’);

    JFormattedTextField ftf2 = new

      JFormattedTextField(mf1);

    content.add(ftf2);

    // US telephone number

    MaskFormatter mf2 =

      new MaskFormatter("(###) ###-####");

    JFormattedTextField ftf3 = new

      JFormattedTextField(mf2);

    content.add(ftf3);

    f.setSize(300, 100);

    f.show();

  }

}

 


 

参考资料

 


 

关于作者

 

John Zukowski JZ Ventures, Inc 从事战略上的 Java 咨询,同时通过 AnswerSquad.com 网站提供技术支持,并且正在与 SavaJe Technologies 公司合作开发下一代移动电话平台。他的最新著作是 Mastering Java 2, J2SE 1.4 (Sybex 出版,20024) Learn Java with JBuilder 6 (Apress出版,20023)。可以通过 jaz@zukowski.net John 联系。

 

2006年03月13日

周末给代办公积金的小姐打了个电话,询问了一下公积金贷款的情况,她告诉我公积金初审已经过了,让我等着接下来的签约等等手续,哈哈,听到这个好消息,我之前的担心都没了。

看来政府这个新公积金政策说是在3月1日执行,其实我觉得还得拖一个多月才能正式执行吧,rp爆发了,躲过一劫!