<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>五四陈科学院-坚信科学，分享技术 &#187; java</title>
	<atom:link href="http://www.54chen.com/tag/java/feed" rel="self" type="application/rss+xml" />
	<link>http://www.54chen.com</link>
	<description>PHP、JAVA、缓存、架构、经验、分享</description>
	<lastBuildDate>Fri, 10 Feb 2012 12:21:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>quercus记录：php使用连接池访问数据库</title>
		<link>http://www.54chen.com/php-tech/quercus-php-connect-pool.html</link>
		<comments>http://www.54chen.com/php-tech/quercus-php-connect-pool.html#comments</comments>
		<pubDate>Fri, 04 Nov 2011 02:29:30 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[quercus]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/quercus-php-connect-pool.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>上周记录了如何用quercus建立混合型项目。 http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html 这里来说说与数据库的访问，使用jndi得到连接池的好处。 JNDI (Java Naming and Directory Interface)是SUN公司提供的一种标准的Java命名系统接口，JNDI提供统一的客户端API，通过不同的访问提供者接口JNDI SPI的实现，由管理者将JNDI API映射为特定的命名服务和目录系统，使得Java应用程序可以和这些命名服务和目录服务之间进行交互。 正题 在quercus中可以随意使用mysql_connect与mysql_pconnect两个方法来连接数据库。 当在web.xml定义得有database相关的消息时，mysql_connect与mysql_pconnect都会自动忽略里面的参数设置，直接使用web.xml的定义。 添加jndi设置： vim WEB-INF/web.xml &#60;?xml&#160;version="1.0"&#160;encoding="utf-8"?&#62;&#160;&#160; &#60;web-app&#160;&#160;xmlns="http://caucho.com/ns/resin"&#62;&#160;&#160; &#160;&#160;&#60;description&#62;truth&#160;application&#60;/description&#62;&#160;&#160; &#160;&#160;&#60;database&#160;jndi-name="jdbc/mysql"&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;driver&#160;type="com.mysql.jdbc.Driver"&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#60;url&#62;jdbc:mysql://192.168.1.5:3306/truth?useUnicode=true&#38;amp;characterEncoding=utf-8&#60;/url&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#60;user&#62;你的用户名&#60;/user&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#60;password&#62;你的密码&#60;/password&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#60;init-param&#160;useUnicode="true"/&#62;&#160;&#60;!--实践证明这个是不管用的，因为quercus写土了，全用的latin1字符集，后面再说--&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;/driver&#62;&#160;&#160; &#160;&#160;&#60;/database&#62;&#160;&#160; 使用的是resin4，需要继续在web.xml的servlet段里增加： &#60;init-param&#62;&#160;&#160; &#160;&#160;&#60;param-name&#62;database&#60;/param-name&#62;&#160;&#160; &#160;&#160;&#60;param-value&#62;jdbc/mysql&#60;/param-value&#62;&#160;&#160; &#60;/init-param&#62;&#160;&#160; 这里注意，param-value与上面的jndi-name对应，mysql_connnect函数在web.xml里有这个init-param的定义的时候，将使用对应的jndi的设置。由此可得到连接池的好处。 上面的例子只使用了jdbc的基础驱动，如果向下面的配置，自然就得到了pool: 例子1: &#60;database&#62;&#160;&#160; &#160;&#160;&#60;jndi-name&#62;jdbc/mysql&#60;/jndi-name&#62;&#160;&#160; &#160;&#160;&#60;driver&#62;&#160;&#60;type&#62;com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource&#60;/type&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;url&#62;jdbc:mysql://localhost:3306/dbname&#60;/url&#62;&#160;&#160; &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://www.caucho.com/wp-content/themes/caucho/images/caucho-logo.png" alt="java php quercus" /><br />
