2007年8月15日星期三

Hibernate Jpetstore 之五 部署

文档内容
  • 概览
  • 获得工程代码
  • 配置
    • 数据库初始化
      • MySQL 5.x
      • Oracle 9i, 10g, HsqlDB, Postgres 及其它
    • 应用服务器初始化
      • 本地数据源(非JNDI 数据源)
        • Tomcat 5.x,
        • Sun Application Server8.x, 9.x / GlassFish 1.x, 2.x
        • Jetty 6.1.3
      • JNDI 数据源
        • Sun Application Server8.x, 9.x / GlassFish 1.x, 2.x
        • JBoss 4.0.4 +
        • Jetty 6.1.3
  • 部署并运行
  • 总结
PS: 为什么这个系列的最后一篇这么长时间才出来?原因是,我跟大家说过,工程的所有源代码最终将发布。所以我要找一个合适的地方上载。
这个过程还是比较烦的,况且老外们的工作效率普通不如我们,每次交流至少等上一周左右才有回应。试想申请、审批,确认,上载等过程,其实令我这个急性子试 图想把自己家里的电脑搬到主机托管中心,申请一个域名了事!

还好,它终于出来了 (hjpetstore)!但愿没让你失望。

在阅读本篇文章之前,请先仔细阅读前面系列的相关内容。

概览

对于传统的J2EE 项目,当项目开发完后,其工作并未结束,紧接着的部署过程其实是很令开发者头痛的,特别是象重量级的应用服务 WebLogic, WebSphere 等。还好 NetBeans 现在抬简化了这一过程。
我们这个例子是基于无存在数据库的方案,所以在我们演示结果前,我们将要导入一些数据。但首先我们得创建相应的数据库用户和数据库方案(Schema).

获得工程代码

1.从 hjpetstore 得到工程源代码,具体的步骤网站上有说明,在 NetBeans 中就很简单了:

CVS | checkout:
cvs root: :pserver:username@cvs.dev.java.net:/cvs (这个 username 是你必须到 java.net 上注册的用户名称,目前 anonymous 好象不能工作了)
password:

下一页中, module: hjpetstore 下载完后,NetBeans 会问你是否打开该工程,选择是。

2. 你可能需要调整一下lib 的位置,这是 NetBeans 的一个缺陷,保存的路径不是相对路径。
右击工程 | properties
点 Libraries,在Compile 页中将所有 .jar 文件 选中后 'remove',
再加入下载下来的WEB-INF/lib 目录下的所有 jar 文件

3. 确保 Clean And Build project 成功


配置

数据库初始化

我这里只介绍 MySql 的 配置,其它的数据库配置列作 TBD. (待做,其实大部分脚本已经在工程中了,等待你的加入吧!因为我不是一个数据库专家,也没有太多时间去研究这个。)我成功配置过oracle 和 hsqldb.

注 意:因为下面的脚本会删除 'hjpetstore'数据库用户及其所有资源,请确保用户 'hjpetstore' (oracle) 或数据库 hjpetstore (mysql) 目前没被使用,如果使用了,请修改数据库脚本。所以最好的办法是使用你的个人数据库来作演示。

MySQL 5.x


1. 创建用户hjpetstore 和 数据库 hjpetstore

# 在命令行下以 root 身份运行创建脚本
# $hjpetstore 是用真实的工程路径代替
# 其它值根据你的设置作相应的改变,比如你如果连非本机的数据库,那 'localhost' 就是那个机器在 ip 了
> mysql -h localhost -u root -p < $hjpetstore\conf\jpetstore_mysql.sql Enter password: ******** 如果程序的输出显示了 hjpetstore, 则表明成功了: Database information_schema
hjpetstore

mysql
...

或者,如果有mysql query browser 的话,用它直接运行如下命令也可:
-- frist drop database hjpetstore and user hjpetstore
drop database if exists hjpetstore;

create database hjpetstore;

-- create user hjpetstore and give the password hjpetstore
grant all privileges on hjpetstore.* to hjpetstore identified by 'hjpetstore';

