2007年7月31日
1.先安装一个Subclipse,地址:
http://subclipse.tigris.org/
2.可以通过Eclipse的Update Site安装方式:
http://subclipse.tigris.org/update_1.4.x或者
下载下来之后,解压缩复制到Eclipse目录即可。
3.启动程序后在Eclipse配置项的Team里面就会多出SVN,就可以进行配置了。
4.想要提交一个项目,对项目点击右键Team——Share project就可以将项目导入SVN了。
需要注意的是,请不要将动态生成的目录添加到SVN,否则其他人Check out的之后,再Update容易出错,例如classes目录,不需要提交上去,本地就可以了。
想要对比本地和服务器上的源代码,请使用Team——Synchronize with Repository,列出不同的文件之后,双击,既可以对比两个文件。
WebService项目会生成一个。apt_generated目录,里面包含了一些源代码,提交的时候不需要提交上去,MyEclipse在获得SVN的项目之后,会自动生成这个目录和底下的文件。
posted @
2008-12-19 11:16 心。 阅读(295) |
评论 (0) |
编辑 收藏
1) Assigned
主键由外部程序负责生成,无需Hibernate参与。
2) hilo
通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。
3) seqhilo
与hilo 类似,通过hi/lo 算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适用于支持Sequence的数据库,如Oracle。
4) increment
主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。
这种方式可能产生的问题是:如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护主键状态,不同实例可能生成同样的主键,从而造成主键重复异常。因此,如果同一数据库有多个实例访问,此方式必须避免使用。
5) identity
采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL中的主键生成机制。
6) sequence
采用数据库提供的sequence 机制生成主键。如Oralce 中的Sequence。
7) native
由Hibernate根据底层数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式。
8) uuid.hex
由Hibernate基于128 位唯一值产生算法生成16 进制数值(编码后以长度32 的字符串表示)作为主键。
9) uuid.string
与uuid.hex 类似,只是生成的主键未进行编码(长度16)。在某些数据库中可能出现问题(如PostgreSQL)。
10) foreign
使用外部表的字段作为主键。
posted @
2008-08-22 15:36 心。 阅读(288) |
评论 (0) |
编辑 收藏
JAR 文件是什么?
JAR 文件格式以流行的 ZIP 文件格式为基础,用于将许多个文件聚集为一个文件。与 ZIP 文件不同的是,JAR 文件不仅用于压缩和发布,而且还用于部署和封装库、组件和插件程序,并可被像编译器和 JVM 这样的工具直接使用。在 JAR 中包含特殊的文件,如 manifests 和部署描述符,用来指示工具如何处理特定的 JAR。
一个 JAR 文件可以用于:
□ 用于发布和使用类库
□ 作为应用程序和扩展的构建单元
□ 作为组件、applet 或者插件程序的部署单位
□ 用于打包与组件相关联的辅助资源
JAR 文件格式提供了许多优势和功能,其中很多是传统的压缩格式如 ZIP 或者 TAR 所没有提供的。它们包括:
☆ 安全性。 可以对 JAR 文件内容加上数字化签名。这样,能够识别签名的工具就可以有选择地为您授予软件安全特权,这是其他文件做不到的,它还可以检测代码是否被篡改过。
☆ 减少下载时间。 如果一个 applet 捆绑到一个 JAR 文件中,那么浏览器就可以在一个 HTTP 事务中下载这个 applet 的类文件和相关的资源,而不是对每一个文件打开一个新连接。
☆ 压缩。JAR 格式允许您压缩文件以提高存储效率。
☆ 传输平台扩展。 Java 扩展框架(Java Extensions Framework)提供了向 Java 核心平台添加功能的方法,这些扩展是用 JAR 文件打包的(Java 3D 和 JavaMail 就是由 Sun 开发的扩展例子)。
☆ 包密封。 存储在 JAR 文件中的包可以选择进行密封,以增强版本一致性和安全性。密封一个包意味着包中的所有类都必须在同一 JAR 文件中找到。
☆ 包版本控制。 一个 JAR 文件可以包含有关它所包含的文件的数据,如厂商和版本信息。
☆ 可移植性。 处理 JAR 文件的机制是 Java 平台核心 API 的标准部分。
压缩的和未压缩的 JAR
jar 工具在默认情况下压缩文件。未压缩的 JAR 文件一般可以比压缩过的 JAR 文件更快地装载,因为在装载过程中要解压缩文件,但是未压缩的文件在网络上的下载时间可能更长。
META-INF 目录
大多数 JAR 文件包含一个 META-INF 目录,它用于存储包和扩展的配置数据,如安全性和版本信息。Java 2 平台识别并解释 META-INF 目录中的下述文件和目录,以便配置应用程序、扩展和类装载器:
☆ MANIFEST.MF。 这个 manifest 文件定义了与扩展和包相关的数据。
☆ INDEX.LIST。 这个文件由 jar 工具的新选项 -i 生成,它包含在应用程序或者扩展中定义的包的位置信息。它是 JarIndex 实现的一部分,并由类装载器用于加速类装载过程。
☆ xxx.SF。 这是 JAR 文件的签名文件。占位符 xxx 标识了签名者。
☆ xxx.DSA。 与签名文件相关联的签名程序块文件,它存储了用于签名 JAR 文件的公共签名。
jar 工具
为了用 JAR 文件执行基本的任务,要使用作为Java Development Kit 的一部分提供的 Java Archive Tool (jar 工具)。用 jar 命令调用 jar 工具。表 1 显示了一些常见的应用:
表 1. 常见的 jar 工具用法
功能 |
命令 |
用一个单独的文件创建一个 JAR 文件 |
jar cf jar-file input-file... |
用一个目录创建一个 JAR 文件 |
jar cf jar-file dir-name |
创建一个未压缩的 JAR 文件 |
jar cf0 jar-file dir-name |
更新一个 JAR 文件 |
jar uf jar-file input-file... |
查看一个 JAR 文件的内容 |
jar tf jar-file |
提取一个 JAR 文件的内容 |
jar xf jar-file |
从一个 JAR 文件中提取特定的文件 |
jar xf jar-file archived-file... |
运行一个打包为可执行 JAR 文件的应用程序 |
java -jar app.jar |
可执行的 JAR
一个可执行的 jar 文件是一个自包含的 Java 应用程序,它存储在特别配置的JAR 文件中,可以由 JVM 直接执行它而无需事先提取文件或者设置类路径。要运行存储在非可执行的 JAR 中的应用程序,必须将它加入到您的类路径中,并用名字调用应用程序的主类。但是使用可执行的 JAR 文件,我们可以不用提取它或者知道主要入口点就可以运行一个应用程序。可执行 JAR 有助于方便发布和执行 Java 应用程序。
创建可执行 JAR
创建一个可执行 JAR 很容易。首先将所有应用程序代码放到一个目录中。假设应用程序中的主类是 com.mycompany.myapp.Sample。您要创建一个包含应用程序代码的 JAR 文件并标识出主类。为此,在某个位置(不是在应用程序目录中)创建一个名为 manifest 的文件,并在其中加入以下一行:
Main-Class: com.mycompany.myapp.Sample
然后,像这样创建 JAR 文件:
jar cmf manifest ExecutableJar.jar application-dir
所要做的就是这些了 -- 现在可以用 java -jar 执行这个 JAR 文件 ExecutableJar.jar。
一个可执行的 JAR 必须通过 menifest 文件的头引用它所需要的所有其他从属 JAR。如果使用了 -jar 选项,那么环境变量 CLASSPATH 和在命令行中指定的所有类路径都被 JVM 所忽略。
启动可执行 JAR
既然我们已经将自己的应用程序打包到了一个名为 ExecutableJar.jar 的可执行 JAR 中了,那么我们就可以用下面的命令直接从文件启动这个应用程序:
java -jar ExecutableJar.jar
包密封
密封 JAR 文件中的一个包意味着在这个包中定义的所有类都必须在同一个 JAR 文件中找到。这使包的作者可以增强打包类之间的版本一致性。密封还提供了防止代码篡改的手段。
要密封包,需要在 JAR 的 manifest 文件中为包添加一个 Name 头,然后加上值为“true”的 Sealed 头。与可执行的 JAR 一样,可以在创建 JAR 时,通过指定一个具有适当头元素的 manifest 文件密封一个 JAR,如下所示:
Name: com/samplePackage/
Sealed: true
Name 头标识出包的相对路径名。它以一个“/”结束以与文件名区别。在 Name 头后面第一个空行之前的所有头都作用于在 Name 头中指定的文件或者包。在上述例子中,因为 Sealed 头出现在 Name 头后并且中间没有空行,所以 Sealed 头将被解释为只应用到包 com/samplePackage 上。
如果试图从密封包所在的 JAR 文件以外的其他地方装载密封包中的一个类,那么 JVM 将抛出一个 SecurityException。
扩展打包
扩展为 Java 平台增加了功能,在 JAR 文件格式中已经加入了扩展机制。扩展机制使得 JAR 文件可以通过 manifest 文件中的 Class-Path 头指定所需要的其他 JAR 文件。
假设 extension1.jar 和 extension2.jar 是同一个目录中的两个 JAR 文件,extension1.jar 的 manifest 文件包含以下头:
Class-Path: extension2.jar
这个头表明 extension2.jar 中的类是 extension1.jar 中的类的扩展类。extension1.jar 中的类可以调用 extension2.jar 中的类,并且不要求 extension2.jar 处在类路径中。
在装载使用扩展机制的 JAR 时,JVM 会高效而自动地将在Class-Path 头中引用的 JAR 添加到类路径中。不过,扩展 JAR 路径被解释为相对路径,所以一般来说,扩展 JAR 必须存储在引用它的 JAR 所在的同一目录中。
例如,假设类 ExtensionClient 引用了类 ExtensionDemo,它捆绑在一个名为 ExtensionClient.jar 的 JAR 文件中,而类 ExtensionDemo 则捆绑在 ExtensionDemo.jar 中。为了使 ExtensionDemo.jar 可以成为扩展,必须将 ExtensionDemo.jar 列在 ExtensionClient.jar 的 manifest 的 Class-Path 头中,如下所示:
Manifest-Version: 1.0
Class-Path: ExtensionDemo.jar
在这个 manifest 中 Class-Path 头的值是没有指定路径的 ExtensionDemo.jar,表明 ExtensionDemo.jar 与 ExtensionClient JAR 文件处在同一目录中。
JAR 文件中的安全性
JAR 文件可以用 jarsigner 工具或者直接通过 java.security API 签名。一个签名的 JAR 文件与原来的 JAR 文件完全相同,只是更新了它的 manifest,并在 META-INF 目录中增加了两个文件,一个签名文件和一个签名块文件。
JAR 文件是用一个存储在 Keystore 数据库中的证书签名的。存储在 keystore 中的证书有密码保护,必须向 jarsigner 工具提供这个密码才能对 JAR 文件签名。
Keystore 数据库
JAR 的每一位签名者都由在 JAR 文件的 META-INF 目录中的一个具有 .SF 扩展名的签名文件表示。这个文件的格式类似于 manifest 文件 -- 一组 RFC-822 头。如下所示,它的组成包括一个主要部分,它包括了由签名者提供的信息、但是不特别针对任何特定的 JAR 文件项,还有一系列的单独的项,这些项也必须包含在 menifest 文件中。在验证一个签名的 JAR 时,将签名文件的摘要值与对 JAR 文件中的相应项计算的摘要值进行比较。
清单 1. 签名 JAR 中的 Manifest 和 signature 文件
Contents of signature file META-INF/MANIFEST.MF
Manifest-Version: 1.0
Created-By: 1.3.0 (Sun Microsystems Inc.)
Name: Sample.java
SHA1-Digest: 3+DdYW8INICtyG8ZarHlFxX0W6g=
Name: Sample.class
SHA1-Digest: YJ5yQHBZBJ3SsTNcHJFqUkfWEmI=
Contents of signature file META-INF/JAMES.SF
Signature-Version: 1.0
SHA1-Digest-Manifest: HBstZOJBuuTJ6QMIdB90T8sjaOM=
Created-By: 1.3.0 (Sun Microsystems Inc.)
Name: Sample.java
SHA1-Digest: qipMDrkurQcKwnyIlI3Jtrnia8Q=
Name: Sample.class
SHA1-Digest: pT2DYby8QXPcCzv2NwpLxd8p4G4=
数字签名
一个数字签名是.SF 签名文件的已签名版本。数字签名文件是二进制文件,并且与 .SF 文件有相同的文件名,但是扩展名不同。根据数字签名的类型 -- RSA、DSA 或者 PGP -- 以及用于签名 JAR 的证书类型而有不同的扩展名。
Keystore
要签名一个 JAR 文件,必须首先有一个私钥。私钥及其相关的公钥证书存储在名为 keystores 的、有密码保护的数据库中。JDK 包含创建和修改 keystores 的工具。keystore 中的每一个密钥都可以用一个别名标识,它通常是拥有这个密钥的签名者的名字。
所有 keystore 项(密钥和信任的证书项)都是用唯一别名访问的。别名是在用 keytool -genkey 命令生成密钥对(公钥和私钥)并在 keystore 中添加项时指定的。之后的 keytool 命令必须使用同样的别名引用这一项。
例如,要用别名“james”生成一个新的公钥/私钥对并将公钥包装到自签名的证书中,要使用下述命令:
keytool -genkey -alias james -keypass jamespass
-validity 80 -keystore jamesKeyStore
-storepass jamesKeyStorePass
这个命令序列指定了一个初始密码“jamespass”,后续的命令在访问 keystore “jamesKeyStore”中与别名“james”相关联的私钥时,就需要这个密码。如果 keystore“jamesKeyStore”不存在,则 keytool 会自动创建它。
jarsigner 工具
jarsigner 工具使用 keystore 生成或者验证 JAR 文件的数字签名。
假设像上述例子那样创建了 keystore “jamesKeyStore”,并且它包含一个别名为“james”的密钥,可以用下面的命令签名一个 JAR 文件:
jarsigner -keystore jamesKeyStore -storepass jamesKeyStorePass
-keypass jamespass -signedjar SSample.jar Sample.jar james
这个命令用密码“jamesKeyStorePass”从名为“jamesKeyStore”的 keystore 中提出别名为“james”、密码为“jamespass”的密钥,并对 Sample.jar 文件签名、创建一个签名的 JAR -- SSample.jar。
jarsigner 工具还可以验证一个签名的 JAR 文件,这种操作比签名 JAR 文件要简单得多,只需执行以下命令:
jarsigner -verify SSample.jar
如果签名的 JAR 文件没有被篡改过,那么 jarsigner 工具就会告诉您 JAR 通过验证了。否则,它会抛出一个 SecurityException, 表明哪些文件没有通过验证。
还可以用 java.util.jar 和 java.security API 以编程方式签名 JAR(有关细节参阅参考资料)。也可以使用像 Netscape Object Signing Tool 这样的工具。
JAR 索引
如果一个应用程序或者 applet 捆绑到多个 JAR 文件中,那么类装载器就使用一个简单的线性搜索算法搜索类路径中的每一个元素,这使类装载器可能要下载并打开许多个 JAR 文件,直到找到所要的类或者资源。如果类装载器试图寻找一个不存在的资源,那么在应用程序或者 applet 中的所有 JAR 文件都会下载。对于大型的网络应用程序和 applet,这会导致启动缓慢、响应迟缓并浪费带宽。
从 JDK 1.3 以后,JAR 文件格式开始支持索引以优化网络应用程序中类的搜索过程,特别是 applet。JarIndex 机制收集在 applet 或者应用程序中定义的所有 JAR 文件的内容,并将这些信息存储到第一个 JAR 文件中的索引文件中。下载了第一个 JAR 文件后,applet 类装载器将使用收集的内容信息高效地装载 JAR 文件。这个目录信息存储在根 JAR 文件的 META-INF 目录中的一个名为 INDEX.LIST 的简单文本文件中。
创建一个 JarIndex
可以通过在 jar 命令中指定 -i 选项创建一个 JarIndex。假设我们的目录结构如下图所示:
JarIndex
您将使用下述命令为 JarIndex_Main.jar、JarIndex_test.jar 和 JarIndex_test1.jar 创建一个索引文件:
jar -i JarIndex_Main.jar JarIndex_test.jar SampleDir/JarIndex_test1.jar
INDEX.LIST 文件的格式很简单,包含每个已索引的 JAR 文件中包含的包或者类的名字,如清单 2 所示:
清单 2. JarIndex INDEX.LIST 文件示例
JarIndex-Version: 1.0
JarIndex_Main.jar
sp
JarIndex_test.jar
Sample
SampleDir/JarIndex_test1.jar
org
org/apache
org/apache/xerces
org/apache/xerces/framework
org/apache/xerces/framework/xml4j
结束语
JAR 格式远远超出了一种压缩格式,它有许多可以改进效率、安全性和组织 Java 应用程序的功能。因为这些功能已经建立在核心平台 -- 包括编译器和类装载器 -- 中了,所以开发人员可以利用 JAR 文件格式的能力简化和改进开发和部署过程。
转自:http://linxh.bokee.com/2946294.html
posted @
2008-05-23 11:08 心。 阅读(406) |
评论 (0) |
编辑 收藏
1、禁用压缩文件夹功能
假如你打开zip文件的话用winzip或者winrar软件的话,以下优化是一个相当好的优化,Windows XP内置了对ZIP文件的,我们可以把zip文件当成文件夹浏览。不过,系统要使用部分资源来实现 这一功能,因此禁用这一功能可以提升系统性能。实现方法非常简单,只需取消zipfldr.dll的注册就可以了。
开始→运行: regsvr32 /u zipfldr.dll
2、减少开机磁盘扫描等待时间,重启时候马上你会看到效果。
开始→运行:chkntfs /t:0
3、删除系统备份文件,在各种软硬件安装妥当之后,其实XP需要更新文件的时候就很少了。
开始→运行:sfc.exe /purgecache
然后回车即可,可节省百兆。
假如担心的话,可不执行,此做法只会节省空间,而不是加速。
4、开始→运行: services.msc进入XP自带服务修改列表
在列表每个服务的属性里可选"关闭","手动","自动"。
alerter -错误警报器。 (可关闭)
application layer gateway service -给与第三者网络共享/防火墙支持的服务,有些防火墙/网络共享软件需要。占用1。5mb内存。 (可关闭)
application management-用于设定,发布和删除软件服务。
automatic updates -windows自动更新。(可关闭)
background intelligent transfer service - 这个服务原是用来实现http1.1服务器之间的信息传输,微软称支持windows更新时断点续传
clipbook - 用与局域网电脑来共享 粘贴/剪贴的内容。(可关闭)
com+Event system -一些 COM+ 软件需要。(检查你的 c:program filesComPlus Applications 目录,没东西可以把这个服务关闭)
COM+Event system application -同上 (可关闭)
COmputer browser -用来浏览局域网电脑的服务,但关了也不影响浏览!(可关闭)
cryptographic services -windows更新时用来确认windows 文件指纹的,我更新时才开启一下。 (可关闭)
DHCP client-静态IP者需要(xDSL 等)。
Distributed link tracking client-用于局域网更新连接信息,比如在电脑A有个文件,在B做了个连接,如果文件移动了,这个服务将会更新信息。占用4兆内存。 (可关闭)
Distributed Transaction coordinator-无聊的东西。 (可关闭)
DNS Client-DNS解析服务。(可关闭)
Error reporting service -错误报告器,把windows中错误报告给微软。(可关闭)
Event Log- 系统日志纪录服务,很有用于查找系统毛病.
Fast user switching compatibility-多用户快速切换服务。(可关闭)
help and support -帮助。(可关闭)
Human interface device access-支持"弱智"电脑配件的。比如键盘上调音量的按钮等等。(可关闭)
IMAPI CD-burning COM service -xp刻牒服务,用软件就不用了。占用1.6兆内存 (可关闭)
Indexing service -恐怖的xp减速……(可关闭)
Internet Connection Firewall(ICF)……-xp防火墙。(不用的话可关闭)
IPSEC Services-大众用户连边都沾不上。 (可关闭)
Logical Disk manager -磁盘管理服务。需要时它会通知你,所以一般关。 (可关闭)
Logical Disk manager administrative service-同上。 (可关闭)
messenger -不是msn,不想被骚扰的话就关。注:妖刺就是利用这个。 (可关闭)
MS software shadow copy provider-无用,据说是备份用的。但……没用。 (可关闭)
Net Logon-登陆Domain Controller用的。(可关闭)
Netmeeting remote desktop sharing-用netmeeting实现电脑共享。(可关闭)
Network Connections - 上网/局域网要用的。
Network DDE -和clipbook一起用的。(可关闭)
Network DDE DSDM -同上 (可关闭)
Network Location Awareness-如有网络共享或ICS/ICF可能需要。(服务器端) (可关闭)
NT LM Security support provider-telnet 服务用的。(可关闭)
NVIDIA Driver Helper service -nvidia 显卡帮助。(可关闭)
PDEngine - perfectdisk 引擎
PDScheduler -perfectdisk 计划服务
PerFORMance logs and alerts-记录机器运行状况而且定时写入日志或发警告,内容可能过于专业,所以自己决定。
Plug and Play- 自动查测新装硬件,即插即用。
Portable media serial number-绝对无用。 (可关闭)
Print Spooler -打印机用的。 (无打印机可关闭)
Protected Storage-储存本地密码和网上服务密码的服务,包括填表时的"自动完成"功能。
QoS RSVP -据说是降低网速20%……(可关闭)
Remote access auto connection manager-宽带/网络共享。
Remote desktop help session manager-远程帮助服务,占用4兆内存。 (可关闭)
Remote Procedure Call (RPC) -系统核心服务。
Remote Procedure Call LOCATOR-这个倒没什么用,管理 RPC 数据库服务,占用1兆内存。 (可关闭)
remote registry -远程注册表运行/修改。微软的漏洞……(可关闭)
removable storage -一般情况下不用,磁带备份用的。 (可关闭)
routing and remote access-不知者关,我也不知。 (可关闭)
secondary logon-给与administrator 以外的用户分配指定操作权.(可关闭)
security accounts manager-像 Protected Storage, IIS Admin 才需要。
server -局域网文件/打印共享需要的。 (不打印者可关闭)
shell hardware detection-给有些配置自动启动,像内存棒,和有些cd驱动等
smart card -占1.4兆内存呢(可关闭)
smart card helper -关。(可关闭)
SSDP Discovery service-没有什么硬件利用这个服务。(可关闭)
system event notification-记录用户登录/注销/重起/关机信息。(可关闭)
system restore service -系统还原服务,吃资源和内存的怪兽。虽然有时用到,自己决定。 (可关闭)
task scheduler-windows 计划服务。(可关闭)
TCP/IP NetBIOS helper-如果你的网络不用Netbios 或WINS的话。(可关闭)
Telephony - 拨号服务,如果你的宽带不用拨号,那么关了它。
telnet -还是微软的漏洞。这根dos中的telnet命令没关系。2兆内存。(可关闭)
terminal services-实现远程登录本地电脑,快速用户切换和远程桌面功能需要,不用这些功能就关了吧。(可关闭)
themes -XP的主题。关闭后是XP的经典风格。(可关闭)
uninterruptible power supply-停电保护设备用的。(可关闭)
universal plug and play device host-同SSDP Discovery Service。(可关闭)
upload manager-用来实现服务器和客户端输送文件的服务,简单文件传输不需要这个。(可关闭)
volume shadow copy-同MS Software Shadow Copy Provider,无用。(可关闭)
webclient-可能和以后的.net技术有联系。(可关闭)
Windows Audio - 控制着你听到的声音。(喜欢无声者可关闭)
Windows Installer -windows的MSI安装服务。(建议设成手动)
windows image acquisition (WIA) -有些数码相机和扫描器用的,觉得没用。(可关闭)
Windows Management Instrumentation - 重要的服务,关了会出现奇怪的问题
posted @
2007-12-08 00:20 心。 阅读(3523) |
评论 (0) |
编辑 收藏
Thread.currentThread().getContextClassLoader().getResource("")
Test.class.getClassLoader().getResource("")
ClassLoader.getSystemResource("")
Test.class.getResource("")
Test.class.getResource("/")
new File("/").getAbsolutePath()
System.getProperty("user.dir")
关于Classloader详见http://www.blogjava.net/lengxinCEO/archive/2007/12/07/166055.html
posted @
2007-12-07 15:25 心。 阅读(1270) |
评论 (0) |
编辑 收藏
当JVM(Java虚拟机)启动时,会形成由三个类加载器组成的初始类加载器层次结构:
bootstrap classloader
|
extension classloader
|
system classloader
bootstrap classloader -引导(也称为原始)类加载器,它负责加载Java的核心类。在Sun的JVM中,在执行java的命令中使用-Xbootclasspath选项或使用 - D选项指定sun.boot.class.path系统属性值可以指定附加的类。这个加载器的是非常特殊的,它实际上不是 java.lang.ClassLoader的子类,而是由JVM自身实现的。大家可以通过执行以下代码来获得bootstrap classloader加载了那些核心类库:
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
for (int i = 0; i < urls.length; i++) {
System.out.println(urls[i].toExternalForm());
}
在我的计算机上的结果为:
文件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/dom.jar
文件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/sax.jar
文件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xalan-2.3.1.jar
文件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xercesImpl-2.0.0.jar
文件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xml-apis.jar
文件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xsltc.jar
文件:/C:/j2sdk1.4.1_01/jre/lib/rt.jar
文件:/C:/j2sdk1.4.1_01/jre/lib/i18n.jar
文件:/C:/j2sdk1.4.1_01/jre/lib/sunrsasign.jar
文件:/C:/j2sdk1.4.1_01/jre/lib/jsse.jar
文件:/C:/j2sdk1.4.1_01/jre/lib/jce.jar
文件:/C:/j2sdk1.4.1_01/jre/lib/charsets.jar
文件:/C:/j2sdk1.4.1_01/jre/classes
这时大家知道了为什么我们不需要在系统属性CLASSPATH中指定这些类库了吧,因为JVM在启动的时候就自动加载它们了。
extension classloader -扩展类加载器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系统属性指定的)中JAR的类包。这为引入除Java核心类以外的新功能提供了一个标准机制。因为默认的扩展目录对所有从同一个JRE中启动的JVM都是通用的,所以放入这个目录的 JAR类包对所有的JVM和system classloader都是可见的。在这个实例上调用方法getParent()总是返回空值null,因为引导加载器bootstrap classloader不是一个真正的ClassLoader实例。所以当大家执行以下代码时:
System.out.println(System.getProperty("java.ext.dirs"));
ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent();
System.out.println("the parent of extension classloader : "+extensionClassloader.getParent());
结果为:
C:\j2sdk1.4.1_01\jre\lib\ext
the parent of extension classloader : null
extension classloader是system classloader的parent,而bootstrap classloader是extension classloader的parent,但它不是一个实际的classloader,所以为null。
system classloader -系统(也称为应用)类加载器,它负责在JVM被启动时,加载来自在命令java中的-classpath或者java.class.path系统属性或者 CLASSPATH*作系统属性所指定的JAR类包和类路径。总能通过静态方法ClassLoader.getSystemClassLoader()找到该类加载器。如果没有特别指定,则用户自定义的任何类加载器都将该类加载器作为它的父加载器。执行以下代码即可获得:
System.out.println(System.getProperty("java.class.path"));
输出结果则为用户在系统属性里面设置的CLASSPATH。
classloader 加载类用的是全盘负责委托机制。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入;委托机制则是先让parent(父)类加载器 (而不是super,它与parent classloader类不是继承关系)寻找,只有在parent找不到的时候才从自己的类路径中去寻找。此外类加载还采用了cache机制,也就是如果 cache中保存了这个Class就直接返回它,如果没有才从文件中读取和转换成Class,并存入cache,这就是为什么我们修改了Class但是必须重新启动JVM才能生效的原因。
每个ClassLoader加载Class的过程是:
1.检测此Class是否载入过(即在cache中是否有此Class),如果有到8,如果没有到2
2.如果parent classloader不存在(没有parent,那parent一定是bootstrap classloader了),到4
3.请求parent classloader载入,如果成功到8,不成功到5
4.请求jvm从bootstrap classloader中载入,如果成功到8
5.寻找Class文件(从与此classloader相关的类路径中寻找)。如果找不到则到7.
6.从文件中载入Class,到8.
7.抛出ClassNotFoundException.
8.返回Class.
其中5.6步我们可以通过覆盖ClassLoader的findClass方法来实现自己的载入策略。甚至覆盖loadClass方法来实现自己的载入过程。
类加载器的顺序是:
先是bootstrap classloader,然后是extension classloader,最后才是system classloader。大家会发现加载的Class越是重要的越在靠前面。这样做的原因是出于安全性的考虑,试想如果system classloader“亲自”加载了一个具有破坏性的“java.lang.System”类的后果吧。这种委托机制保证了用户即使具有一个这样的类,也把它加入到了类路径中,但是它永远不会被载入,因为这个类总是由bootstrap classloader来加载的。大家可以执行一下以下的代码:
System.out.println(System.class.getClassLoader());
将会看到结果是null,这就表明java.lang.System是由bootstrap classloader加载的,因为bootstrap classloader不是一个真正的ClassLoader实例,而是由JVM实现的,正如前面已经说过的。
下面就让我们来看看JVM是如何来为我们来建立类加载器的结构的:
sun.misc.Launcher,顾名思义,当你执行java命令的时候,JVM会先使用bootstrap classloader载入并初始化一个Launcher,执行下来代码:
System.out.println("the Launcher's classloader is "+sun.misc.Launcher.getLauncher().getClass().getClassLoader());
结果为:
the Launcher's classloader is null (因为是用bootstrap classloader加载,所以class loader为null)
Launcher 会根据系统和命令设定初始化好class loader结构,JVM就用它来获得extension classloader和system classloader,并载入所有的需要载入的Class,最后执行java命令指定的带有静态的main方法的Class。extension classloader实际上是sun.misc.Launcher$ExtClassLoader类的一个实例,system classloader实际上是sun.misc.Launcher$AppClassLoader类的一个实例。并且都是 java.net.URLClassLoader的子类。
让我们来看看Launcher初试化的过程的部分代码。
Launcher的部分代码:
public class Launcher {
public Launcher() {
ExtClassLoader extclassloader;
try {
//初始化extension classloader
extclassloader = ExtClassLoader.getExtClassLoader();
} catch(IOException ioexception) {
throw new InternalError("Could not create extension class loader");
}
try {
//初始化system classloader,parent是extension classloader
loader = AppClassLoader.getAppClassLoader(extclassloader);
} catch(IOException ioexception1) {
throw new InternalError("Could not create application class loader");
}
//将system classloader设置成当前线程的context classloader(将在后面加以介绍)
Thread.currentThread().setContextClassLoader(loader);
......
}
public ClassLoader getClassLoader() {
//返回system classloader
return loader;
}
}
extension classloader的部分代码:
static class Launcher$ExtClassLoader extends URLClassLoader {
public static Launcher$ExtClassLoader getExtClassLoader()
throws IOException
{
File afile[] = getExtDirs();
return (Launcher$ExtClassLoader)AccessController.doPrivileged(new Launcher$1(afile));
}
private static File[] getExtDirs() {
//获得系统属性“java.ext.dirs”
String s = System.getProperty("java.ext.dirs");
File afile[];
if(s != null) {
StringTokenizer stringtokenizer = new StringTokenizer(s, File.pathSeparator);
int i = stringtokenizer.countTokens();
afile = new File;
for(int j = 0; j < i; j++)
afile[j] = new File(stringtokenizer.nextToken());
} else {
afile = new File[0];
}
return afile;
}
}
system classloader的部分代码:
static class Launcher$AppClassLoader extends URLClassLoader
{
public static ClassLoader getAppClassLoader(ClassLoader classloader)
throws IOException
{
//获得系统属性“java.class.path”
String s = System.getProperty("java.class.path");
File afile[] = s != null ? Launcher.access$200(s) : new File[0];
return (Launcher$AppClassLoader)AccessController.doPrivileged(new Launcher$2(s, afile, classloader));
}
}
看了源代码大家就清楚了吧,extension classloader是使用系统属性“java.ext.dirs”设置类搜索路径的,并且没有parent。system classloader是使用系统属性“java.class.path”设置类搜索路径的,并且有一个parent classloader。Launcher初始化extension classloader,system classloader,并将system classloader设置成为context classloader,但是仅仅返回system classloader给JVM。
这里怎么又出来一个context classloader呢?它有什么用呢?我们在建立一个线程Thread的时候,可以为这个线程通过setContextClassLoader方法来指定一个合适的classloader作为这个线程的context classloader,当此线程运行的时候,我们可以通过getContextClassLoader方法来获得此context classloader,就可以用它来载入我们所需要的Class。默认的是system classloader。利用这个特性,我们可以“打破”classloader委托机制了,父classloader可以获得当前线程的context classloader,而这个context classloader可以是它的子classloader或者其他的classloader,那么父classloader就可以从其获得所需的 Class,这就打破了只能向父classloader请求的限制了。这个机制可以满足当我们的classpath是在运行时才确定,并由定制的 classloader加载的时候,由system classloader(即在jvm classpath中)加载的class可以通过context classloader获得定制的classloader并加载入特定的class(通常是抽象类和接口,定制的classloader中是其实现),例如web应用中的servlet就是用这种机制加载的.
好了,现在我们了解了classloader的结构和工作原理,那么我们如何实现在运行时的动态载入和更新呢?只要我们能够动态改变类搜索路径和清除 classloader的cache中已经载入的Class就行了,有两个方案,一是我们继承一个classloader,覆盖loadclass方法,动态的寻找Class文件并使用defineClass方法来;另一个则非常简单实用,只要重新使用一个新的类搜索路径来new一个 classloader就行了,这样即更新了类搜索路径以便来载入新的Class,也重新生成了一个空白的cache(当然,类搜索路径不一定必须更改)。噢,太好了,我们几乎不用做什么工作,java.netURLClassLoader正是一个符合我们要求的classloader!我们可以直接使用或者继承它就可以了!
这是j2se1.4 API的doc中URLClassLoader的两个构造器的描述:
URLClassLoader(URL[] urls)
Constructs a new URLClassLoader for the specified URLs using the default delegation parent ClassLoader.
URLClassLoader(URL[] urls, ClassLoader parent)
Constructs a new URLClassLoader for the given URLs.
其中URL[] urls就是我们要设置的类搜索路径,parent就是这个classloader的parent classloader,默认的是system classloader。
好,现在我们能够动态的载入Class了,这样我们就可以利用newInstance方法来获得一个Object。但我们如何将此Object造型呢?可以将此Object造型成它本身的Class吗?
首先让我们来分析一下java源文件的编译,运行吧!javac命令是调用“JAVA_HOME/lib/tools.jar”中的“com.sun.tools.javac.Main”的compile方法来编译:
public static int compile(String as[]);
public static int compile(String as[], PrintWriter printwriter);
返回0表示编译成功,字符串数组as则是我们用javac命令编译时的参数,以空格划分。例如:
javac -classpath c:\foo\bar.jar;. -d c:\ c:\Some.java
则字符串数组as为{"-classpath","c:\\foo\\bar.jar;.","-d","c:\\","c:\Some.java"},如果带有PrintWriter参数,则会把编译信息出到这个指定的printWriter中。默认的输出是 System.err。
其中 Main是由JVM使用Launcher初始化的system classloader载入的,根据全盘负责原则,编译器在解析这个java源文件时所发现的它所依赖和引用的所有Class也将由system classloader载入,如果system classloader不能载入某个Class时,编译器将抛出一个“cannot resolve symbol”错误。
所以首先编译就通不过,也就是编译器无法编译一个引用了不在CLASSPATH中的未知Class的java源文件,而由于拼写错误或者没有把所需类库放到CLASSPATH中,大家一定经常看到这个“cannot resolve symbol”这个编译错误吧!
其次,就是我们把这个Class放到编译路径中,成功的进行了编译,然后在运行的时候不把它放入到CLASSPATH中而利用我们自己的 classloader来动态载入这个Class,这时候也会出现“java.lang.NoClassDefFoundError”的违例,为什么呢?
我们再来分析一下,首先调用这个造型语句的可执行的Class一定是由JVM使用Launcher初始化的system classloader载入的,根据全盘负责原则,当我们进行造型的时候,JVM也会使用system classloader来尝试载入这个Class来对实例进行造型,自然在system classloader寻找不到这个Class时就会抛出“java.lang.NoClassDefFoundError”的违例。
OK,现在让我们来总结一下,java文件的编译和Class的载入执行,都是使用Launcher初始化的system classloader作为类载入器的,我们无法动态的改变system classloader,更无法让JVM使用我们自己的classloader来替换system classloader,根据全盘负责原则,就限制了编译和运行时,我们无法直接显式的使用一个system classloader寻找不到的Class,即我们只能使用Java核心类库,扩展类库和CLASSPATH中的类库中的Class。
还不死心!再尝试一下这种情况,我们把这个Class也放入到CLASSPATH中,让system classloader能够识别和载入。然后我们通过自己的classloader来从指定的class文件中载入这个Class(不能够委托 parent载入,因为这样会被system classloader从CLASSPATH中将其载入),然后实例化一个Object,并造型成这个Class,这样JVM也识别这个Class(因为 system classloader能够定位和载入这个Class从CLASSPATH中),载入的也不是CLASSPATH中的这个Class,而是从 CLASSPATH外动态载入的,这样总行了吧!十分不幸的是,这时会出现“java.lang.ClassCastException”违例。
为什么呢?我们也来分析一下,不错,我们虽然从CLASSPATH外使用我们自己的classloader动态载入了这个Class,但将它的实例造型的时候是JVM会使用system classloader来再次载入这个Class,并尝试将使用我们的自己的classloader载入的Class的一个实例造型为system classloader载入的这个Class(另外的一个)。大家发现什么问题了吗?也就是我们尝试将从一个classloader载入的Class的一个实例造型为另外一个classloader载入的Class,虽然这两个Class的名字一样,甚至是从同一个class文件中载入。但不幸的是JVM 却认为这个两个Class是不同的,即JVM认为不同的classloader载入的相同的名字的Class(即使是从同一个class文件中载入的)是不同的!这样做的原因我想大概也是主要出于安全性考虑,这样就保证所有的核心Java类都是system classloader载入的,我们无法用自己的classloader载入的相同名字的Class的实例来替换它们的实例。
看到这里,聪明的读者一定想到了该如何动态载入我们的Class,实例化,造型并调用了吧!
那就是利用面向对象的基本特性之一的多形性。我们把我们动态载入的Class的实例造型成它的一个system classloader所能识别的父类就行了!这是为什么呢?我们还是要再来分析一次。当我们用我们自己的classloader来动态载入这我们只要把这个Class的时候,发现它有一个父类Class,在载入它之前JVM先会载入这个父类Class,这个父类Class是system classloader所能识别的,根据委托机制,它将由system classloader载入,然后我们的classloader再载入这个Class,创建一个实例,造型为这个父类Class,注意了,造型成这个父类 Class的时候(也就是上溯)是面向对象的java语言所允许的并且JVM也支持的,JVM就使用system classloader再次载入这个父类Class,然后将此实例造型为这个父类Class。大家可以从这个过程发现这个父类Class都是由 system classloader载入的,也就是同一个class loader载入的同一个Class,所以造型的时候不会出现任何异常。而根据多形性,调用这个父类的方法时,真正执行的是这个Class(非父类 Class)的覆盖了父类方法的方法。这些方法中也可以引用system classloader不能识别的Class,因为根据全盘负责原则,只要载入这个Class的classloader即我们自己定义的 classloader能够定位和载入这些Class就行了。
这样我们就可以事先定义好一组接口或者基类并放入CLASSPATH中,然后在执行的时候动态的载入实现或者继承了这些接口或基类的子类。还不明白吗?让我们来想一想Servlet吧,web application server能够载入任何继承了Servlet的Class并正确的执行它们,不管它实际的Class是什么,就是都把它们实例化成为一个Servlet Class,然后执行Servlet的init,doPost,doGet和destroy等方法的,而不管这个Servlet是从web- inf/lib和web-inf/classes下由system classloader的子classloader(即定制的classloader)动态载入。说了这么多希望大家都明白了。在applet,ejb等容器中,都是采用了这种机制.
对于以上各种情况,希望大家实际编写一些example来实验一下。
最后我再说点别的, classloader虽然称为类加载器,但并不意味着只能用来加载Class,我们还可以利用它也获得图片,音频文件等资源的URL,当然,这些资源必须在CLASSPATH中的jar类库中或目录下。我们来看API的doc中关于ClassLoader的两个寻找资源和Class的方法描述吧:
public URL getResource(String name)
用指定的名字来查找资源,一个资源是一些能够被class代码访问的在某种程度上依赖于代码位置的数据(图片,音频,文本等等)。
一个资源的名字是以'/'号分隔确定资源的路径名的。
这个方法将先请求parent classloader搜索资源,如果没有parent,则会在内置在虚拟机中的classloader(即bootstrap classloader)的路径中搜索。如果失败,这个方法将调用findResource(String)来寻找资源。
public static URL getSystemResource(String name)
从用来载入类的搜索路径中查找一个指定名字的资源。这个方法使用system class loader来定位资源。即相当于ClassLoader.getSystemClassLoader().getResource(name)。
例如:
System.out.println(ClassLoader.getSystemResource("java/lang/String.class"));
的结果为:
jar:文件:/C:/j2sdk1.4.1_01/jre/lib/rt.jar!/java/lang/String.class
表明String.class文件在rt.jar的java/lang目录中。
因此我们可以将图片等资源随同Class一同打包到jar类库中(当然,也可单独打包这些资源)并添加它们到class loader的搜索路径中,我们就可以无需关心这些资源的具体位置,让class loader来帮我们寻找了!
posted @
2007-12-07 15:23 心。 阅读(1536) |
评论 (0) |
编辑 收藏
<script language="vbscript">
/*利用VBScript构建asc吗和字符串的互转函数*/
Function str2asc(strstr)
str2asc = hex(asc(strstr))
End Function
Function asc2str(ascasc)
asc2str = chr(ascasc)
End Function
</script>
<script language="javascript">
/*这里开始时UrlEncode和UrlDecode函数*/
function UrlEncode(str){
var ret="";
var strSpecial="!"#$%&'()*+,/:;<=>?[]^`{|}~%";
for(var i=0;i<str.length;i++){
var chr = str.charAt(i);
var c=str2asc(chr);
if(parseInt("0x"+c) > 0x7f){
ret+="%"+c.slice(0,2)+"%"+c.slice(-2);
}else{
if(chr==" "){
ret+="+";
}else if(strSpecial.indexOf(chr)!=-1){
ret+="%"+c.toString(16);
}else{
ret+=chr;
}
}
}
return ret;
}
function UrlDecode(str){
var ret="";
for(var i=0;i<str.length;i++){
var chr = str.charAt(i);
if(chr == "+"){
ret+=" ";
}else if(chr=="%"){
var asc = str.substring(i+1,i+3);
if(parseInt("0x"+asc)>0x7f){
ret+=asc2str(parseInt("0x"+asc+str.substring(i+4,i+6)));
i+=5;
}else{
ret+=asc2str(parseInt("0x"+asc));
i+=2;
}
}else{
ret+= chr;
}
}
return ret;
}
</script>
posted @
2007-12-04 13:25 心。 阅读(1850) |
评论 (0) |
编辑 收藏
quartz报错:
Caused by: java.lang.NoSuchMethodError: org.apache.commons.collections.SetUtils.orderedSet(Ljava/util/Set;)Ljava/util/Set;
的原因是由于使用的commons-collections.jar版本太低导致的要使用3.*的才行。
对于使用MyEclipse的,如果导入了commons-collections.jar 3.*的包还不行,而且没有找到其他的包的话很可能是MyEclipse自带的Liberary中包括了版本低的包而你导入了这个lib。
比如MyEclipse的Hibernate的Lib中包括commons-collections.jar但是版本是2.*。
Window->Preferences->Myeclipse->Project Capabilities->Hibernate
从lib中删除此包即可。
posted @
2007-12-03 11:45 心。 阅读(10517) |
评论 (6) |
编辑 收藏
window.open()方法中,窗口控制参数的详细定义:
alwaysLowered
innerWidth
screenY
alwaysRaised
left
scrollbars
channelmode
location
status
dependent
menubar
titlebar
directories
outerWidth
toolbar
fullscreen
outerHeight
top
height
menubar
width
hotkeys
resizable
z-lock
innerHeight
screenX
--------------------------------------------------------------------------------------------------------------------
alwaysLowered
Internet Explorer:不支持
Navigator:版本 4+
指定窗口总是保留在堆栈的最下面。换言之,不管新窗口是否激活,总是其他窗口下。
window.open("alwayslowered.html", "_blank", "alwaysLowered");
--------------------------------------------------------------------------------------------------------------------
alwaysRaised
Internet Explorer:不支持
Navigator:版本 4+
指定窗口总是保留在堆栈的最上面。换言之,不管新窗口是否激活,总是其他窗口上。
window.open("alwaysraised.html", "_blank", "alwaysRaised");
--------------------------------------------------------------------------------------------------------------------
channelmode
Internet Explorer:版本 4+
Navigator:不支持
指定是否按照剧场模式显示窗口,以及是否显示频道区。
window.open("channelmode.html", "_blank", "channelmode");
--------------------------------------------------------------------------------------------------------------------
dependent
Internet Explorer:不支持
Navigator:版本 4+
定义是否窗口成为当前打开窗口的依赖子窗口。依赖窗口就是当它的父窗口关闭时,它也随即关闭。在windows平台上,一个依赖窗口不会在任务栏上显示。
window.open("dependent.html", "_blank", "dependent");
--------------------------------------------------------------------------------------------------------------------
directories
Internet Explorer:所有版本
Navigator:所有版本
指定是否显示目录按钮(比如众所周知的"What's Cool" and "What's New" 按钮)。Internet Explorer将这些目录按钮引用为链接工具栏,Navigator(版本4和以上)称之为个人工具栏。
window.open("directories.html", "_blank", "directories");
--------------------------------------------------------------------------------------------------------------------
fullscreen
Internet Explorer:版本 4+
Navigator:不支持
定义是否按照全屏方式打开浏览器。请小心使用全屏模式,因为在这种模式下,浏览器的标题栏和菜单都被隐藏,所有你应该提供一个按钮或者其他可视的线索来帮助用户关闭这个窗口。当然,使用热键ALT+F4也能关闭窗口。
window.open("fullscreen.html", "_blank", "fullscreen");
--------------------------------------------------------------------------------------------------------------------
height
Internet Explorer:所有版本
Navigator:所有版本
以象素pixel为单位定义窗口文档显示区域的高度,最小数值是100。如果仅仅定义高度,Internet Explorer使用给定的高度和默认的宽度。对于Navigator,如果不同时指定width或者innerWidth,那么就将忽略这个属性。
window.open("height.html", "_blank", "height=200,width=300");
--------------------------------------------------------------------------------------------------------------------
hotkeys
Internet Explorer:不支持
Navigator:版本 4+
如果没有定义(或者为0),那么就屏蔽了没有菜单条的新窗口的大部分热键。但是安全以及退出热键仍然保留。
window.open("hotkeys.html", "_blank", "hotkeys=0,menubar=0");
--------------------------------------------------------------------------------------------------------------------
innerHeight
Internet Explorer:不支持
Navigator:版本 4+
以象素pixel为单位定义窗口文档显示区域的高度,最小数值是100。在Navigator版本4中,这个特征替换height,为得是保持向后兼容。对于Navigator,如果不同时指定width或者innerWidth,那么就将忽略这个属性。
window.open("innerheight.html", "_blank", "innerHeight=200,innerWidth=300");
--------------------------------------------------------------------------------------------------------------------
innerWidth
Internet Explorer:不支持
Navigator:版本 4+
以象素pixel为单位定义窗口文档显示区域的宽度,最小数值是100。在Navigator版本4中,这个特征替换width,为得是保持向后兼容。对于Navigator,如果不同时指定height或者innerHeight,那么就将忽略这个属性。
window.open("innerwidth.html", "_blank", "innerHeight=200,innerWidth=300");
--------------------------------------------------------------------------------------------------------------------
left
Internet Explorer:版本 4+
Navigator:不支持
以象素为单位定义窗口的X左标。
window.open("left.html", "_blank", "left=20");
--------------------------------------------------------------------------------------------------------------------
location
Internet Explorer:所有版本
Navigator:所有版本
定义是否显示浏览器中供地址URL输入的文本域。
window.open("location.html", "_blank", "location");
--------------------------------------------------------------------------------------------------------------------
menubar
Internet Explorer:所有版本
Navigator:所有版本
定义是否显示菜单条(菜单条位于窗口顶部,包括“文件”和“编辑”等)。
window.open("menubar.html", "_blank", "menubar");
--------------------------------------------------------------------------------------------------------------------
outerHeight
Internet Explorer:不支持
Navigator:版本 4+
以象素为单位定义窗口(它的外部边界)的总高度,最小数值比100多一些,因为窗口内容区域的高度必须至少是100。如果没有同时定义outerWidth,Navigator将忽视这个特征。
window.open("outerheight.html", "_blank", "outerHeight=200,outerWidth=300");
--------------------------------------------------------------------------------------------------------------------
outerWidth
Internet Explorer:不支持
Navigator:版本 4+
以象素为单位定义窗口(它的外部边界)的总宽度,最小数值比100多一些,因为窗口内容区域的宽度必须至少是100。如果没有同时定义outerHeight,Navigator将忽视这个特征。
window.open("outerwidth.html", "_blank", "outerHeight=200,outerWidth=300");
--------------------------------------------------------------------------------------------------------------------
resizable
Internet Explorer:所有版本
Navigator:所有版本
定义是否窗口可以通过它的边界进行大小缩放控制。依赖于平台不同,用户也许还有其他改变窗口大小的方法。
window.open("resizable.html", "_blank", "resizable");
--------------------------------------------------------------------------------------------------------------------
screenX
Internet Explorer:不支持
Navigator:版本 4+
以象素为单位定义窗口的X坐标。
window.open("screenx.html", "_blank", "screenX=20");
--------------------------------------------------------------------------------------------------------------------
screenY
Internet Explorer:不支持
Navigator:版本 4+
以象素为单位定义窗口的Y坐标。
window.open("screeny.html", "_blank", "screenY=20");
--------------------------------------------------------------------------------------------------------------------
scrollbars
Internet Explorer:所有版本
Navigator:所有版本
定义是否激活水平和垂直滚动条。
window.open("scrollbars.html", "_blank", "scrollbars");
--------------------------------------------------------------------------------------------------------------------
status
Internet Explorer:所有版本
Navigator:所有版本
定义是否在窗口的下部添加状态栏。
window.open("status.html", "_blank", "status");
--------------------------------------------------------------------------------------------------------------------
titlebar
Internet Explorer:Version 5+
Navigator:版本 4+
定义是否显示窗口的标题栏。在Internet Explorer中,除非调用者是一个HTML应用程序或者一个可信任的对话框,那么这个特征是被屏蔽的。
window.open("titlebar.html", "_blank", "titlebar=0");
--------------------------------------------------------------------------------------------------------------------
toolbar
Internet Explorer:所有版本
Navigator:所有版本
定义是否显示浏览器的工具栏(位于窗口的上部,包括“后退”和“向前”)。
window.open("toolbar.html", "_blank", "toolbar");
--------------------------------------------------------------------------------------------------------------------
top
Internet Explorer:版本 4+
Navigator:不支持
以象素为单位定义窗口的纵坐标。
window.open("top.html", "_blank", "top=20");
--------------------------------------------------------------------------------------------------------------------
width
Internet Explorer:所有版本
Navigator:所有版本
以象素pixel为单位定义窗口文档显示区域的宽度,最小数值是100。如果仅仅定义宽度,Internet Explorer使用给定的宽度和默认的高度。对于Navigator,如果不同时指定height或者innerHeight,那么就将忽略这个属性。
window.open("width.html", "_blank", "height=200,width=300");
--------------------------------------------------------------------------------------------------------------------
z-lock
Internet Explorer:不支持
Navigator:版本 4+
定义窗口激活时不在堆栈中浮起,就是说,新窗口当被激活时并不能位于其他窗口之上。
window.open("zlock.html", "_blank", "z-lock");
--------------------------------------------------------------------------------------------------------------------
posted @
2007-11-29 15:25 心。 阅读(628) |
评论 (0) |
编辑 收藏
一直做jdk1.5的项目,突遇一个老项目jdk1.4的,导致tomcat启动报java.lang.reflect.InvocationTargetException
解决:eclipse中
Windows-->Preferences在弹出的窗口中选择
java-->compiler在右上方把Compile compliance level改成1.4
posted @
2007-10-24 12:31 心。 阅读(369) |
评论 (0) |
编辑 收藏
且,windows installer服务不能启动
解决:
在命令行提示符下,键入msiexec /unregister
然后再键入msiexec /regserver
posted @
2007-10-23 16:34 心。 阅读(555) |
评论 (0) |
编辑 收藏
我用的installAnyWhere是6.1版本的,有关installAnyWhere的安装、破解,网上有很多,我是用自己写的cracker破解的,如果不注册,生成的安装包每次都会提示“该安装包是用未注册的installAnyWhere创建的”,非常不爽。所以,最好破解了再用。
网上有关installAnyWhere的使用,自己看了很久,都觉得不太明白,所以,自己摸索的几天,下面,就把我自己的使用的一些细节介绍给大家,如果你觉得对你有所帮助,那就是我最大的荣幸。
使用步骤:
一、修改本地化文件
installAnyWhere本身支持多种语言的本地化,包括中文。但缺省自带的简体中文文件中,几乎都是繁体中文,因此,如果你的安装包要支持简体中文安装的话,最好先把简体中文的本地化文件“简化”一下。
简化方法如下:
到installAnyWhere安装目录的\resource\i18nresources目录下,找到custom_zh_CN文件,把其中的中文内容删除后重新输入简体的汉字,记得输入法要用简体中文的。
二、创建新的安装工程
打开installAnyWhere后,如下图所示:
选择“Create New Project”,选择“Basic Project Template”模版,选择“Save as”按钮,弹出保存新建工程的目录以及名称,名称的后缀为.iap_xml。
点击“Next”进入工程设置界面,也可以直接点击“Advanced Designer”进入高级设计界面。如果想对工程作一些高级的设置,就选择高级设计界面。
高级设计界面如下图所示:
从该界面中可以看到,有很多项设置,一级导航包括:Project、Installer UI、Organization、Files、Pre-Install、Post-Install、Pre-Uninstall、Post-Uninstall、Build。下面分别逐个介绍。
三、工程设置
进入高级设计界面的Projiect界面,其中包括了Info、Description、File Setting、Platforms、Locales、Rules、Config、Java。
1、Info设置
Info中主要设置工程的一些信息,包括安装的title、名称、产品名称、工程的存放位置、构建后的安装包存放位置等信息,如下图所示:
如无特殊情况,一般使用缺省设置即可。
2、Description设置
Description界面中设置安装包的产品可能写入注册表中的一些信息,包括:产品名称、ID、版本、以及支持、提供商等信息,如下图所示:
在该界面中,你可以详细的填写相关的信息,包括产品介绍等。
3、File Settings
该界面中主要设置安装过程中,被安装的文件的时间如何处理,你可以选择保留文件本身的时间,也可以设置为安装时的时间,还可以设置成指定的时间。该界面中还可以设置当文件已经存在时,如何提示或操作。一般,使用缺省设置即可。
File Settings的操作界面如下:
4、Platforms
我用的6.1版本的InstallAnywhere,支持三种操作系统平台:Mac OS X、Windows和UNIX。因此,Platforms设置界面中,你可以分别对这三种操作平台的缺省安装路径和缺省快捷方式进行设置。Windows平台的设置界面如下:
一般使用缺省设置即可。
5、Locales
Locales项设置安装包所支持的安装界面的语言。缺省是英文安装语言。只有选择了除英文之外的至少一种其他语言,安装包才会在安装开始时显示选择安装语言的界面。一般选择支持简体中文即可。操作界面如下:
在installAnyWhere 的其他的版本手册中都提及需要注意中文的问题,我在前面已经有说明。如果大家在使用中遇到中文显示有问题的话(尤其是在非windows操作平台上),也很简单只要将”*locales”的文件夹中” custom_zh_CN”文件中的中文用UNICODE码代替就OK了,JDK\BIN中提过了相关的工具native2ascii.exe运行后替换原先的custom_zh_CN就OK了。
6、Rules
Rules项中可以配置多种安装规则,如安装前检查安装路径属性、安装平台或者其他自定义的规则。一般,我们会用到检查安装平台,如是否是指定的操作系统,如下图所示:
7、Config
“Config”界面“installer debug output”中有俩个文本框,大家可以在里面填上“console”,这样大家在安装文件生成后,调试安装时可以通过控制台来查看相关的提示信息。正是发布的话,清空即可。其他几项都可以使用缺省设置即可。
8、Java
如果需要安装VM的话,就需要注意VM的安装路径,而设置VM的安装路径,就在该界面中:
一般用缺省设置即可
四、安装界面
主要设置安装的界面相关信息,一般选择swing模式即可。该界面中,特别需要注意的就是图片,如果没有特别需要,最好使用默认的,否则,经常出现找不到图片的问题。如果需要的话,最好在InstallAnywhere的resources目录中建立图片文件夹,然后使用该路径。其他使用缺省设置即可。
五、组织
Organization界面下主要包含Install Set、Feathures、Components和Modules四个子界面,分别用来设置安装集合(如典型安装、最小化安装、自定义安装等)、特性(如公共组件、帮助文档、应用程序等)、组建(要安装内容的各个组成部分)、模块(其他需要合并的模块)。在配置安装集合时,指定哪些特性在某个安装类型时缺省选择被安装,而每个特性中具体包含哪些内容,是在组建中配置的。没有特殊需求的话,使用缺省设置即可。
六、文件
Files界面中,真正配置要安装的文件内容,也就是哪些内容要被添加到安装包里。缺省的操作界面如下图所示:
简单安装的话,只要把要安装的文件通过“Add Files”按钮添加近来即可,如下图所示:
添加文件后,效果图下图所示:
其他使用缺省设置即可。
七、预安装
Pre-Install界面比较重要,安装过程中的各种界面都在这里设置,如安装协议、安装路径、程序快捷、预安装摘要等。一般简单安装的话,使用缺省设置即可。缺省情况下,没有安装协议界面,如果需要的话,可以通过向导添加。
点击“Add Action”按钮打开选择action的界面,如下图所示:
切换到Panels界面,选择“Panel:License Agreement”条目,点击“Add”按钮,然后关闭选择action界面。这样就添加了安装协议的界面,如下图所示:
首先要选中刚刚添加的安装协议条目,通过中间的上下箭头移动安装协议条目到合适的位置,然后修改下面的Path,使其指定到你所使用的安装协议文件。目前只支持文本和htm俩中格式的协议文件。
八、安装后
Post-Install界面中配置安装完成后的操作,缺省会有俩个界面,一个是提示安装完成,另一个是重启操作系统,如下图所示:
如果安装完成后不需要重启操作系统,就选中“RestartWindows”,然后点击“Remove”按钮即可。
九、预卸载
Pre-Uninstall界面中设置卸载过程的交互界面和步骤,缺省有三个界面:卸载介绍、选择卸载类型、选择要卸载的feature,如下图所示:
其中的卸载类型与前面Organization中设置的install set对应,如install set中有多种安装类型,那卸载。也就有多种选择,否则就没必要选择卸载类型。卸载的feature也与organization中的feature对应,如果前面没有配置,这里也就没必要配置该panel。
十、卸载后
Post-Uninstall界面也很简单,主要就是一个卸载完成的提示界面。缺省会有restart windows的步骤,如果不需要重启操作系统,可以直接remove掉restart windows的action。
十一、构建
Build界面中,主要设置要构建的安装包的目标平台以及是否在安装包中包含VM,如下图所示:
如果运行安装程序的目标机器上已经安装有VM,就可以选择安装包中不包含VM,否则,就要包含VM,否则,安装包不能执行。需要注意的是选择VM的版本,如果你的程序本身也需要VM运行环境的话,而且需要的VM版本较高,那就要从网上下载合适版本的VM。
依照上面的步骤,可以构建出基本功能的安装包了。后面将介绍一些特殊功能的安装包的制作,如多语言安装环境下的多语言的安装协议等。
由于InstallAnywhere制作出的安装包本身是基于java的,因此,如果目标计算机上没有安装java运行环境的话,就必须在build安装包,选择包含VM,否则,安装包不能运行。
如果你打包的内容本身是基于java的程序,那程序本身运新就需要java运行环境,因此,可以在安装说明可以明确安装条件:必须安装java运行环境。
如果用InstalalAnywhere打包非java程序,那你的安装包最好包含VM,否则,就必须先安装java运新环境,才能运行安装包。
下面说说本地化的问题。
在用InstallAnywhere制作安装包的过程中,locale的设置界面中,允许你选择多种语言。locale中的选择,决定了你的安装包在启动安装时所提供的安装界面的语言选择。如果只选择了一种语言,那安装就不会出现选择安装语言的界面,只有选择了一种以上的语言,安装才会出现选择安装语言的界面。
英文是InstallAnywhere缺省的语言,因此,只要你在Locale中选择了非英文的语言,就会出现安装语言的选项界面。
如果安装包配置了多语言安装的支持,那在安装过程中,一般都希望对应的安装界面、信息都是索选的语言,如选择了中文的话,那安装过程中的信息希望都是中文的,如安装协议。也就是,如果选择中文安装的话,安装协议是中文的;如果选择英文安装的话,安装协议是英文的。这种情况,应该是大家都希望的。
具体操作步骤如下:
一、准备两种语言的安装协议文件:假设分别为license_en.txt和license_zh.txt
二、在工程的locale配置界面中选中简体中文
三、按照之前介绍的方法配置、构建工程,否则没有custom_zh_CN文件
四、打开安装工程目录下的custom_zh_CN文件,一般都在安装工程名+locale目录下,找到“LicenseAgrAction.*.resourceName=”项,修改配置为你的中文安装协议文件名:license_zh.txt,*号的内容与具体工程有关,是不同的代码
五、继续在custom_zh_CN文件中查找“LicenseAgrAction.*.resourcePath=”项,修改配置文license_zh.txt文件所在的绝对路径,如:d:\\test\\,要注意是路径
六、切换到InstallAnywhere高级设计界面,打开Files项,选中“User
Install Fould”,点击“Add
launcher”,这时会弹出对话框,询问你是否让InstallAnywhere自动搜索含有main方法的类,非java程序的话,可以选择取消。就会在文件树中添加“shortcut
destination fold”项,如下图所示:
选择中“shortcut destination fold”,点击“property”中的path项的下拉框,选择“DO NOT INSTALL”,如下图所示:
添加license_zh.txt文件到“DO NOT INSTALL”项中,并删除掉“Create LaunchAnywhere”,如下图所示:
七、构建工程即可。
这样,在安装时,选择中文的话,就会使用中文的安装协议。
缺省情况下,InstallAnywhere构建出的安装包是自解压的、可用于web方式安装的单文件的安装包,也就是,构建出的安装包可以自解压,可以嵌入网页通过网页来安装。通常,这种方式的安装包,基本可以满足我们的需要,把这种安装包直接刻录到光盘也可以进行发行,只是光盘中的内容比较单一,如过希望自己的发布光盘也像其安装光盘那样:里边包含很多文件,而这些文件本身就是要被安装的内容,但真正的内容又被隐藏在这些文件中,那该怎么办呢??
其实,只要选择InstallAnywhere的Build标签项中的Distribution中的“Build CD-ROM Installer”即可,如下图所示:
这样,就可以构建出可用于光盘刻录的发布内容了,这些内容一般存放在输出目录的CDROM_Installers目录下。缺省情况下,一个光盘的容量是650M,如果内容超过650M,InstallAnywhere会自动把内容分隔到其他disk的。假如内容有700M,那构建出的CD-ROM的disk1中可以包含650M的内容,而disk2中则包含其余的内容。在安装过程中,会自动提示你更换disk2。
每张disk的容量,可以单独设置,只要点击“Change Disk Space ans Name”按钮,就可以打开修改disk属性的界面,如下图所示:
其中的“Media Name”属性就是安装过程中提示你更换光盘的名称,而Mesia Size项中就是设置光盘容量大小的,切忌,其单位是byte。
在制作安装包的过程中,有时候我们也希望自己做的安装包稍微有点专业的感觉,比如安装时必须输入一个安装序列号什么的,这样,就给人的感觉不同了。InstallAnywhere提供了这样的功能,只要进行简单的配置,就可以很快制作出一个需要序列号的安装包了。具体的配置步骤如下:
一、按照先前的说明构建基本安装工程
二、在预安装配置界面中,添加一个action,选择Panel中的get serial number,通过上下箭头移动到合适的安装顺序
三、选中刚刚添加的“get serial number”panel,点击下面的Configure Serial Number按钮,打开序列号生成配置界面,如下图所示:
有下列几点需要特别说明:
1、序列号个数必须大于等于产品个数
2、固定的字符串可以是前缀也可以是后缀
3、种子随机数最长9位,可以手工输入,但最好使用自动生成的
4、记得选择把生成的序列号保存到文件,否则很麻烦
5、如果一个产品,选择生成多个序列号,这些序列号都可以用来进行安装
四、保存安装工程,就可以在指定的目录下生成了序列号文件
五、build工程,生成新的安装包
这样,新的安装包就必须输入安装序列号才能完成安装,否则,不能继续安装。
posted @
2007-09-18 10:36 心。 阅读(2460) |
评论 (0) |
编辑 收藏
1. How are you doing?(你好吗?)
2. I'm doing great.(我过得很好。)
3. What's up?(出什么事了/你在忙些什么/怎么了?)
4. Nothing special.(没什么特别的。)
5. Hi. Long time no see.(嗨,好久不见了。)
6. So far so good.(到目前为止,一切都好。)
7. Things couldn't be better.(一切顺利。)
8. How about yourself?(你自己呢?)
9. Today is a great day.(今天是个好日子。)
10. Are you making progress?(有进展吗?)
11. May I have your name, please?(请问尊姓大名?)
12. I've heard so much about you.(久仰大名。)
13. I hope you're enjoying your staying here.(希望你在这里过得愉快。)
14. Let's get together again.(改天再聚聚。)
15. That's a great idea!(好主意!)
16. Please say hello to your mother for me.(请代我向你母亲问好。)
17. I'm glad to have met you.(很高兴遇到你。)
18. Don't forget us.(别忘了我们。)
19. Keep in touch.(保持联系。)
20. I had a wonderful time here.(我在这里度过了难忘的时光。)
21. Have a nice weekend.(周末愉快。)
22. Same to you.(彼此彼此。)
23. Nice talking to you.(很高兴与你聊天。)
24. Take care of yourself.(自己当心/照顾好你自己。)
25. Thank you for everything.(谢谢你的多方关照/你为我所做的一切。)
26. Thank you all for coming.(谢谢光临。)
27. I appreciate your help.(我感谢你的帮助。)
28. You're always welcome.(别客气/不用谢)
29. Forget it.(算了吧)
30. It was my pleasure.(不用谢。)
31. I made a mistake.(我弄错了。)
32. I'm terribly sorry.(实在抱歉。)
33. I must apologize!(我必须道歉!)
34. I feel terrible.(我感觉糟透了。)
35. It's not your fault. (那不是你的错。)
36. Sorry to bother /have bothered you.(抱歉,打扰一下/打扰你了。)
37. What do you do?(你做什么工作?)
38. How do you like your new job?(你觉得你的新工作怎样?)
39. I like it a lot.(我很喜欢。)
40. I like reading and listening to music.(我喜欢阅读和欣赏音乐。)
41. What's wrong?(怎么回事?)
42. What happened?(发生什么事了?)
43. I hope nothing is wrong.(我希望一切顺利。)
44. I know how you feel.(我知道你的感受。)
45. Sorry to hear that.(听到这个消息我很难受。)
46. Come on, you can do that.(来吧,你能做到的。)
47. Use your head.(动动脑筋。)
48. You did a great job.(你赶得很好。)
49. That's very nice of you.(你真好。)
50. I'm very proud of you.(我为你感到自豪。)
51. I like your style.(我喜欢你的风格。)
52. I love you guys.(我爱你们。)
53. How do I look?(我看起来怎么样?)
54. You look great!(你看上去棒极了!)
55. That's fantastic!(那真是棒极了!)
56. That's really something.(那真是了不起!)
57. It's a pleasure working with you.(与您合作很愉快。)
58. Congratulations on you success.(祝贺你的成功。)
59. I'd like to propose a toast.(我提议干杯!)
60. Are you married or single?(你结婚了吗?)
61. I've been dying to see you.(我非常想见到你。)
62. I'm crazy about you.(我为你疯狂/痴迷/神魂颠倒。)
63. I love you with all my heart.(我全心全意爱你!)
64. You're everything to me.(你是我的一切!)
65. You're in love!(你恋爱了!)
66. I'm tired of working all day.(整日工作使我厌烦。)
67. You work too much.(你做得太多了。)
68. Money will come and go.(钱乃身外之物。)
69. Are you crazy?(你疯了吗?)
70. Have you got it?(明白了吗?)
71. I've got it.(我懂了。)
72. I can't afford that.(我承担/买不起。)
73. I did it, I'm so happy now.(我做到了,现在我很满意。)
74. I don't care.(不关我的事/我不管。)
75. I don't think so.(我不这么想/我看不会/不行/不用。)
76. I guess so.(我想是吧。)
77. I have no other choice.(我别无选择。)
78. I will do my best!(我会尽力的!)
79. I mean it.(我是认真的。)
80. I'm so scared.(我怕极了。)
81. It's hard to say.(难说。)
82. It's a long story.(说来话长/一言难尽。)
83. It's a small world.(世界真小。)
84. It's against the law!(那是违法的!)
85. It's a good opportunity!(好机会!)
86. It's dangerous!(危险!)
87. May I help you?(我能帮忙吗?)
88. No doubt about it.(毫无疑问。)
89. That's bull****!(废话!)
90. Think it over.(仔细考虑一下。)
91. Time will tell.(时间会证明的。)
92. What a surprise!(太令人惊讶了!)
93. Whatever you say!(随便你!)
94. You are the boss!(听你的!你说了算!)
95. You have my word!(我保证!)
96. Tough job, tough day, tough world. Life is not always sweet. That's life!
(艰苦的工作,艰难的日子,不幸的世界。生活并不总是甜蜜的。这就是生活!)
97. I need some sleep.(我需要睡眠。)
98. Take it easy.(别紧张。)
99. Just relax.(放松一下。)
posted @
2007-09-04 10:51 心。 阅读(259) |
评论 (1) |
编辑 收藏
hibernate这个映射的错,搞得我昨天很烦。
想重新生成hbm.xml时,取java src folder说no entries available,奇怪了半天。终于发现工程从subvsion上checkout出来,没有hibernate capabilities,于是add进去。
可恶的映射,想手动配得没有bug还真难。
posted @
2007-08-14 09:22 心。 阅读(6490) |
评论 (1) |
编辑 收藏
在前两天发生java heap space后,终于承认现在这个项目的可憾性,呵呵。
于是毫不犹豫的把JVM Heap Size加大到-Xms256m -Xmx512m。
没想到今天居然PermGen space!真是服了JVM,内存的问题真的是很烦恼的。
于是又无奈的在-Xms256m -Xmx512m 后面追加了 -XX:MaxNewSize=256m -XX:MaxPermSize=512m。
真心疼我的本本……
posted @
2007-08-04 17:45 心。 阅读(777) |
评论 (1) |
编辑 收藏
虽然本人用本本,不过boss坚决抵制内网外网同时上,因为不知道什么原因内外网会乱发包。
由于公司管理网络的才辞掉了,所以前段时间一直苦于内网外网不停的切换中。
偶尔在网上搜到一个办法,发觉真是个高人。
先解决办法如下:
1.设置外网的TCP/IP。
2.设置内网的TCP/IP,and,
不要设置网关,网关为空!
(使得内网无法通过网关路由)
3.运行cmd route命令:route
-p add
149.0.12.0 mask 255.255.255.0
149.0.12.1 metric 1
(-p参数代表永久写入路由表,149.0.12.0和149.0.12.1分别代表你内网的IP段和默认网关)
4.启动两个连接。
终于能一起上,而且不会乱发包了!
posted @
2007-08-04 11:51 心。 阅读(6487) |
评论 (9) |
编辑 收藏
- IOException while loading persisted sessions: java.io.EOFException
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2279)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2748)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:780)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:280)
at org.apache.catalina.util.CustomObjectInputStream.<init>(CustomObjectInputStream.java:57)
at org.apache.catalina.session.StandardManager.doLoad(StandardManager.java:361)
at org.apache.catalina.session.StandardManager.load(StandardManager.java:320)
at org.apache.catalina.session.StandardManager.start(StandardManager.java:634)
at org.apache.catalina.core.ContainerBase.setManager(ContainerBase.java:431)
at org.apache.catalina.startup.ContextConfig.managerConfig(ContextConfig.java:391)
at org.apache.catalina.startup.ContextConfig.start(ContextConfig.java:1042)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:255)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4053)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1012)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1012)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
at org.apache.catalina.core.StandardService.start(StandardService.java:450)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:683)
at org.apache.catalina.startup.Catalina.start(Catalina.java:537)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:271)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:409)
- Exception loading sessions from persistent storage
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2279)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2748)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:780)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:280)
at org.apache.catalina.util.CustomObjectInputStream.<init>(CustomObjectInputStream.java:57)
at org.apache.catalina.session.StandardManager.doLoad(StandardManager.java:361)
at org.apache.catalina.session.StandardManager.load(StandardManager.java:320)
at org.apache.catalina.session.StandardManager.start(StandardManager.java:634)
at org.apache.catalina.core.ContainerBase.setManager(ContainerBase.java:431)
at org.apache.catalina.startup.ContextConfig.managerConfig(ContextConfig.java:391)
at org.apache.catalina.startup.ContextConfig.start(ContextConfig.java:1042)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:255)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4053)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1012)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1012)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
at org.apache.catalina.core.StandardService.start(StandardService.java:450)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:683)
at org.apache.catalina.startup.Catalina.start(Catalina.java:537)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:271)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:409)
解决:保存在硬盘上的session数据读取失败,删除“tomcat\work\Catalina\localhost\工程名”下SESSIONS.ser即可。
posted @
2007-08-03 21:37 心。 阅读(1796) |
评论 (2) |
编辑 收藏
- Creating ActiveMQ Broker
- Loading ActiveMQ Broker configuration from: /WEB-INF/classes/activemq.xml
- Failed to create broker: java.lang.IllegalStateException: Could not find valid implementation for: 2.0
java.lang.IllegalStateException: Could not find valid implementation for: 2.0
at org.apache.xbean.spring.context.impl.XBeanHelper.createBeanDefinitionReader(XBeanHelper.java:48)
at org.apache.xbean.spring.context.ResourceXmlApplicationContext.loadBeanDefinitions(ResourceXmlApplicationContext.java:94)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:89)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:269)
at org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:64)
at org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:52)
at org.apache.activemq.xbean.BrokerFactoryBean.afterPropertiesSet(BrokerFactoryBean.java:77)
at org.apache.activemq.web.SpringBrokerContextListener.createBroker(SpringBrokerContextListener.java:110)
at org.apache.activemq.web.SpringBrokerContextListener.contextInitialized(SpringBrokerContextListener.java:72)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3669)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4104)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1012)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1012)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
at org.apache.catalina.core.StandardService.start(StandardService.java:450)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:683)
at org.apache.catalina.startup.Catalina.start(Catalina.java:537)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:271)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:409)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.apache.xbean.spring.context.impl.XBeanHelper.createBeanDefinitionReader(XBeanHelper.java:46)
23 more
Caused by: java.lang.NoSuchMethodError: org.springframework.beans.factory.xml.XmlBeanDefinitionReader.setValidationMode(I)V
at org.apache.xbean.spring.context.v2.XBeanXmlBeanDefinitionReader.<init>(XBeanXmlBeanDefinitionReader.java:58)
28 more
- Starting ActiveMQ Broker
- Failed to start ActiveMQ broker: java.lang.NullPointerException
java.lang.NullPointerException
at org.apache.activemq.web.SpringBrokerContextListener.contextInitialized(SpringBrokerContextListener.java:76)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3669)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4104)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1012)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1012)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
at org.apache.catalina.core.StandardService.start(StandardService.java:450)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:683)
at org.apache.catalina.startup.Catalina.start(Catalina.java:537)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:271)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:409)
Failed to create broker: java.lang.IllegalStateException: Could not find valid implementation for: 2.0
解决:加载了2次不同的spring,spring 的jar包有重复,删除spring-1.4.jar,保留spring-2.0.jar。
posted @
2007-08-03 21:27 心。 阅读(1034) |
评论 (0) |
编辑 收藏
安装过程就不多说了,执行server811_win32.exe文件,开始安装。安装目录我选在d:\bea,选择完全安装,其他按默认值就行。
下面主要看看配置过程,以下步骤按照WebLogic配置出现界面
1.“开始->程序->Bea WebLogic Platform 8.1-> Configuration Wizard”,启动Configuration Wizard工具。
2.选择“新建WebLogic配置”,单击“next”。
3.选择“Basic WebLogic Server Domain”,单击“next”。
4.选择“custom”,单击“next”。
5.更改Name,单击“next”。
6.选择“否”,单击“next”。
7.选择“否”,单击“next”。
8.选择“否”,单击“next”。
9.输入“User name”和“password”,单击“next”,需要至少8位密码,单击“next”。
10.默认设置,单击“next”。
11.默认设置,单击“next”。
12.Bea WebLogic默认安装了JDK1.4.1,若要使用其它版本。选择“other Java SDK”,点击“browse”指定安装目录。单击“next”。
13.默认值设置,单击“create”。
14.选择“start run server”,单击“done”。
15.再次启动Configuration Wizard工具。
16.选择“extend an existing weblogic configuration”,单击“next”。
17.选择“\bea\user_projects\domains\mydomain”,单击“next”。
18.在“DefaultWebApp”前打上勾选中,单击“next”。
19.默认设置,单击“next”。
20.默认设置,单击“next”。
21.默认设置,单击“next”。
22.默认设置,单击“next”。
23.可更改配置应用程序位置,默认为“\bea\user_projects\applications\mydomain”,单击“import”。导入完成后,系统会在应用程序位置下创建一个DefaultWebApp目录,把你的jsp就放在这儿吧:)
24.单击“done”结束配置。
在jbuider里面进行配置:
1。工具栏上的:enterprise-->configure servers
2。选择左侧user home下的weblogic platform server 8.x
3。选择右侧的enable server
4。home directory选择D:/bea/weblogic81/server
5。选择custom选项卡,bea home directory选择D:/bea
6。domain directory选择D:/bea/user_projects/domains/mydomain
7。输入user name和password
8。去掉下面两个勾选,然后ok
最后一步我有点迷糊。。。
posted @
2007-07-31 16:28 心。 阅读(1610) |
评论 (3) |
编辑 收藏
SimpleDateFormat format=new SimpleDateFormat("yyyyMMdd");
Date end = format.parse("20070729");
Date begin = format.parse("20060420");
long l = end.getTime() - begin.getTime();
long d = l/(24*60*60*1000);
System.out.println(d);
posted @
2007-07-31 16:25 心。 阅读(1099) |
评论 (6) |
编辑 收藏
String sql = "isql -Usa -P -S221 -Jcp936 iE:\\aaa.sql";
try {
Runtime.getRuntime().exec(sql);
} catch (IOException e) {
e.printStackTrace();
}
sybase用isql,-S是你本机sybase客户端的服务名,-J是设置的字符集,-i就需要全路径了。
以上是在能确定数据库用户名、密码……硬件条件的情况下实行的,否则还是在sql脚本文件读到String里,写上for循环一句一句的执行吧。
posted @
2007-07-31 16:25 心。 阅读(883) |
评论 (1) |
编辑 收藏
最笨最实在思路最全面的做法,用于最基础的代码锻炼非常有效,推荐给大家打打java底^_^
package cn.net.withub.xfgl.common;
/** *//**
* @author YuLuo
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
//前一篇已介绍此方法
import cn.net.withub.xfgl.common.ToUnicode;
public class CreatePro {
//读文件
public static String readFile(String filePath, String parameterName) throws IOException, FileNotFoundException {
String result = null;
File file = new File(filePath);
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
byte[] b = new byte[fis.available()];
fis.read(b);
result = new String(b, "UTF-8");
fis.close();
}
return result;
}
//修改后存储
public static void saveFile(String content, String path, String fileName) throws IOException {
File f = new File(path);
if (!f.exists()) {
f.mkdirs();
}
File fn = new File(f, fileName);
FileOutputStream fos = new FileOutputStream(fn);
fos.write(content.getBytes());
fos.close();
}
//删除旧文件
public static void deleteFile(String path) throws IOException {
File f = new File(path);
if (f.exists()) {
f.delete();
} else {
throw new IOException("未找到相关文件");
}
}
//执行方法
public static boolean writeProperties(String filePath, String parameterName, String parameterValue) {
boolean flag = false;
try {
//取得文件所有内容
String all = CreatePro.readFile(filePath, parameterName);
String result = null;
//如果配置文件里存在parameterName
if (all.indexOf(parameterName) != -1) {
//得到parameterName前的字节数
int a=all.indexOf(parameterName);
//取得以前parameterName的值
String old = readProperties(filePath, parameterName);
//得到parameterName值前的字节数
int b=a+(parameterName.length()+"=".length());
//新的properties文件所有内容为:旧的properties文件中内容parameterName+"="+新的parameterName值(parameterValue)+旧的properties文件中parameterName值之后的内容
result=all.substring(0,a)+parameterName+"="+parameterValue+all.substring(b+ToUnicode.convert(old).length(),all.length());
}
//删除以前的properties文件
CreatePro.deleteFile(filePath);
//存储新文件到以前位置
String[] arrPath = filePath.split("WEB-INF");
String path = arrPath[0]+"WEB-INF\\configs";
CreatePro.saveFile(result, path, "xf.properties");
flag=true;
} catch (IOException e) {
e.printStackTrace();
flag=false;
}
return flag;
}
//Properties方法写properties文件
/**//*Properties prop = new Properties();
try {
InputStream fis = new
FileInputStream(filePath);
//从输入流中读取属性列表(键和元素对) prop.load(fis);
//调用 Hashtable 的方法 put。使用 getProperty 方法提供并行性。
//强制要求为属性的键和值使用字符串。返回值是 Hashtable 调用 put 的结果。
OutputStream fos = new FileOutputStream(filePath);
prop.setProperty(parameterName,parameterValue);
//以适合使用 load 方法加载到 Properties 表中的格式,
//将此Properties 表中的属性列表(键和元素对)写入输出流
prop.store(fos, "Update '" + parameterName + "' value \n");
falg = true;
}catch (IOException e) {
e.printStackTrace();
System.err.println("Visit " + filePath + " for updating " + parameterName + " value error");
falg = false;
}*/
//读properties文件,Properties方法
public static String readProperties(String filePath, String parameterName) {
String value = "";
Properties prop = new Properties();
try {
InputStream fis = new FileInputStream(filePath);
prop.load(fis);
value = prop.getProperty(parameterName);
} catch (IOException e) {
e.printStackTrace();
}
return value;
}
posted @
2007-07-31 16:24 心。 阅读(2465) |
评论 (2) |
编辑 收藏
配置文件里的中文,用JDK的native2ascii.exe可以编码,特别好用,自己写了段代码实现如下:
public class ToUnicode {
public static String convert(String s) {
//判断传入字符串是否为中文:取第一个字符判断其字节数
if(s.substring(0,1).getBytes().length==2){
String unicode = "";
char[] charAry = new char[s.length()];
for(int i=0; i<charAry.length; i++) {
charAry = (char)s.charAt(i);
unicode+="\\u" + Integer.toString(charAry, 16);
}
return unicode;
}else{
return s;
}
}
}
posted @
2007-07-31 16:23 心。 阅读(1128) |
评论 (2) |
编辑 收藏
1。
SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd" + " " + "hh:mm:ss");
String datetime = tempDate.format(new java.util.Date());
2。
Calendar now=Calendar.getInstance();
String time=now.get(Calendar.YEAR)+"-"+(now.get(Calendar.MONTH)+1)+"-"+now.get(Calendar.DAY_OF_MONTH)+" "+now.get(Calendar.HOUR_OF_DAY)+":"+now.get(Calendar.MINUTE)+":"+now.get(Calendar.SECOND);
posted @
2007-07-31 16:22 心。 阅读(6103) |
评论 (3) |
编辑 收藏
邮箱:
function isEmail(email){
var filter=/^\s*([A-Za-z0-9_-]+(\.\w+)*@(\w+\.)+\w{2,3})\s*$/;
if(!filter.test(email)){
alert("email error!");
}else{
alert("email ok!");
}
}
电话:
function isTel(tel){
var filter=/^\s*[.0-9]{8,11}\s*$/;
if(!filter.test(tel) || tel<30000000 || tel>20000000000){
alert("tel error!");
}else{
alert("tel ok!");
}
}
QQ:
function isQQ(qq){
var filter=/^\s*[.0-9]{5,10}\s*$/;
if(!filter.test(qq)){
alert("QQ error!");
}else{
alert("QQ ok!");
}
}
posted @
2007-07-31 16:22 心。 阅读(5261) |
评论 (1) |
编辑 收藏
<%!
public String turn(String str) {
while (str.indexOf( " \n " ) !=- 1 ) {
str = str.substring( 0 ,str.indexOf( " \n " )) + " <br> " + str.substring(str.indexOf( " \n " ) + 1 );
}
while (str.indexOf( " " ) !=- 1 ) {
str = str.substring( 0 ,str.indexOf( " " )) + " " + str.substring(str.indexOf( " " ) + 1 );
}
return str;
}
%>
使用时
<%=turn(rs.getString("name"))%>
posted @
2007-07-31 16:21 心。 阅读(960) |
评论 (2) |
编辑 收藏
< script type = " text/javascript " >
var delta = 0.15
var collection;
function floaters() {
this.items = [];
this.addItem = function (id,x,y,content){
document.write( ' <DIV id='+id+'style="Z-INDEX: 10; POSITION:absolute;width:100px;height:100px;left:'+(typeof(x)=='string'?eval(x):x)+';top:'+(typeof(y)=='string'?eval(y):y)+'">'+content+'<br><a href=#onClick="javascript:hiddDiv(this);">关闭</a></DIV>');
var newItem = {};
newItem.object = document.getElementById(id); newItem.x = x;
newItem.y = y;
this.items[this.items.length] = newItem;
}
this.play = function () {
collection = this.items timerShow = setInterval( ' play()',10);
}
}
function play(){
for (var i = 0 ;i < collection.length;i ++ ){
var followObj = collection[i].object;
var followObj_x = (typeof(collection[i].x) == ' string'?eval(collection[i].x):collection[i].x);
var followObj_y = (typeof(collection[i].y) == ' string'?eval(collection[i].y):collection[i].y);
if (followObj.offsetLeft! = (document.body.scrollLeft + followObj_x)) {
var dx = (document.body.scrollLeft + followObj_x - followObj.offsetLeft) * delta;
dx = (dx > 0 ? 1 : - 1 ) * Math.ceil(Math.abs(dx));
followObj.style.left = followObj.offsetLeft + dx;
}
if (followObj.offsetTop! = (document.body.scrollTop + followObj_y)) {
var dy = (document.body.scrollTop + followObj_y - followObj.offsetTop) * delta;
dy = (dy > 0 ? 1 : - 1 ) * Math.ceil(Math.abs(dy));
followObj.style.top = followObj.offsetTop + dy;
}
followObj.style.display = ' ';
}
}
var theFloaters = new floaters();
theFloaters.addItem( ' followDiv1','document.body.clientWidth-85',85,'<a href=photolink target=_blank><img src=photourl border=0 width=85></a>');
theFloaters.addItem( ' followDiv2',0,85,'<a href=photolink target=_blank><img src=photourl border=0 width=85></a>');
theFloaters.play();
function hiddDiv(a){ window.clearInterval(timerShow)
a.parentNode.style.display = ' none';
}
function is800Dpi() // 800 * 600隐藏广告{ if (window.screen.height == 600 ){
hiddDiv();
}
}
is800Dpi()
</ script >
红色部分自行修改. 此乃本公司js高手松哥的原著,勿转载.抄用请注明出处.
posted @
2007-07-31 16:19 心。 阅读(1151) |
评论 (0) |
编辑 收藏
jsp里的两个select:
<select name="lei" onchange="callServer(this.options[this.selectedIndex].text)">
<%
rs=stmt.executeQuery("select dfl from dhyfl");
while(rs.next()){
%>
<option><%=rs.getString("dfl") %></option>
<%
}
%>
</select><select name="smallLei"></select>
jsp底部的Ajax:
<script language="javascript">
var xmlHttp=false;
try {
xmlHttp = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
}
}
}
function callServer(smallLei){
var url="<%=request.getContextPath()%>/smallLei?lei=" + smallLei;
xmlHttp.open("get",url,"true");
xmlHttp.onreadystatechange =upsmlei;
xmlHttp.send(null);
}
function upsmlei(){
if(xmlHttp.readyState == 4){
if(xmlHttp.status==200){
var smlei = document.all.smallLei;
smlei.options.length=0;
var arr=xmlHttp.responseText.split("|");
for(var i=0;i<arr.length-1;i++){
smlei.add(new Option(arr[i],arr[i]));
}
}
}
}
</script>
Ajax的servlet:
package cqrx.ajax;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cqrx.zgdsc.Conn;
public class SmallLei extends HttpServlet {
public SmallLei() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=gb2312");
PrintWriter out = response.getWriter();
String lei = request.getParameter("lei");
lei = new String(lei.getBytes("ISO8859-1"), "GB2312");
out.print(lei);
Conn c = new Conn();
Statement stmt = null;
ResultSet rs = null;
try {
stmt = c.getConn().createStatement();
String sql = "select sfl from shyfl where dfl ='" + lei + "'";
rs = stmt.executeQuery(sql);
String str = "";
while (rs.next()) {
str = str + rs.getString(1) + "|";
}
out.print(str);
} catch (Exception e) {
System.out.print(e.getMessage());
} finally {
out.flush();
out.close();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
public void init() throws ServletException {
}
}
posted @
2007-07-31 16:18 心。 阅读(2705) |
评论 (3) |
编辑 收藏
1.
getServletContext().getRequestDispatcher("/one.jsp").include(request, response);
2.
response.sendRedirect("/demo/one.jsp");
3.
out.println("<script>window.location=\"/demo/one.jsp\";</script>");
posted @
2007-07-31 16:16 心。 阅读(1287) |
评论 (4) |
编辑 收藏