上周记录了如何用quercus建立混合型项目。<br />
<a href="http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html">http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html</a><br />
这里来说说与数据库的访问，使用jndi得到连接池的好处。</p>
<p><strong>JNDI</strong><br />
(Java Naming and Directory Interface)是SUN公司提供的一种标准的Java命名系统接口，JNDI提供统一的客户端API，通过不同的访问提供者接口JNDI SPI的实现，由管理者将JNDI API映射为特定的命名服务和目录系统，使得Java应用程序可以和这些命名服务和目录服务之间进行交互。</p>
<p><strong>正题</strong><br />
在quercus中可以随意使用mysql_connect与mysql_pconnect两个方法来连接数据库。<br />
当在web.xml定义得有database相关的消息时，mysql_connect与mysql_pconnect都会自动忽略里面的参数设置，直接使用web.xml的定义。</p>
<p><strong>添加jndi设置：</strong><br />
vim WEB-INF/web.xml</p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-xml" start="1">
<li class="alt"><span><span class="tag">&lt;?</span><span class="tag-name">xml</span><span>&nbsp;</span><span class="attribute">version</span><span>=</span><span class="attribute-value">"1.0"</span><span>&nbsp;</span><span class="attribute">encoding</span><span>=</span><span class="attribute-value">"utf-8"</span><span class="tag">?&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span><span class="tag">&lt;</span><span class="tag-name">web-app</span><span>&nbsp;&nbsp;</span><span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://caucho.com/ns/resin"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">description</span><span class="tag">&gt;</span><span>truth&nbsp;application</span><span class="tag">&lt;/</span><span class="tag-name">description</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">database</span><span>&nbsp;</span><span class="attribute">jndi-name</span><span>=</span><span class="attribute-value">"jdbc/mysql"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">driver</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"com.mysql.jdbc.Driver"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">url</span><span class="tag">&gt;</span><span>jdbc:mysql://192.168.1.5:3306/truth?</span><span class="attribute">useUnicode</span><span>=</span><span class="attribute-value">true</span><span>&amp;amp;</span><span class="attribute">characterEncoding</span><span>=</span><span class="attribute-value">utf</span><span>-8</span><span class="tag">&lt;/</span><span class="tag-name">url</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">user</span><span class="tag">&gt;</span><span>你的用户名</span><span class="tag">&lt;/</span><span class="tag-name">user</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">password</span><span class="tag">&gt;</span><span>你的密码</span><span class="tag">&lt;/</span><span class="tag-name">password</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">init-param</span><span>&nbsp;</span><span class="attribute">useUnicode</span><span>=</span><span class="attribute-value">"true"</span><span class="tag">/&gt;</span><span>&nbsp;</span><span class="comments">&lt;!--实践证明这个是不管用的，因为quercus写土了，全用的latin1字符集，后面再说--&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">driver</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">database</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>使用的是resin4，需要继续在web.xml的servlet段里增加：</p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-xml" start="1">
<li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">init-param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">param-name</span><span class="tag">&gt;</span><span>database</span><span class="tag">&lt;/</span><span class="tag-name">param-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">param-value</span><span class="tag">&gt;</span><span>jdbc/mysql</span><span class="tag">&lt;/</span><span class="tag-name">param-value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span><span class="tag">&lt;/</span><span class="tag-name">init-param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>这里注意，param-value与上面的jndi-name对应，mysql_connnect函数在web.xml里有这个init-param的定义的时候，将使用对应的jndi的设置。由此可得到连接池的好处。</p>
<p>上面的例子只使用了jdbc的基础驱动，如果向下面的配置，自然就得到了pool:<br />
<strong>例子1:</strong></p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-xml" start="1">
<li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">database</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">jndi-name</span><span class="tag">&gt;</span><span>jdbc/mysql</span><span class="tag">&lt;/</span><span class="tag-name">jndi-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">driver</span><span class="tag">&gt;</span><span>&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">type</span><span class="tag">&gt;</span><span>com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource</span><span class="tag">&lt;/</span><span class="tag-name">type</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">url</span><span class="tag">&gt;</span><span>jdbc:mysql://localhost:3306/dbname</span><span class="tag">&lt;/</span><span class="tag-name">url</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">user</span><span class="tag">&gt;</span><span>username</span><span class="tag">&lt;/</span><span class="tag-name">user</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">password</span><span class="tag">&gt;</span><span>password</span><span class="tag">&lt;/</span><span class="tag-name">password</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">init-param</span><span>&nbsp;</span><span class="attribute">useUnicode</span><span>=</span><span class="attribute-value">"true"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">driver</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span><span class="tag">&lt;/</span><span class="tag-name">database</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p><strong>例子2:</strong></p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-xml" start="1">
<li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">database</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">jndi-name</span><span class="tag">&gt;</span><span>jdbc/mysql</span><span class="tag">&lt;/</span><span class="tag-name">jndi-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">driver</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"org.gjt.mm.mysql.Driver"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">url</span><span class="tag">&gt;</span><span>jdbc:mysql://localhost:3306/test</span><span class="tag">&lt;/</span><span class="tag-name">url</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">user</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">user</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">password</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">password</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">driver</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">prepared-statement-cache-size</span><span class="tag">&gt;</span><span>8</span><span class="tag">&lt;/</span><span class="tag-name">prepared-statement-cache-size</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">max-connections</span><span class="tag">&gt;</span><span>20</span><span class="tag">&lt;/</span><span class="tag-name">max-connections</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">max-idle-time</span><span class="tag">&gt;</span><span>30s</span><span class="tag">&lt;/</span><span class="tag-name">max-idle-time</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">database</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>这些简单的配置，都可以让php轻松跑在连接池上。<br />
<strong>问题所在：</strong><br />
quercus写土了，没有在用户设置为unicode的时候来解析用户的输入，到处是hard code的latin1。（本来在GAE里使用这东西的人挺多的，可惜吧，AGE被盾了，然后quercus反馈latin1问题的人也不多，唉。）</p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-j" start="1">
<li class="alt"><span><span>com.caucho.quercus.lib.db.JdbcConnectionResource:&nbsp;</span><span class="number">94</span><span>&nbsp;&nbsp;</span><span class="number">348</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>com.caucho.quercus.lib.db.Mysqli:<span class="number">229</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>上面三处修改为utf8即可。</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/php-tech/quercus-php-connect-pool.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>quercus记录：php和java的混合型项目建立手记</title>
		<link>http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html</link>
		<comments>http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html#comments</comments>
		<pubDate>Tue, 25 Oct 2011 13:30:55 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[quercus]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>创业公司参与项目的人口众多、背景不一，目前市场上的主流方向为php与java，很多时候java工程师恨铁不成钢，php工程师也无可奈何。于是便有了此文，讲述如何使用quercus创建php java混合型项目。 quercus是什么？ quercus是Caucho公司针对php语言的java实现，100%完成了php5的解析。是resin内建支持的功能。同时，因为使用了resin，使得php可以很容易得到连接池、分布式session、负载均衡等功能。使用resin的php项目可以更加安全，不存在很多fastcgi的问题。 性能如何？ 官方：用mediawiki与drupal来做实验，要比mod_php快4倍。 有一个编译选项，在resin专业版里支持，可以把php转成java class，得到更高性能。 新建一个java项目混合php项目 web.xml是关键，里面声明了*.php文件的访问都以com.caucho.quercus.servlet.QuercusServlet来执行。 &#60;?xml&#160;version="1.0"&#160;encoding="UTF-8"?&#62;&#160;&#160; &#60;web-app&#160;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&#160;&#160; &#160;&#160;&#160;&#160;xmlns="http://java.sun.com/xml/ns/javaee"&#160;xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&#160;&#160; &#160;&#160;&#160;&#160;xsi:schemaLocation="http://java.sun.com/xml/ns/javaee&#160;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&#160;&#160; &#160;&#160;&#160;&#160;id="WebApp_ID"&#160;version="2.5"&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;display-name&#62;testquercus&#60;/display-name&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;welcome-file-list&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;welcome-file&#62;index.html&#60;/welcome-file&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;welcome-file&#62;index.php&#60;/welcome-file&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;/welcome-file-list&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;servlet&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;servlet-name&#62;Quercus&#160;Servlet&#60;/servlet-name&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;servlet-class&#62;com.caucho.quercus.servlet.QuercusServlet&#60;/servlet-class&#62;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#60;/servlet&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;servlet-mapping&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;servlet-name&#62;Quercus&#160;Servlet&#60;/servlet-name&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;url-pattern&#62;*.php&#60;/url-pattern&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;/servlet-mapping&#62;&#160;&#160;&#160; &#60;/web-app&#62;&#160;&#160; 所有的php文件放在webapp下，所有的java文件还放到java目录里。 如何混合java到php中? 在java目录新建类Test54Chen，生成后位置： WEB-INF/classes/com/chen/FrameWork.class /**&#160; &#160;*&#160;@author&#160;54chen(陈臻)&#160;[chenzhen@xiaomi.com&#160;czhttp@gmail.com]&#160; &#160;*&#160;@since&#160;2011-10-25&#160;下午08:40:49&#160; &#160;*/&#160;&#160; package&#160;com.chen;&#160;&#160; &#160;&#160; public&#160;class&#160;FrameWork&#160;{&#160;&#160; &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p>创业公司参与项目的人口众多、背景不一，目前市场上的主流方向为php与java，很多时候java工程师恨铁不成钢，php工程师也无可奈何。于是便有了此文，讲述如何使用quercus创建php java混合型项目。</p>