show databases;

2. 得用 hibernate.hbm2ddl.auto 自动生成数据库方案
确保 web/WEB-INF/dataAccessContext-hibernate.xml 中 设置了 update

这个属性的具体含义,我在前面的系列中已经讲过了,在产品初始化,你就可以安全地把它注释掉。

3. 在 NetBeans 右击工程 Run project
这一步将所有的数据库表创建出来, 只是没有数据。

4. 加裁数据
使用 NetBeans Sql Editor
4.1 注册mysql 驱动
Runtime | DataBases 右击 -> new Driver
Add ... -> 导航到工程WEB-INF/lib/下的 mysql-connector-java-3.1.12-bin 点 OK

4.2 创建连接
右击刚注册的驱动 MySql (Connector/J driver) -> Connect using ....
Database URL: jdbc:mysql://localhost:3306/hjpetstore?useUnicode=true&characterEncoding=UTF-8
user name: hjpetstore
password: hjpetstore

点 Ok 后,在Databases 下应该会出现一个新的连接。

4.3 执行 SQL 脚本
1. 在 Files 窗口中导航到 db/mhsql/jpetstore-mysql-dataload.sql 并双击打开它
2. 在编辑器的工具条中 Connection: 选择 刚创建的数据库连接:jdbc:mysql://localhost:3306/hjpetstore?useUnicode=true&amp;amp;amp;amp;amp;amp;amp;amp;ampamp;characterEncoding=UTF-8
3. 点击编辑器工具条上,紧挨着下拉框的 run sql

确保没有显示错误信息。


Oracle 9i, 10g, HsqlDB, Postgres 及其它


数据库脚本都已经在工程中了,你所要做的就是利用这些数据库提供的工具创建一个用户 'hjpetstore',
之后的步骤与上述相同。


应用服务器初始化

本地数据源(非JNDI 数据源)


Tomcat 5.x,
事实上,工程默认是使用 Tomcat 服务器的,所以现在你根本不需要改动什么就可以运行工程了。
有关数据源的配置是在 web/META-INF/ context.xml 文件中

Sun Application Server8.x, 9.x / GlassFish 1.x, 2.x
同样的配置,只不过要生成一个 sun-web.xml 文件,
很好,NetBeans 会帮你自动产生,如下:
右击工程 -> Run | Server: 选择注册的Sun App Server (如果你还没注册 Sun App Server 的话,你需要先注册一下,具体步骤见相关文档)

此时,文件已经产生,右击工程 -> Run Project

Jetty 6.1.3
所有的配置文件已经在 WEB-INF 下了: jetty-web.xml, jetty-env.xml, 所以要做的只剩下将dist 上下生成的 hibernateJpetstore.war
放到 Jetty 的部署目录,还好这个目录跟 Tomcat 的目录同名叫 webapps

在 Jetty 目录下运行:
java -jar start.jar
然后在浏览器中请求: http://localhost:8080/hjpetstore/

JNDI 数据源


使用JNDI数据源当然是为了使用其 JTA(包容器管理的事务及其数据库连接池的实现),
只需要按正确的名称 jdbc/hjpetstore 在管理界面配好数据库连接池和相应的数据源,运行起来还是挺方便的,

Sun Application Server8.x, 9.x / GlassFish 1.x, 2.x
1. 首先按照这篇文章介绍的步骤正确配置 mysql 数据源连接池
(中文) http://pprun.blogspot.com/2007/05/glassfishsun-app-server.html
(English) http://enpprun.blogspot.com/2007/05/problem-in-setting-mysql-xa-datasource.html
注意,我文章中介绍的是使用root/root 作为用户名/密码,此时可以设置成hjpetstore/hjpetstore

2. 配置数据源
在应用服务器的 管理 界面 导航Resources | JDBC | JDBC Resources
点击右边主页面中的 new 后进入配置页面,填入:
JNDI Name: jdbc/hjpetstore
Pool Name: 选择前面配置的数据源:连接池:mysql
完成后点击 Ok


JBoss 4.0.4 +