<p><strong>quercus是什么？</strong><br />
quercus是Caucho公司针对php语言的java实现，100%完成了php5的解析。是resin内建支持的功能。同时，因为使用了resin，使得php可以很容易得到连接池、分布式session、负载均衡等功能。使用resin的php项目可以更加安全，不存在很多fastcgi的问题。</p>
<p><strong>性能如何？</strong><br />
官方：用mediawiki与drupal来做实验，要比mod_php快<strong>4</strong>倍。<br />
有一个编译选项，在resin专业版里支持，可以把php转成java class，得到更高性能。</p>
<p><strong>新建一个java项目混合php项目</strong><br />
web.xml是关键，里面声明了*.php文件的访问都以com.caucho.quercus.servlet.QuercusServlet来执行。</p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-xml" start="1">
<li class="alt"><span><span class="tag">&lt;?</span><span class="tag-name">xml</span><span>&nbsp;</span><span class="attribute">version</span><span>=</span><span class="attribute-value">"1.0"</span><span>&nbsp;</span><span class="attribute">encoding</span><span>=</span><span class="attribute-value">"UTF-8"</span><span class="tag">?&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span><span class="tag">&lt;</span><span class="tag-name">web-app</span><span>&nbsp;</span><span class="attribute">xmlns:xsi</span><span>=</span><span class="attribute-value">"http://www.w3.org/2001/XMLSchema-instance"</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://java.sun.com/xml/ns/javaee"</span><span>&nbsp;</span><span class="attribute">xmlns:web</span><span>=</span><span class="attribute-value">"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">xsi:schemaLocation</span><span>=</span><span class="attribute-value">"http://java.sun.com/xml/ns/javaee&nbsp;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">id</span><span>=</span><span class="attribute-value">"WebApp_ID"</span><span>&nbsp;</span><span class="attribute">version</span><span>=</span><span class="attribute-value">"2.5"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">display-name</span><span class="tag">&gt;</span><span>testquercus</span><span class="tag">&lt;/</span><span class="tag-name">display-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">welcome-file-list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">welcome-file</span><span class="tag">&gt;</span><span>index.html</span><span class="tag">&lt;/</span><span class="tag-name">welcome-file</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">welcome-file</span><span class="tag">&gt;</span><span>index.php</span><span class="tag">&lt;/</span><span class="tag-name">welcome-file</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">welcome-file-list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>Quercus&nbsp;Servlet</span><span class="tag">&lt;/</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet-class</span><span class="tag">&gt;</span><span>com.caucho.quercus.servlet.QuercusServlet</span><span class="tag">&lt;/</span><span class="tag-name">servlet-class</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">servlet</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>Quercus&nbsp;Servlet</span><span class="tag">&lt;/</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>*.php</span><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">servlet-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp;</span></span></li>
<li class="alt"><span><span class="tag">&lt;/</span><span class="tag-name">web-app</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>所有的php文件放在webapp下，所有的java文件还放到java目录里。</p>
<p>如何混合java到php中?<br />
在java目录新建类Test54Chen，生成后位置：<br />
WEB-INF/classes/com/chen/FrameWork.class</p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-j" start="1">
<li class="alt"><span><span class="comment">/**</span>&nbsp;</span></li>
<li class=""><span><span class="comment">&nbsp;*&nbsp;@author&nbsp;54chen(陈臻)&nbsp;[chenzhen@xiaomi.com&nbsp;czhttp@gmail.com]</span>&nbsp;</span></li>
<li class="alt"><span><span class="comment">&nbsp;*&nbsp;@since&nbsp;2011-10-25&nbsp;下午08:40:49</span>&nbsp;</span></li>
<li class=""><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.chen;&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;</span></li>
<li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;FrameWork&nbsp;{&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;String&nbsp;go(String&nbsp;who)&nbsp;{&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;who&nbsp;+&nbsp;</span><span class="string">"&nbsp;gogogo!"</span><span>;&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
<li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>在webapp新建php文件：<br />
test.php</p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-c" start="1">
<li class="alt"><span><span>&lt;?php&nbsp;&nbsp;</span></span></li>
<li class=""><span>import&nbsp;com.chen.FrameWork;&nbsp;&nbsp;</span></li>
<li class="alt"><span><span class="vars">$f</span><span>&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;FrameWork();&nbsp;&nbsp;</span></span></li>
<li class=""><span>var_dump(<span class="vars">$f</span><span>-&gt;go(</span><span class="string">"ohohoh"</span><span>));&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>?&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>配置到resin中：<br />
目标文件夹指到webapp。</p>
<p>访问：test.php</p>
<p>截图：<br />
1.整个项目的情况<br />
<img src="http://img04.taobaocdn.com/imgextra/i4/T1dG1wXjBcXXa0Lrvb_092913.jpg" alt="quercus" /><br />
2.访问的结果<br />
<img src="http://img01.taobaocdn.com/imgextra/i1/T115OvXmaaXXXqGHYb_092949.jpg" alt="quercus php java" /><br />
下一记：如何利用java做连接池提供给php使用。</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>持续构建工具hudson使用手记</title>
		<link>http://www.54chen.com/java-ee/ci-tool-hudson-usage.html</link>
		<comments>http://www.54chen.com/java-ee/ci-tool-hudson-usage.html#comments</comments>
		<pubDate>Thu, 07 Jul 2011 01:23:53 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[hudson]]></category>

		<guid isPermaLink="false">http://www.54chen.com/java-ee/ci-tool-hudson-usage.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>hudson是一个强大的持续性构建服务器。（现在开发者们分了一个分支，改叫Jenkins。）我（54chen）在使用过程中的手记如下： 下载 地址：http://hudson-ci.org/ wget http://java.net/projects/hudson/downloads/download/war/hudson-2.0.1.war 速度不咋的，60k/s. 先决条件 系统：centos 5.5 resin4下不work，换成了tomcat。 cp /opt/soft/hudson/hudson-2.0.1.war /opt/soft/apache-tomcat-7.0.16/webapps/ 遇到的问题 1）tomcat使用utf8环境。 vim tomcat/conf/server.xml 找到8080，加入一行 URIEncoding="UTF-8"。 2）maven不工作 hudson启动后，系统管理里面，设置maven的地址：MAVEN_HOME指到maven的主目录，不是bin目录。 3）svn不工作 报re_version错误，在你的svn地址的最后面加上@HEAD 4）hudson一切正常后，有svn bug FATAL: tried to access method hudson.scm.ChangeLogSet$Entry.setParent(Lhudson/scm/ChangeLogSet;)V from class hudson.scm.SubversionChangeLogSet 报上面的错误，我（54chen）在http://issues.hudson-ci.org/browse/HUDSON-8885里找到更新新的svn插件即可。进入到系统管理的插件管理中，选中svn 插件，安装更新即可。 5）定时执行 建立job时，有一个选项是Build Triggers，勾选 Build &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://img04.taobaocdn.com/imgextra/i4/T1RgNyXjFsXXXG8Bva_092141.jpg" alt="hudson" /><br />
hudson是一个强大的持续性构建服务器。（现在开发者们分了一个分支，改叫Jenkins。）我（54chen）在使用过程中的手记如下：<br />
<strong>下载</strong><br />
地址：http://hudson-ci.org/</p>
<blockquote><p>wget http://java.net/projects/hudson/downloads/download/war/hudson-2.0.1.war</p></blockquote>
<p>速度不咋的，60k/s.<br />
<strong>先决条件</strong><br />
系统：centos 5.5</p>
<blockquote><p>resin4下不work，换成了tomcat。</p></blockquote>
<blockquote><p> cp /opt/soft/hudson/hudson-2.0.1.war /opt/soft/apache-tomcat-7.0.16/webapps/</p></blockquote>
<p><strong>遇到的问题</strong><br />
1）tomcat使用utf8环境。<br />
 vim tomcat/conf/server.xml<br />
 找到8080，加入一行 URIEncoding="UTF-8"。</p>
<p>2）maven不工作<br />
hudson启动后，系统管理里面，设置maven的地址：MAVEN_HOME指到maven的主目录，不是bin目录。</p>
<p>3）svn不工作<br />
报re_version错误，在你的svn地址的最后面加上@HEAD</p>
<p>4）hudson一切正常后，有svn bug</p>
<blockquote><p>FATAL: tried to access method hudson.scm.ChangeLogSet$Entry.setParent(Lhudson/scm/ChangeLogSet;)V from class hudson.scm.SubversionChangeLogSet
</p></blockquote>
<p>报上面的错误，我（54chen）在http://issues.hudson-ci.org/browse/HUDSON-8885里找到更新新的svn插件即可。进入到系统管理的插件管理中，选中svn 插件，安装更新即可。</p>
<p>5）定时执行<br />
建立job时，有一个选项是Build Triggers，勾选 Build periodically ，schedule填写：0 10,22 * * *表示每天10/22点执行。</p>
<p>6）重启后jobs丢失<br />
jobs都是定义在$HUDSON_HOME里的，如果一开始的时候没有设置，jobs将放在~/.hudson下，当重启的时候，可能发生各种找不到原来的jobs的问题，此时需要确定原来的HUDSON_HOME是啥，现在的是啥，如果不一致就会出问题。</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/java-ee/ci-tool-hudson-usage.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>java log4j 日志分析工具分享</title>
		<link>http://www.54chen.com/java-ee/java-log4j-logger-analyzer.html</link>
		<comments>http://www.54chen.com/java-ee/java-log4j-logger-analyzer.html#comments</comments>
		<pubDate>Fri, 24 Jun 2011 06:26:59 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[analyzer]]></category>
		<category><![CDATA[logger]]></category>

		<guid isPermaLink="false">http://www.54chen.com/java-ee/java-log4j-logger-analyzer.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>java线上项目往往有许多的exception出现了没来得及去看，通过下面的工具，可以在每天早晨上班的时候通过邮件发出头一天出现的异常次数，是提高生产力和提早发现问题的好办法。 配置： 1.解压到指定目录 /data/analyze 2.email发送配置 vim mail.pl 5行，6行，7行，14行 修改为自己的配置 3.server配置 ssh-keygen打通ssh cd server 项目名_server写服务器ip，多个机器一行一个 4.其他 可能会有不相同的log目录地址，看着修改一下shell就行。 *修改自烧饼的脚本，点击下载： http://ishare.iask.sina.com.cn/f/16530420.html<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://img01.taobaocdn.com/imgextra/i1/T1jH1hXjFkXXciRrcW_022533.jpg" alt="log4j,analyzer" /><br />
java线上项目往往有许多的exception出现了没来得及去看，通过下面的工具，可以在每天早晨上班的时候通过邮件发出头一天出现的异常次数，是提高生产力和提早发现问题的好办法。<br />
配置：</p>
<blockquote><p>
1.解压到指定目录<br />
 /data/analyze<br />
2.email发送配置<br />
 vim mail.pl<br />
 5行，6行，7行，14行 修改为自己的配置<br />
3.server配置<br />
 ssh-keygen打通ssh<br />
 cd server<br />
 项目名_server写服务器ip，多个机器一行一个<br />
4.其他<br />
 可能会有不相同的log目录地址，看着修改一下shell就行。
</p></blockquote>
<p>*修改自烧饼的脚本，点击下载：<br />
<a href=" http://ishare.iask.sina.com.cn/f/16530420.html">http://ishare.iask.sina.com.cn/f/16530420.html</a></p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/java-ee/java-log4j-logger-analyzer.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>java实时日志大文件分析</title>
		<link>http://www.54chen.com/java-ee/java-realtime-big-file-tailer.html</link>
		<comments>http://www.54chen.com/java-ee/java-realtime-big-file-tailer.html#comments</comments>
		<pubDate>Tue, 07 Jun 2011 00:16:04 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[realtime]]></category>
		<category><![CDATA[tailer]]></category>

		<guid isPermaLink="false">http://www.54chen.com/java-ee/java-realtime-big-file-tailer.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>日志分析时经常会遇到这个问题：一个正在增长中的大文件，要分析新增的每一行的固定内容进行统计并展示啥的。用java的RandomAccessFile盯住文件的末尾，是一个不错的选择，下面的实现，是一个高效的java tail工具，实现类似linux的tail工具的功能。用来做大日志文件的实时分析，是一个不错的选择。 public class LogFileTailer extends Thread { private Logger logger = LoggerFactory.getLogger(LogFileTailer.class); /** * How frequently to check for file changes; defaults to 5 seconds */ private long sampleInterval = 5000; /** * The log file to tail */ &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://img04.taobaocdn.com/imgextra/i4/T14z9eXa4fXXXUxOU4_053357.jpg" alt="java logger tailer" /><br />
日志分析时经常会遇到这个问题：一个正在增长中的大文件，要分析新增的每一行的固定内容进行统计并展示啥的。用java的RandomAccessFile盯住文件的末尾，是一个不错的选择，下面的实现，是一个高效的java tail工具，实现类似linux的tail工具的功能。用来做大日志文件的实时分析，是一个不错的选择。</p>
<blockquote><p>public class LogFileTailer extends Thread {<br />
    private Logger logger = LoggerFactory.getLogger(LogFileTailer.class);</p>
<p>    /**<br />
     * How frequently to check for file changes; defaults to 5 seconds<br />
     */<br />
    private long sampleInterval = 5000;</p>
<p>    /**<br />
     * The log file to tail<br />
     */<br />
    private File logfile;</p>
<p>    /**<br />
     * Defines whether the log file tailer should include the entire contents of<br />
     * the exising log file or tail from the end of the file when the tailer<br />
     * starts<br />
     */<br />
    private boolean startAtBeginning = false;</p>
<p>    /**<br />
     * Is the tailer currently tailing?<br />
     */<br />
    private boolean tailing = false;</p>
<p>    /**<br />
     * Set of listeners<br />
     */<br />
    private Set listeners = new HashSet();</p>
<p>    /**<br />
     * Creates a new log file tailer that tails an existing file and checks the<br />
     * file for updates every 5000ms<br />
     */<br />
    public LogFileTailer(File file) {<br />
        this.logfile = file;<br />
    }</p>
<p>    /**<br />
     * Creates a new log file tailer<br />
     *<br />
     * @param file The file to tail<br />
     * @param sampleInterval How often to check for updates to the log file<br />
     *            (default = 5000ms)<br />
     * @param startAtBeginning Should the tailer simply tail or should it<br />
     *            process the entire file and continue tailing (true) or simply<br />
     *            start tailing from the end of the file<br />
     */<br />
    public LogFileTailer(File file, long sampleInterval, boolean startAtBeginning) {<br />
        this.logfile = file;<br />
        this.sampleInterval = sampleInterval;<br />
    }</p>
<p>    public void addLogFileTailerListener(LogFileTailerListener l) {<br />
        this.listeners.add(l);<br />
    }</p>
<p>    public void removeLogFileTailerListener(LogFileTailerListener l) {<br />
        this.listeners.remove(l);<br />
    }</p>
<p>    protected void fireNewLogFileLine(String line) {<br />
        for (Iterator i = this.listeners.iterator(); i.hasNext();) {<br />
            LogFileTailerListener l = (LogFileTailerListener) i.next();<br />
            l.newLogFileLine(line);<br />
        }<br />
    }</p>
<p>    public void stopTailing() {<br />
        this.tailing = false;<br />
    }</p>
<p>    public void run() {<br />
        long filePointer = 0;</p>
<p>        if (this.startAtBeginning) {<br />
            filePointer = 0;<br />
        } else {<br />
            filePointer = this.logfile.length();<br />
        }</p>
<p>        try {<br />
            this.tailing = true;<br />
            RandomAccessFile file = new RandomAccessFile(logfile, "r");<br />
            while (this.tailing) {<br />
                long fileLength = this.logfile.length();<br />
                if (fileLength < filePointer) {<br />
                    file = new RandomAccessFile(logfile, "r");<br />
                    filePointer = 0;<br />
                }<br />
                if (fileLength > filePointer) {<br />
                    file.seek(filePointer);<br />
                    String line = file.readLine();<br />
                    while (line != null) {<br />
                        this.fireNewLogFileLine(line);<br />
                        line = file.readLine();<br />
                    }<br />
                    filePointer = file.getFilePointer();<br />
                }<br />
                sleep(this.sampleInterval);<br />
            }<br />
            file.close();<br />
        } catch (IOException e) {<br />
            logger.error("IO ERROR:", e);<br />
        } catch (InterruptedException e) {<br />
            logger.error("InterruptedException:", e);<br />
        }</p>
<p>    }<br />
}</p></blockquote>
<p>使用起来很简单，只需要实现一个LogFileTailerListener后加入到tailer，这个tailer会去自动去执行。</p>
<p>类似：</p>
<blockquote><p>public class Tail implements LogFileTailerListener {<br />
    /**<br />
     * The log file tailer<br />
     */<br />
    private LogFileTailer tailer;</p>
<p>    /**<br />
     * Creates a new Tail instance to follow the specified file<br />
     */<br />
    public Tail(String filename) {<br />
        tailer = new LogFileTailer(new File(filename), 1000, false);<br />
        tailer.addLogFileTailerListener(this);<br />
        tailer.start();<br />
    }</p>
<p>    /**<br />
     * A new line has been added to the tailed log file<br />
     *<br />
     * @param line The new line that has been added to the tailed log file<br />
     */<br />
    public void newLogFileLine(String line) {<br />
        System.out.println(line);<br />
    }</p>
<p>  /**<br />
     * Command-line launcher<br />
     */<br />
    public static void main(String[] args) {<br />
        if (args.length < 1) {<br />
            System.out.println("Usage: Tail <filename>");<br />
            System.exit(0);<br />
        }<br />
        Tail tail = new Tail(args[0]);<br />
    }<br />
}</p></blockquote>
<p>上面的代码出处：http://www.informit.com/guides/content.aspx?g=java&#038;seqNum=226，我(54chen)对其进行了一些修改，保障出现异常时不会出现死循环。</p>
<p>下载修改后的可用的代码：<br />
<a href="http://ishare.iask.sina.com.cn/f/15999043.html">http://ishare.iask.sina.com.cn/f/15999043.html</a></p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/java-ee/java-realtime-big-file-tailer.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>改写java TreeMap制造方便查询的ip内存库</title>
		<link>http://www.54chen.com/java-ee/chang-java-treemap-store-ip.html</link>
		<comments>http://www.54chen.com/java-ee/chang-java-treemap-store-ip.html#comments</comments>
		<pubDate>Mon, 30 May 2011 02:00:21 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[ip]]></category>
		<category><![CDATA[mem]]></category>

		<guid isPermaLink="false">http://www.54chen.com/java-ee/chang-java-treemap-store-ip.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>国库流行的ip库记录数大约在6万条左右，数据格式大约都是如下： start,end,country... 要查询的时候都是放到mysql里去，然后select * from ip where start&#62;=xx and end end &#60;=xx来得到ip信息，我（54chen）在搞一个实时监控时，因为并发量非常大，全部查询IP库，需要好几万每秒的查询，特改了java的TreeMap的get方法，将所有数据放到内存里来操作，put的时候还是保持TreeMap的红黑树实现，以start作为key，而在get的时候有一个 compare的过程，在发现compare是大于0的时候进行如下修改： else if (cmp &#62; 0) { int start = ((Data) p.value).getStart(); int end = ((Data) p.value).getEnd(); int intKey = Integer.parseInt(k.toString()); if (intKey &#62;= start &#38;&#38; intKey &#60;= &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://img04.taobaocdn.com/imgextra/i4/T1AhydXlJnXXcZ9h76_061839.jpg" alt="ip" /></p>