1. 使用 JBoss 也许是冲着所谓的 #1 应用服务器而来的吧,但其配置有一些变化:
第一它实现了自己的一套日志方式,所以需要把 web.xml 中的

org.springframework.web.util.Log4jConfigListener

注释掉。

2. 它的数据源的配法也不相同,只需要将相应的数据库的配置文件(如:mysql-ds.xml ,内容见随后)放到
jboss-4.0.4.GA\server\default\deploy 目录下,
再在 jboss-4.0.4.GA\server\default\conf\login-config.xml 中加入:
    <application-policy name = "MySqlDbRealm">
<authentication>
<login-module code
= "org.jboss.resource.security.ConfiguredIdentityLoginModule" flag =
"required">
<module-option name ="principal">hjpetstore</module-option>
<module-option name ="userName">hjpetstore</module-option>
<module-option name ="password">hjpetstore</module-option>

<module-option name
="managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=hjpetstore-mysql</module-option>
</login-module>
</authentication>
</application-policy>
mysql-ds.xml 相应的内容如下:
    <?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>

<jndi-name>hjpetstore-mysql</jndi-name>
<connection-url>jdbc:mysql://localhost:3306/hjpetstore</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>hjpetstore</user-name>
<password>hjpetstore</password>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>

<!-- should only be used on drivers after 3.22.1 with "ping" support

<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>
-->
<!-- sql to call when
connection is created

<new-connection-sql>some arbitrary sql</new-connection-sql>
-->
<!-- sql to call on an
existing pooled connection when it is obtained from pool -
MySQLValidConnectionChecker is preferred for newer drivers

<check-valid-connection-sql>some arbitrary
sql</check-valid-connection-sql>

-->

<!-- corresponding
type-mapping in the standardjbosscmp-jdbc.xml (optional for ejb) -->
<metadata>

<type-mapping>mySQL</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>


3. 还有,就是JBoss 的 JNDI 的名称有些怪:
    <bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">

<!-- JBoss
-->

<property name="jndiName" value="java:/hjpetstore-mysql">

<!-- other standard Java EE server

<property name="jndiName"
value="java:comp/env/jdbc/hjpetstore">
-->
</bean>


看到区别了吗?它只需要java:/hjpetstore-mysql


Jetty 6.1.3
目前,还未测试成功!


部署并运行


在 NetBeans 中,只需要在 工程属性中选定所要运行的 服务器后,点 Run Project 即可运行在本地数据源配置上。
此外,还可以按照服务指定的自动部署目录,将生成的 dist/hibernateJpetstore.war 文件放到该目录,
如果服务器已经运行,一切就 ok 了,如果没有,启动服务器即可。

如果要运行在 JNDI 配置上,则需要改一下 web.xml :

<!--
- Location of the XML file that defines the root
application context.
- Applied by ContextLoaderServlet.
-->
<context-param>

<param-name>contextConfigLocation</param-name>

<!-- local datasource -->
<param-value>
/WEB-INF/dataAccessContext-hibernate.xml
/WEB-INF/applicationContext.xml
</param-value>
<!-- jndi datasource and JTA (for a transactional
JNDI DataSource)

<param-value>

/WEB-INF/dataAccessContext-hibernate-jndi.xml
/WEB-INF/applicationContext.xml
</param-value>
-->
</context-param>

这几行配置说的应该很明白了,上面的是默认情况下的本地数据源,如果使用JNDI数据源,是这样了:

<context-param>


<param-name>contextConfigLocation</param-name>



<!-- jndi datasource and JTA (for a
transactional JNDI DataSource) -->

<param-value>


/WEB-INF/dataAccessContext-hibernate-jndi.xml
/WEB-INF/applicationContext.xml

</param-value>



</context-param>


只要按照上述的步骤配置好了应用服务器的数据源,现在运行的效果应该跟本地数据源是一样的。


总结


NetBeans 对于 Java EE 的开发是全面的,除了几个服务器还未集成进来之外,其它的功能已经走在了所有IDE的最前列,
但这也不防碍开发者使用这些未集成的服务器,因为大部分服务器都支持热部署,当NetBeans 给你的工程生成了 WAR 文件后,
剩下的就是“将它放入热部署目录”了。