<p>国库流行的ip库记录数大约在6万条左右，数据格式大约都是如下：<br />
start,end,country...<br />
要查询的时候都是放到mysql里去，然后select * from ip where start&gt;=xx and end end &lt;=xx来得到ip信息，我（54chen）在搞一个实时监控时，因为并发量非常大，全部查询IP库，需要好几万每秒的查询，特改了java的TreeMap的get方法，将所有数据放到内存里来操作，put的时候还是保持TreeMap的红黑树实现，以start作为key，而在get的时候有一个 compare的过程，在发现compare是大于0的时候进行如下修改：</p>
<blockquote><p>else if (cmp &gt; 0) {<br />
int start = ((Data) p.value).getStart();<br />
int end = ((Data) p.value).getEnd();<br />
int intKey = Integer.parseInt(k.toString());<br />
if (intKey &gt;= start &amp;&amp; intKey &lt;= end) {<br />
return p;<br />
}<br />
p = p.right;<br />
}</p></blockquote>
<p>大概意思是：在树上遇到比要找的数据小的节点时，从数据中取到end的大小，来参加对比，如果满足要求，直接返回。</p>
<p>附修改好的代码：<br />
<a href="http://ishare.iask.sina.com.cn/f/15805095.html">http://ishare.iask.sina.com.cn/f/15805095.html</a></p>
<p><strong>重要补充：</strong></p>
<p>由qunar的sunli大侠补充，用实现comparable的key用法更加正宗，代码如下：</p>
<blockquote><p>public class Chen {<br />
public static void main(String[] args) {</p>
<p>java.util.TreeMap&lt;IpEntry, Data&gt; xmap = new  java.util.TreeMap&lt;IpEntry, Data&gt;();<br />
xmap.put(new IpEntry(0, 100), genData(0, 100, "中国"));<br />
xmap.put(new IpEntry(101, 200), genData(101, 200, "日本"));<br />
xmap.put(new IpEntry(2000, 3000), genData(2000, 3000, "美国"));<br />
xmap.put(new IpEntry(201, 300), genData(201, 300, "巴西"));<br />
xmap.put(new IpEntry(501, 600), genData(501, 600, "法国"));<br />
xmap.put(new IpEntry(701, 800), genData(701, 800, "英国"));<br />
xmap.put(new IpEntry(601, 700), genData(601, 700, "北京"));<br />
xmap.put(new IpEntry(1601, 1700), genData(1601, 1700, "广州"));</p>
<p>Data data = xmap.get(new IpEntry(1260, 1260));<br />
if (data == null) {<br />
System.out.println("not found!");<br />
} else {<br />
System.out.println(data.getCountry());<br />
}<br />
}</p>
<p>private static class IpEntry implements Comparable&lt;IpEntry&gt; {</p>
<p>final long start;<br />
final long end;</p>
<p>IpEntry(long start, long end) {<br />
this.start = start;<br />
this.end = end;<br />
}</p>
<p>public int compareTo(IpEntry t) {<br />
long t1 = start - t.start;<br />
if (t1 &lt; 0) {<br />
return -1;<br />
}<br />
long t2 = end - t.end;<br />
if (t1 &gt;= 0 &amp;&amp; t2 &lt;= 0) {<br />
return 0;<br />
}<br />
return 1;<br />
}</p>
<p>}</p>
<p>private static Data genData(int start, int end, String country) {<br />
Data data = new Data();<br />
data.setCountry(country);<br />
data.setStart(start);<br />
data.setEnd(end);<br />
return data;<br />
}<br />
}</p></blockquote>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/java-ee/chang-java-treemap-store-ip.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>maven项目代码质量检测工具sonar使用手记</title>
		<link>http://www.54chen.com/java-ee/open-source-quality-management-platform-sonar-notes.html</link>
		<comments>http://www.54chen.com/java-ee/open-source-quality-management-platform-sonar-notes.html#comments</comments>
		<pubDate>Wed, 23 Mar 2011 05:40:14 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[sonar]]></category>

		<guid isPermaLink="false">http://www.54chen.com/java-ee/open-source-quality-management-platform-sonar-notes.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>Sonar是一个开源代码质量控制工具。把它加到现在的持续集成工具中就能够让你的java开发项目集中处于质量控制之下。下面是安装和使用记录 ： 修改.m2/settings.xml 增加下边的内容到profiles段落中： &#60;profile&#62; &#60;id&#62;sonar&#60;/id&#62; &#60;activation&#62; &#60;activeByDefault&#62;true&#60;/activeByDefault&#62; &#60;/activation&#62; &#60;properties&#62; &#60;!-- EXAMPLE FOR MYSQL --&#62; &#60;sonar.jdbc.url&#62; jdbc:mysql://localhost:3306/sonar?useUnicode=true&#38;amp;characterEncoding=utf8 &#60;/sonar.jdbc.url&#62; &#60;sonar.jdbc.driverClassName&#62;com.mysql.jdbc.Driver&#60;/sonar.jdbc.driverClassName&#62; &#60;sonar.jdbc.username&#62;sonar&#60;/sonar.jdbc.username&#62; &#60;sonar.jdbc.password&#62;sonar&#60;/sonar.jdbc.password&#62; &#60;!-- SERVER ON A REMOTE HOST --&#62; &#60;sonar.host.url&#62;http://localhost:8888&#60;/sonar.host.url&#62; &#60;/properties&#62; &#60;/profile&#62; 增加mysql权限 GRANT all ON sonar.* TO sonar@localhost IDENTIFIED BY &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://img02.taobaocdn.com/imgextra/i2/T1o7d4XgVmXXa0tYUU_013741.jpg" alt="sonar" /></p>
<p>Sonar是一个开源代码质量控制工具。把它加到现在的持续集成工具中就能够让你的java开发项目集中处于质量控制之下。下面是安装和使用记录 ：</p>
<p><strong>修改.m2/settings.xml</strong><br />
增加下边的内容到profiles段落中：</p>
<blockquote><p>&lt;profile&gt;<br />
&lt;id&gt;sonar&lt;/id&gt;<br />
&lt;activation&gt;<br />
&lt;activeByDefault&gt;true&lt;/activeByDefault&gt;<br />
&lt;/activation&gt;<br />
&lt;properties&gt;<br />
&lt;!-- EXAMPLE FOR MYSQL --&gt;<br />
&lt;sonar.jdbc.url&gt;<br />
jdbc:mysql://localhost:3306/sonar?useUnicode=true&amp;amp;characterEncoding=utf8<br />
&lt;/sonar.jdbc.url&gt;<br />
&lt;sonar.jdbc.driverClassName&gt;com.mysql.jdbc.Driver&lt;/sonar.jdbc.driverClassName&gt;<br />
&lt;sonar.jdbc.username&gt;sonar&lt;/sonar.jdbc.username&gt;<br />
&lt;sonar.jdbc.password&gt;sonar&lt;/sonar.jdbc.password&gt;</p>
<p>&lt;!-- SERVER ON A REMOTE HOST --&gt;<br />
&lt;sonar.host.url&gt;http://localhost:8888&lt;/sonar.host.url&gt;<br />
&lt;/properties&gt;<br />
&lt;/profile&gt;</p></blockquote>
<p><strong>增加mysql权限 </strong><br />
GRANT all ON sonar.* TO sonar@localhost IDENTIFIED BY 'sonar';<br />
FLUSH PRIVILEGES ;</p>
<p><strong>vim .bashrc</strong><br />
export MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=128m -Duser.timezone=Asia/Shanghai"</p>
<p>source .bashrc</p>
<p><strong>下载sonar，配置mysql:</strong></p>
<blockquote><p>conf/sonar.properties<br />
sonar.jdbc.url: jdbc:mysql://localhost:3306/sonar?useUnicode=true&amp;characterEncoding=utf8<br />
sonar.jdbc.driverClassName: com.mysql.jdbc.Driver<br />
sonar.jdbc.validationQuery: select 1</p></blockquote>
<p>用户密码不用，默认都是sonar</p>
<p><strong>配置启动的http端口</strong></p>
<blockquote><p>sonar.web.host : localhost<br />
sonar.web.port: 8888<br />
sonar.web.context: /</p></blockquote>
<p><strong>启动服务：</strong></p>
<blockquote><p>bin/[YOUR PLATEFORM]/sonar.sh start</p></blockquote>
<p><strong>开始使用：</strong></p>
<blockquote><p>进到项目里运行 mvn sonar:sonar</p>
<p>打开http://localhost:8888 即可看到对应项目里的代码质量和修改建议。</p></blockquote>
<p><strong>解决系统时区的问题：</strong><br />
vim sonar-xx/conf/wrapper.conf<br />
wrapper.java.additional.3=-Duser.timezone=Asia/Shanghai</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/java-ee/open-source-quality-management-platform-sonar-notes.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>关于maven，做错的十件事</title>
		<link>http://www.54chen.com/java-ee/about-maven-10-wrong-things.html</link>
		<comments>http://www.54chen.com/java-ee/about-maven-10-wrong-things.html#comments</comments>
		<pubDate>Tue, 15 Mar 2011 09:10:58 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://www.54chen.com/java-ee/about-maven-10-wrong-things.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>maven管理的java项目越来越多，令人遗憾的是在使用maven的时候，多多少少都会遇到这样那样的问题，于是会有各种各样的解决办法，下面是一个列表，列出了使用maven的误区和解决办法。 1.频繁在所有项目使用mvn install并且随时在更新 这是我见过的最常见的问题，解决了这个问题有许多的好处。在maven的文档中找不到一句对这种情况的描述，不过我坚信一句话：每个artifact在maven仓库中都有一个家。 在你的公司里，应该有一个仓库管理工具。每一个你开发的模块都应该发布到这个仓库上去。你可能会问，应该什么时候发布？答案是，每次在你的构建服务器构建之后，都需要发到仓库。我们通常都使用Hudson来做这件事情，另外还有Continuum和TeamCity也还不错。 现在，当你所有的项目都在仓库里有的时候，你的项目就不再需要不断地mvn install了。如果你修改一个模块，你只需要重建这个模块，其余依赖的模块会由maven自动从仓库中下载。 2.你和你的团队成员依靠复制.m2文件夹来解决项目里的依赖找不到的问题 这看起来很疯狂，不过这件事情经常发生。解决的办法，设置一名仓库管理员。一旦管理好了仓库，就不会再出现大家找u盘复制.m2文件夹的事情了。因为可以加速，你不应该把本地的仓库整个地删除掉，毕竟在本地读取仓库是最快的。 3. 你为了解决依赖找不到一个老版本构件的问题，把最新的pom文件修改了版本弄到了老文件里后安装 考虑到这种情况，有人把一个模块的版本从1.3-SNAPSHOT修改成了1.4-SNAPSHOT。你马上要去度假，所以呢你就不想再更新和安装1.3的版本了，而你的模块正好要依赖1.3版本的那个模块，你如何去弄到老的版本呢？嗯，你可以到处找找，在代码库里找到了这个模块的最新代码，而且版本还是1.3的，你更新了这个版本号并且进行了安装。或者你还可以把你的代码从1.4弄到1.3去，安装并祈祷能够正常工作。 我想上面的解决办法都不是很好，同样，你的公司需要一个代码仓库管理员，如果有一次1.3-SNAPSHOT成功的构建，那就应该在仓库里存在一份，问题解决。 4. 你有许多shell脚本或者是批处理文件，它们通过你的模块的target文件来产生一个zip文件 maven有方法专门做这件事情，叫做“assemblies”。他们不是最容易安装的，但是一旦你安装好了，将与maven完全无缝结合，这要比许多山寨自制的脚本要平滑得多。这些山寨的脚本有许多的问题，比如说版本开始改变，模块被移动等等。 5.你有许多的xml在pom里，目的只是复制文件到发布时的文件夹去，而且它不成很好的工作，也不轻便 这和4正好是对立的，maven看上去不是为了复制文件而构建。如果你想复制你的包（诸如war,ear,zip文件），写一个ant shell bat文件都会很简单完成。 6.你在build的时候总是呆在“checking for updates from xxx-repo”而你不知道什么原因 这是一个很让有些人很气愤的事情，往往花费太多时间去找问题所在。也许这个事情正好可以让你去喝杯咖啡。尽管如此，这个问题的一些通常原因，就是你有一个快照版本的依赖，并且在你的pom文件中有一堆的仓库列表。maven不关心哪个包去哪个仓库里取，所以看上去是从所有的仓库里更新所有的包。 如果你配置了你的maven安装时到指定的仓库里去寻找所有的包（在settings.xml里设置mirror），maven会只到这个仓库里寻找。当这个服务器在本地，将得到加速。用上仓库管理很重要， 7.如果你在release分支上写代码，你的trunk的构建将会失败（或者说是1.0-SNAPSHOT应该对所有人来说都是好用的） 有许多事情你应该记住，当给你的项目创建一个分枝的时候。其中之一是告诉你的构建服务器，并且其他模块需要修改版本为你的pom的声明。如果你忽略随后才做这事，当你想修改了分支里的代码又想在主干里开发时，你会遇到问题。 这里有一个goal在发布插件里，叫做“branch”，靠运行“mvn release:branch”，maven可以为你自动重命名pom文件里的版本号。（免责声明，我还没试过这个命令。。。目前我经常只在创建了一个release的时候才打分支，在“mvn release:perform”后使用“mvn release:prepare”） 8.整个公司内容的依赖都是以-SNAPSHOT结束 快照对开发者来说很舒服，它几乎要完成了，但是迟早，你应该要停下你的脚步，发送你的包给世人，或者是你的同事。一直呆在快照版本有许多的问题。首先它减慢了你的构建速度。因为maven不得不去检查最后的快照是不是在更新了。其次，如果你的项目依赖于一个快照版本，你很难判断是依赖哪个版本的快照。构建可能会失败，只是因为你拿到了一个更新的快照。 如果你依赖一个公司内部的模块，并且这个模块目前是好用的，那么修改所有的依赖为非快照版本后才发布，是一个不错的主意。这样我们才能知道，即使有家伙还在那个模块上疯狂写代码的时候，你的模块依旧可以构建通过，因为它依赖的是一个稳定的发布。 9.跑一下“mvn dependency:analyze”，没有使用和没有使用的依赖列表很长 这个很BT，但不知道准确依赖很危险。最大的问题是maven的传递依赖。 10.当有人发布了你使用的新版本的插件，你的构建就挂了 &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://img03.taobaocdn.com/imgextra/i3/T13gR3Xa4cXXcFX9c3_050845.jpg" alt="java maven" /></p>