看运行在 Jetty6.1.3 上的效果 (注意脚注部分显示,当前运行在什么服务器上):

2007年8月14日星期二

爱因斯坦精神

[转载]
听过一个故事:以前有个小孩,很喜欢拉小提琴,却又拉得不怎么样。连他的父母也觉得这孩子没什么天分,因为琴声真的好难听。于是他求教于一位教授,教授 说:“你为什么要拉小提琴呢?你觉得你快乐吗?”小孩子说:“我想成为一个伟大的小提琴家!我觉得我拉小提琴很快乐。”“那你就不用太刻意去学了”教授 说,你只要觉得快乐就好。小孩于是明白了,他以后都只是把拉小提琴当作是一种生活享受。后来,他在物理领域获得了很大成功,成了改变世界的一个伟人。此人 就是爱因斯坦!!
我觉得我们应该学习他:学会放弃,只要你从中获得快乐,那么你就不要计较是否要获得成功。学会坦然处之。

今年是狭义相对论发表100周年,也是联合国确定的世界物理年,主要纪念伟大的物理学家和社会活动家爱因斯坦对人类所作出的多方面的巨大贡献。爱因斯坦是全身心献身科学和主张科学无国界的理想主义者,是强调科学技术应当以人为本的人道主义者,是具有强烈社会责任感、反对法西斯和主持正义的社会活动家。在人类发展史上,爱因斯坦占有光辉的位置。我们纪念爱因斯坦这位伟人,不仅要了解他在科学上所作出的重要贡献,更要学习他在任何困难条件下都一心为科学而献身的精神,学习他为社会公正和反对法西斯战争而无私无畏的奋斗精神。我们还应当通过爱因斯坦成长的道路,分析产生这样杰出人物的条件,努力为中国青年创造良好的学习和成长的环境,使优秀人才能够脱颖而出,使中国科学能够早日跻身世界先进行列。

一、爱因斯坦对物理学的重要贡献


在20世纪初古典物理学出现危机的关键时刻,爱因斯坦是推动物理学革命思想的一面光辉旗帜。他独自发现了狭义相对论和广义相对论,从根本上改变了传统的绝对时空观念,将时空、物质和作用力通过对称性统一起来。从狭义相对论出发,他提出了质量和能量等价的公式,开辟了原子能的时代。从广义相对论和核能出发,他和一批科学家发展了宇宙构造和起源的模式,他提出的宇宙常数预示了产生排斥力的暗能量的存在。他和普兰克及玻尔一起是量子论的主要奠基人,他提出了集波动性和粒子性于一身的光量子学说,解释了光电效应,促进了量子波动力学的发现。他发展了原子论和统计力学,解释了从布朗运动、固体比热到受激辐射等一系列现象,和玻色合作,建立了玻色—爱因斯坦量子统计理论,预见了玻色凝聚态的存在。他质疑量子力学提出的量子纠缠态,开辟了量子信息学的新领域。他在晚年致力于统一场论,虽然没有取得他预期的结果,但他提出的从高维几何局域对称性出发进行统一相互作用力的思想至今仍指导着基本相互作用大统一理论的发展方向,在他逝世后的半个世纪中,已经在弱电和强相互作用的统一中得到体现。

他的科学思想远远超越当时的时代,具有非凡的前瞻性和深刻性,以至他许多重要的理论发表以后,短期内得不到物理界的普遍认同。他的科学发现不是天才的灵机一动,而是通过自学掌握了当时最前沿的科学成就,经过多年艰苦的思索才完成的。他在高中最后一年,就已经学习了当时大学还未讲授的电动力学理论,并对和光一起运动会产生什么现象进行了思考,10年以后才发现了狭义相对论。他在1909年开始认识到加速度和重力的等价关系,经过6年的努力和多次的失败,才建立了正确的广义相对论引力方程。