<p>maven管理的java项目越来越多，令人遗憾的是在使用maven的时候，多多少少都会遇到这样那样的问题，于是会有各种各样的解决办法，下面是一个列表，列出了使用maven的误区和解决办法。<br />
<strong>1.频繁在所有项目使用mvn install并且随时在更新</strong><br />
这是我见过的最常见的问题，解决了这个问题有许多的好处。在maven的文档中找不到一句对这种情况的描述，不过我坚信一句话：每个artifact在maven仓库中都有一个家。<br />
在你的公司里，应该有一个仓库管理工具。每一个你开发的模块都应该发布到这个仓库上去。你可能会问，应该什么时候发布？答案是，每次在你的构建服务器构建之后，都需要发到仓库。我们通常都使用<a href="https://hudson.dev.java.net/">Hudson</a>来做这件事情，另外还有<a href="http://continuum.apache.org/">Continuum</a>和<a href="http://www.jetbrains.com/teamcity/">TeamCity</a>也还不错。</p>
<p>现在，当你所有的项目都在仓库里有的时候，你的项目就不再需要不断地mvn install了。如果你修改一个模块，你只需要重建这个模块，其余依赖的模块会由maven自动从仓库中下载。</p>
<p><strong>2.你和你的团队成员依靠复制.m2文件夹来解决项目里的依赖找不到的问题</strong><br />
这看起来很疯狂，不过这件事情经常发生。解决的办法，设置一名仓库管理员。一旦管理好了仓库，就不会再出现大家找u盘复制.m2文件夹的事情了。因为可以加速，你不应该把本地的仓库整个地删除掉，毕竟在本地读取仓库是最快的。</p>
<p><strong>3. 你为了解决依赖找不到一个老版本构件的问题，把最新的pom文件修改了版本弄到了老文件里后安装</strong><br />
考虑到这种情况，有人把一个模块的版本从1.3-SNAPSHOT修改成了1.4-SNAPSHOT。你马上要去度假，所以呢你就不想再更新和安装1.3的版本了，而你的模块正好要依赖1.3版本的那个模块，你如何去弄到老的版本呢？嗯，你可以到处找找，在代码库里找到了这个模块的最新代码，而且版本还是1.3的，你更新了这个版本号并且进行了安装。或者你还可以把你的代码从1.4弄到1.3去，安装并祈祷能够正常工作。</p>
<p>我想上面的解决办法都不是很好，同样，你的公司需要一个代码仓库管理员，如果有一次1.3-SNAPSHOT成功的构建，那就应该在仓库里存在一份，问题解决。</p>
<p><strong>4. 你有许多shell脚本或者是批处理文件，它们通过你的模块的target文件来产生一个zip文件</strong><br />
maven有方法专门做这件事情，叫做“assemblies”。他们不是最容易安装的，但是一旦你安装好了，将与maven完全无缝结合，这要比许多山寨自制的脚本要平滑得多。这些山寨的脚本有许多的问题，比如说版本开始改变，模块被移动等等。</p>
<p><strong>5.你有许多的xml在pom里，目的只是复制文件到发布时的文件夹去，而且它不成很好的工作，也不轻便</strong><br />
这和4正好是对立的，maven看上去不是为了复制文件而构建。如果你想复制你的包（诸如war,ear,zip文件），写一个ant shell bat文件都会很简单完成。</p>
<p><strong>6.你在build的时候总是呆在“checking for updates from xxx-repo”而你不知道什么原因</strong><br />
这是一个很让有些人很气愤的事情，往往花费太多时间去找问题所在。也许这个事情正好可以让你去喝杯咖啡。尽管如此，这个问题的一些通常原因，就是你有一个快照版本的依赖，并且在你的pom文件中有一堆的仓库列表。maven不关心哪个包去哪个仓库里取，所以看上去是从所有的仓库里更新所有的包。<br />
如果你配置了你的maven安装时到指定的仓库里去寻找所有的包（在settings.xml里设置mirror），maven会只到这个仓库里寻找。当这个服务器在本地，将得到加速。用上仓库管理很重要，</p>
<p><strong>7.如果你在release分支上写代码，你的trunk的构建将会失败（或者说是1.0-SNAPSHOT应该对所有人来说都是好用的）</strong><br />
有许多事情你应该记住，当给你的项目创建一个分枝的时候。其中之一是告诉你的构建服务器，并且其他模块需要修改版本为你的pom的声明。如果你忽略随后才做这事，当你想修改了分支里的代码又想在主干里开发时，你会遇到问题。<br />
这里有一个goal在发布插件里，叫做“branch”，靠运行“mvn release:branch”，maven可以为你自动重命名pom文件里的版本号。（免责声明，我还没试过这个命令。。。目前我经常只在创建了一个release的时候才打分支，在“mvn release:perform”后使用“mvn release:prepare”）</p>
<p><strong>8.整个公司内容的依赖都是以-SNAPSHOT结束</strong><br />
快照对开发者来说很舒服，它几乎要完成了，但是迟早，你应该要停下你的脚步，发送你的包给世人，或者是你的同事。一直呆在快照版本有许多的问题。首先它减慢了你的构建速度。因为maven不得不去检查最后的快照是不是在更新了。其次，如果你的项目依赖于一个快照版本，你很难判断是依赖哪个版本的快照。构建可能会失败，只是因为你拿到了一个更新的快照。<br />
如果你依赖一个公司内部的模块，并且这个模块目前是好用的，那么修改所有的依赖为非快照版本后才发布，是一个不错的主意。这样我们才能知道，即使有家伙还在那个模块上疯狂写代码的时候，你的模块依旧可以构建通过，因为它依赖的是一个稳定的发布。</p>
<p><strong>9.跑一下“mvn dependency:analyze”，没有使用和没有使用的依赖列表很长</strong><br />
这个很BT，但不知道准确依赖很危险。最大的问题是maven的传递依赖。</p>
<p><strong>10.当有人发布了你使用的新版本的插件，你的构建就挂了</strong><br />
maven的插件不必写上版本，maven会找到最好的版本。当有新版本的插件的时候，你不必知道就会下载使用最新的。有时候，最好的判断不总是正确。根据经验，越新的越有bug。因此，明码标价写上你使用的插件的版本是有意义的</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/java-ee/about-maven-10-wrong-things.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>分布式日志系统scribe使用手记</title>
		<link>http://www.54chen.com/java-ee/log-server-scribe-helper.html</link>
		<comments>http://www.54chen.com/java-ee/log-server-scribe-helper.html#comments</comments>
		<pubDate>Thu, 24 Feb 2011 03:29:18 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[架构研究]]></category>
		<category><![CDATA[scribe]]></category>

		<guid isPermaLink="false">http://www.54chen.com/java-ee/log-server-scribe-helper.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>scribe 是facebook 开源的分布式日志系统 。其使用了thrift传输log，由于使用thrift，所以不论是什么语言的项目都可以实现日志收集，可达到远程或者是本地同步远程的分布式日志收集效果，在其示例配置中，并发量可达到max_msg_per_second=2000000，对普通的应用来说，每秒上百万的访问量可能性很小，因此基本上即使最简单的配置，远程收集所有项目的log也是可靠的，如果压力大的话，可以采取主从的配置，将日志打到本地后由scribe的主从配置来自动同步。下面讲述如何安装和使用scribe。 下载boost、thrift、scribe boost_1_45_0.tar.gz thrift-0.5.0.tar.gz facebook-scribe-2ee14d3.zip 通过yum安装需要的依赖 yum install libevent libevent-devel python-devel yum install gcc-c++ yum install automake yum install byacc flex 安装boost tar -zxvf boost_1_45_0.tar.gz cd boost_1_45_0 ./bootstrap.sh ./bjam install --prefix=/opt/soft/bootstrap 安装thrift-0.5.0 tar zxvf thrift-0.5.0.tar.gz ./configure --with-php-config=/opt/soft/php/bin/php-config &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://img02.taobaocdn.com/imgextra/i2/T1a5J6XmhtXXbWyPE9_103845.jpg" alt="java,scribe" width=400/><br />