相对论和量子力学是20世纪最重要的科学发现,不仅为我们提供了从微观夸克到宏观宇宙的物质和运动的图像和规律,丰富了我们的物质观和宇宙观,而且为20 世纪技术的发展提供了科学的基础。虽然爱因斯坦从事的是基础研究,他并不知道这些研究有什么实用价值,但是,越是基本的规律,覆盖的现象越广泛,潜在应用的面越广,产生的价值也越大。在微电子、激光、原子能、GPS、传感器、加速器、信息保密等等广泛应用的技术中都可以看到爱因斯坦研究成果的影响。

二、爱因斯坦的人生观和社会活动


爱因斯坦对他自己的人生观曾经说道:“要追究一个人自己或是一切生物生存的意义或目的,从客观的观点看来,我总觉得是愚蠢可笑的。可是每个人都有一定的理想,这种理想决定着他的努力和判断的方向。就在这个意义上,我从来不把安逸和享乐看作是生活目的本身——这种伦理基础,我叫它猪栏的理想。照亮我的道路,并且不断地给我新的勇气去愉快地正视生活的理想,是善、美和真。要是没有志同道合者之间的亲切感情,要不是全神贯注于客观世界——那个在艺术和科学工作领域里永远达不到的对象,那么在我看来,生活就会是空虚的。人们所努力追求的庸俗的目标——财产、虚荣、奢侈的生活——我总觉得都是可鄙的。”“当我还是一个相当早熟的少年的时候,我就已经深切地意识到,大多数人终生无休止地追逐的那些希望和努力是毫无价值的。而且,我不久就发现了这种追逐的残酷,这在当年较之今天是更加精心地用伪善和漂亮的字句掩饰着的。每个人只是因为有个胃,就注定要参与这种追逐。而且,由于参与这种追逐,他的胃是有可能得到满足的;但是,一个有思想、有感情的人却不能由此而得到满足。”“我每天上百次地提醒自己,我的精神生活和物质生活都依靠别人(包括活着的人和死去的人)的劳动。我必须尽力以同样的分量来报答我领受了的和至今还在领受的东西,我强烈地向往着简朴的生活,并常常为发现自己占有了同胞过多的劳动而难以忍受。”

他不仅是这样说,也是这样做的。在他创造力最丰富的青年时代,他的生活非常艰苦,经历过歧视和失业,但他从不屈服去追求庸俗的目标,而是全神贯注于科学研究。即使到美国定居以后,他主动要求不要给他很高的薪水,继续过着俭朴的生活。

在他就职柏林科学院不久,第一次世界大战爆发,他从头开始就公开反对这场战争。他说过:“我反对一切形式的战争,除非那个敌人以毁灭人类作为它的唯一目的”。为此,他遭到了当局的迫害和部分报纸的谴责。德国的失败使德国科学家处于孤立的困难境地。爱因斯坦虽有瑞士国籍,被邀请参加国际物理会议和到其它国家就职,但他认为,科学是全人类共同的事业,不应该因政治原因而孤立德国科学家。在德国科学家不被邀请的情况下,他也拒绝出席会议和离开柏林去他地就职。他说:“我曾对普朗克许下诺言,在这里的环境没恶化到普朗克本人承认我的离开是自然而然的和正确的之前,我不离开柏林。如果我不是迫不得已,而是哪怕是部分地出自物质利益便离开我的政治期望正在那里实现的国家,离开用爱和友谊来温暖我的人们,而在开始堕落的时期我的离开对他们来说可能会加倍地难受……那我就是忘恩负义了。”很可惜,他的民主和社会主义的政治期望并未在战后德国实现,法西斯上台后把他视为犹太人的领袖,加大了迫害的手段,迫使他移居美国。此后,他一直以他个人的威望反对法西斯和关心弱小民族的命运。他对中国人民的苦难深表同情,多次支持中国抗日和中国人民争取民主权利的斗争。

爱因斯坦多次告诫科学家要履行自己的社会职责。他说:“任何技术的应用都必须以人为本,关怀人的命运。”“要关心如何安排人的劳动和分配财富,以保证科学的成果用于造福人类,而不是用于破坏的那些尚未解决的大问题。”他还说:“国家是为人而存在,而不是相反,科学也是一样。”

三、爱因斯坦的教育思想和成长历程


爱因斯坦不是一个通常意义下循规蹈矩的好学生,他厌恶那些不尊重学生主动性和独立人格的灌输式教育,他在中学和大学都不为老师所看重。他在自述中写到: “有时,人们把学校简单地看作是一种工具,靠它来把大量的知识传授给成长中的一代。但这种看法是不正确的。知识是死的;而学校却要为活人服务。它应当发展青年人中那些有益于公共福利的品质和才能。但这并不是意味着个性应当消灭,而个人只变成像一只蜜蜂或蚂蚁那样仅仅是社会的一种工具。因为一个由没有个人独创性和个人志愿的规格、统一的个人所组成的社会,将是一个没有发展可能的不幸的社会。相反地,学校的目标应当是培养有独立行动和独立思考的个人,不过他们要把为社会服务看作是自己人生的最高目的。”他还说:“自由行动和自我负责的教育,比起那种依赖训练、外界权威和追求名利的教育来,是多么的优越呀。真正的民主决不是虚幻的空想。”他从小就需要自由的时空和选择来安排自己的学习,他很少听课,利用同学的笔记对付强制的考试,他说:“尽管摆在我们面前的课程本身都是有意义的,可是我仍要花费很大的力气才能基本上学会这些东西。对于像我这样爱好沉思的人来说,大学教育并不总是有益的。无论多好的食物强迫吃下去,总有一天会把胃口和肚子搞坏的。纯真的好奇心的火花会渐渐地熄灭。幸运的是,对我来说,这种智力的低落在我学习年代的幸福结束之后只持续了一年。” “事实上,现代的教学方法还没有把神圣的求知欲完全扼杀掉,这差不多是一个奇迹;因为这株脆弱的幼苗,除了需要鼓励之外,首先需要自由——没有自由它将不可避免地会夭折”。

给一位教授的求情信这样写到:“亲爱的教授:请原谅一个父亲为了他儿子的事情来打搅您。……我的儿子目前失业,这使他深感难过。他越来越觉得,他的事业已经失败,再也无可挽回。而最使他沮丧的是,他感到自己是我们的负担,因为我们的景况不好……”这位教授是否给过帮助,现在已无从了解,但可以肯定大学的教授们从未认为爱因斯坦是个做学问的人才。

1902年,在同学格罗斯曼的父亲的帮助下,爱因斯坦获得了瑞士专利局职员的工作,才得以靠微薄的收入维持一家的生活,而在1905年发表的改变20世纪物理学面貌的5篇重要论文则是他业余时间的创作。爱因斯坦在专利局工作到1909年,才有大学聘请他为副教授。对这7年的生活,他回顾到:“在我最富于创造性活动的1902~1909年这几年中,我就不用为生活而操心了。即使完全不提这一点,明确规定技术专利权的工作,对我来说也是一种真正的幸福。它迫使你从事多方面的思考,它对物理的思索也有重大的激励作用。总之,对于我这样的人,一种实际工作的职业就是一种绝大的幸福。因为学院生活会把一个年轻人置于这样一种被动的地位:不得不去写大量科学论文——结果是趋于浅薄,这只有那些具有坚强意志的人才能顶得住。然而大多数实际工作却完全不是这样……作为一个平民,他的日常生活并不靠特殊的智慧。如果他对科学深感兴趣,他就可以在本职工作之外埋头研究他所爱好的问题。不必担心他的努力会毫无成果。”

四、留给我们的思考


爱因斯坦的一生多姿多彩,光辉伟大。他在艰苦条件下坚持献身科学的理想,他维护正义、反对法西斯和强调以人为本的社会责任感,他不唯上、不唯书、不迷信权威、不惧怕困难、不为世俗名利动心、不受传统制度和观点的束缚,独立自主,自由思考,刨根到底地追求科学真理。敢想敢干,敢于超越!