scribe 是facebook 开源的分布式日志系统 。其使用了thrift传输log，由于使用thrift，所以不论是什么语言的项目都可以实现日志收集，可达到远程或者是本地同步远程的分布式日志收集效果，在其示例配置中，并发量可达到max_msg_per_second=2000000，对普通的应用来说，每秒上百万的访问量可能性很小，因此基本上即使最简单的配置，远程收集所有项目的log也是可靠的，如果压力大的话，可以采取主从的配置，将日志打到本地后由scribe的主从配置来自动同步。下面讲述如何安装和使用scribe。</p>
<p><strong>下载boost、thrift、scribe</strong></p>
<blockquote><p>boost_1_45_0.tar.gz<br />
thrift-0.5.0.tar.gz<br />
facebook-scribe-2ee14d3.zip</p></blockquote>
<p><strong>通过yum安装需要的依赖</strong></p>
<blockquote><p>yum install libevent libevent-devel python-devel<br />
yum install gcc-c++<br />
yum install automake<br />
yum install byacc flex
</p></blockquote>
<p><strong>安装boost</strong></p>
<blockquote><p>tar -zxvf boost_1_45_0.tar.gz<br />
cd boost_1_45_0<br />
./bootstrap.sh<br />
./bjam install --prefix=/opt/soft/bootstrap</p></blockquote>
<p><strong>安装thrift-0.5.0</strong></p>
<blockquote><p>tar zxvf thrift-0.5.0.tar.gz<br />
./configure --with-php-config=/opt/soft/php/bin/php-config  --with-boost=/opt/soft/boost/ --with-java --prefix=/opt/soft/thrift<br />
make<br />
make install</p></blockquote>
<p><strong>安装fb303</strong></p>
<blockquote><p>cd contrib/fb303<br />
./bootstrap.sh --prefix=/opt/soft/thrift/fb303 --with-boost=/opt/soft/boost/ --with-thriftpath=/opt/soft/thrift/<br />
make<br />
make install</p></blockquote>
<p><strong>安装scribe</strong></p>
<blockquote><p>unzip facebook-scribe-2ee14d3.zip<br />
cd facebook-scribe-2ee14d3</p>
<p>export BOOST_ROOT=/opt/soft/boost/<br />
export LD_LIBRARY_PATH=/opt/soft/thrift/lib:/usr/lib:/usr/local/lib:/opt/soft/boost/lib/<br />
./bootstrap.sh --prefix=/opt/soft/scribe --with-boost=/opt/soft/boost/ --with-thriftpath=/opt/soft/thrift/<br />
make<br />
make install</p></blockquote>
<p><strong>启动scribe服务</strong></p>
<blockquote><p>cd facebook-scribe-2ee14d3<br />
cp example/exmaple1.conf /opt/soft/scribe/bin<br />
cd /opt/soft/scribe/bin/<br />
export BOOST_ROOT=/opt/soft/boost/<br />
export LD_LIBRARY_PATH=/opt/soft/thrift/lib:/usr/lib:/usr/local/lib:/opt/soft/boost/lib/<br />
./scibed example1.conf</p></blockquote>
<p><strong>生成客户端使用scribe</strong></p>
<blockquote><p>先产生java的thrift代码:<br />
cd facebook-scribe-2ee14d3/if/<br />
thrift -r -I ../../thrift-0.5.0/contrib/（这里需要指到你的thrift的源码目录） -gen java scribe.thrift</p></blockquote>
<p><strong>使用</strong></p>
<blockquote><p>gen-java目录下有thrift的客户端，即取即用。javaeye里有一篇写配置log4j使用scribe的不错：http://www.javaeye.com/topic/800208</p></blockquote>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/java-ee/log-server-scribe-helper.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>[java]如何优雅读取properties文件-part2</title>
		<link>http://www.54chen.com/java-ee/java-read-properties-files-part2.html</link>
		<comments>http://www.54chen.com/java-ee/java-read-properties-files-part2.html#comments</comments>
		<pubDate>Tue, 25 Jan 2011 08:25:09 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[properties]]></category>

		<guid isPermaLink="false">http://www.54chen.com/java-ee/java-read-properties-files-part2.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>接上part1:http://www.54chen.com/java-ee/java-read-properties-files-part.html 从数据流到java.util.Properties 你应该注意到之前提过的方法只是一半的措施：他们都只返回输入数据流，而并没有类似键值对的返回。幸运的是，把数据加载成一个列表很简单（可以实例化java.util.Properties即可）。因为你会发现你在一再地使用它，搞成几个帮助类是有意义的。 java的内置方法给classpath加载指定的资源有小小的不同也是一件讨厌的事情，特别是当一些资源名字是硬编码但你现在想换另一个加载的方法时。抽取出来一些东西是有意义的，类似斜杠和点作为命名的分隔符等等。干脆一点，帖出我的properties的处理类，代码在这里下载：http://www.javaworld.com/javaqa/2003-08/01-qa-0808-property.html?page=2#resources ［代码略］ 在loadProperties方法的javadoc里的注释显示这个方法的输入参数要求非常随意：接受资源名字被任何按照原生的方法设计（除了相关的包外尽量使用Class.getResourceAsStream()）的格式化而且使其本地实现标准化。 短一点的loadProperties() 公用方法决定了哪个类加载器加载资源。下面的解决方法是合理的但并非完美。你应该考虑使用文章"Find a Way Out of the ClassLoader Maze"里提到的技术来代替。 注意有两个条件编译的常量来控制loadProperties的行为，你可以调整它们来适应你的口味： THROW_ON_LOAD_FAILURE选择loadProperties在找不到资源的情况下是抛异常还是返回空。 LOAD_AS_RESOURCE_BUNDLE 选择资源在查找的时候是绑定资源还是给出的classpath资源。 将LOAD_AS_RESOURCE_BUNDLE设置为true是不好的，除非你是想通过编译到java.util.ResourceBundle的本地化支持得到好处。而且，java内部缓存了资源绑定，所以你可以避免重复地对同样的资源名字进行磁盘文件读写。 更多的事情 我有意省略了一个有趣的classpath资源加载方法，ClassLoader.getResources。尽管它不常使用，但其允许许多有用的选项，这些选项在设计高度定制和简单配置的应用程序非常有用。 我没有在这文章里讨论ClassLoader.getResources是因为它值得专门写一篇文章。碰巧，这个方法与剩下的取得资源的方法联系紧密：Java.net.URLs。你可以使用他们，因为资源描述符要比classpath资源名字符要更通用。<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://www.oracle.com/technetwork/java/javaspotlight-189455.png" alt="java properties" /><br />
接上part1:<a href="http://www.54chen.com/java-ee/java-read-properties-files-part.html">http://www.54chen.com/java-ee/java-read-properties-files-part.html</a><br />
<strong>从数据流到java.util.Properties</strong><br />
你应该注意到之前提过的方法只是一半的措施：他们都只返回输入数据流，而并没有类似键值对的返回。幸运的是，把数据加载成一个列表很简单（可以实例化java.util.Properties即可）。因为你会发现你在一再地使用它，搞成几个帮助类是有意义的。</p>
<p>java的内置方法给classpath加载指定的资源有小小的不同也是一件讨厌的事情，特别是当一些资源名字是硬编码但你现在想换另一个加载的方法时。抽取出来一些东西是有意义的，类似斜杠和点作为命名的分隔符等等。干脆一点，帖出我的properties的处理类，代码在这里下载：http://www.javaworld.com/javaqa/2003-08/01-qa-0808-property.html?page=2#resources</p>
<p>［代码略］</p>
<p>在loadProperties方法的javadoc里的注释显示这个方法的输入参数要求非常随意：接受资源名字被任何按照原生的方法设计（除了相关的包外尽量使用Class.getResourceAsStream()）的格式化而且使其本地实现标准化。</p>
<p>短一点的loadProperties() 公用方法决定了哪个类加载器加载资源。下面的解决方法是合理的但并非完美。你应该考虑使用文章"<a href="http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html">Find  a Way Out of the ClassLoader Maze</a>"里提到的技术来代替。</p>
<p>注意有两个条件编译的常量来控制loadProperties的行为，你可以调整它们来适应你的口味：</p>
<p>THROW_ON_LOAD_FAILURE选择loadProperties在找不到资源的情况下是抛异常还是返回空。</p>
<p>LOAD_AS_RESOURCE_BUNDLE 选择资源在查找的时候是绑定资源还是给出的classpath资源。</p>
<p>将LOAD_AS_RESOURCE_BUNDLE设置为true是不好的，除非你是想通过编译到java.util.ResourceBundle的本地化支持得到好处。而且，java内部缓存了资源绑定，所以你可以避免重复地对同样的资源名字进行磁盘文件读写。</p>
<p><strong>更多的事情</strong></p>
<p>我有意省略了一个有趣的classpath资源加载方法，ClassLoader.getResources。尽管它不常使用，但其允许许多有用的选项，这些选项在设计高度定制和简单配置的应用程序非常有用。</p>
<p>我没有在这文章里讨论ClassLoader.getResources是因为它值得专门写一篇文章。碰巧，这个方法与剩下的取得资源的方法联系紧密：Java.net.URLs。你可以使用他们，因为资源描述符要比classpath资源名字符要更通用。</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/java-ee/java-read-properties-files-part2.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

