使用JRockit JVM运行eclipse


来源:Running Eclipse on JRockit JVM

Oracle收购Sun之后,曾有媒体爆出Oracle考虑整合Sun JVM和JRockit JVM,要知道JRockit JVM也不是Oracle自己开发的,来自于之前的BEA公司。其实作为开发人员,真心希望两个JVM整合,以提供更好的性能。最近就在折腾把eclipse以及tomcat的开发环境从Sun JVM切换到JRockit JVM。

虽然JRockit JVM是着眼与服务器端的高性能JVM,但是也能运行客户端程序,像eclipse就能在JRockit JVM上很好的运行。

一、最简单的配置方法

-showsplash
org.eclipse.platform
-vm
/opt/Oracle/jrockit-jdk1.6.0_22-R28.1.1-4.0.1/bin/java

二、指定堆内存大小

-showsplash
org.eclipse.platform
-vm
/opt/Oracle/jrockit-jdk1.6.0_22-R28.1.1-4.0.1/bin/java
-vmargs -Xms384m -Xmx384m

三、配置deterministic GC,提高响应速度

-showsplash
org.eclipse.platform
-vm
/opt/Oracle/jrockit-jdk1.6.0_22-R28.1.1-4.0.1/bin/java
-vmargs
-Xms384m
-Xmx384m
-XgcPrio:deterministic
-XpauseTarget:20
-XXcompactratio:1

安装完成后,从主观感受上来看,eclipse响应速度确实快了不少。客观上,使用384内存出来的效果和Sun JVM服务器模式运行512内存出来的效果一样,也就是说相比调整后Sun JVM(Eclipse JVM 性能调优),内存占用有所降低。

此外,JRockit JVM还提供了Mission Control for eclipse插件,可以在eclipse通过Mission Control perspective视图分析JVM工作情况。这个插件的安装方法也很简单。找到安装目录下的missioncontrol目录,将里面的featrues和plugins文件夹复制到eclipse中即可。

对于tomcat,我们在Server Runtime Environment中选择jrockit jvm即可实现使用jrockit jvm运行tomcat,启动速度那是飕飕的!!!有木有!!!

资源:
Oracle JRockit Online Documentation

Advertisements

跟踪 c3p0 连接池连接泄漏


最近的项目碰到了连接泄漏的问题。 项目用的是Spring + Hibernate + c3p0,具体表现为,系统运行一段时间后,用户打开登录页后,执行登录无响应,查看后台日志,提示Could not open Connection。将c3p0日志级别调成debug之后,发现c3p0报告连接数已经达到设置的上限。 之前检查连接泄漏时,使用的是极低效的办法,目测代码,所以问题解决起来颇费周折,效果还不好。 今天查了一下c3p0官方手册,c3p0官方提供了两个参数,能够很方便的检查没有正确返回连接池的连接。

debugUnreturnedConnectionStackTraces
默认为false,如果此参数设置为true,当所有连接用完的时候,会以堆栈信息显示哪些代码使用了连接。由于跟踪连接状态会产生额外的消耗,如果程序稳定,应该将此参数恢复为默认值false。

unreturnedConnectionTimeout
设置连接被checkout后,经过多长时间还未返还连接池,则连接缓冲池直接Kill该连接,此时,结合debugUnretrunedConnectionStackTraces,我们可以知道是什么程序持有了连接,并且没有返回。这个方法很暴力,有可能造成应用程序不稳定,所以,如果真的出现了连接泄漏,一时半会又找不到问题点所在,可以暂时使用这个方法让应用程序跑起来。

参考:c3p0官方手册

Element type “nodeName” must be followed by either attribute specifications, “>” or “/>”.


今天碰到了一个很头疼的问题,自定义的一个XML文档,在eclipse中做测试的时候能够正常解析,但是一旦部署到服务器上就会出现下面的错误:

[Fatal Error] :1:1476: Element type “nodeName” must be followed by either attribute specifications, “>” or “/>”.
net.sf.json.JSONException: nu.xom.ParsingException: Element type “nodeName” must be followed by either attribute specifications, “>” or “/>”. at line 1, column 1476
at net.sf.json.xml.XMLSerializer.read(XMLSerializer.java:331)
at net.sf.json.xml.XMLSerializer.FromStream(XMLSerializer.java:391)
at net.sf.json.xml.XMLSerializer.FromFile(XMLSerializer.java:355)
……
Caused by: nu.xom.ParsingException: Element type “nodeName” must be followed by either attribute specifications, “>” or “/>”. at line 1, column 1476
at nu.xom.Builder.build(Unknown Source)
at nu.xom.Builder.build(Unknown Source)
at net.sf.json.xml.XMLSerializer.read(XMLSerializer.java:309)
… 62 more
Caused by: org.xml.sax.SAXParsingException: Element type “nodeName” must be followed by either attribute specifications, “>” or “/>”.

从错误提示来看,是有标签没有结束,清空文件内容,一点点的添加,逐步排查,发现所有的标签都正常结束了阿。按照异常提示,一层层阅读源代码,从json-lib.jar到xom.jar,最后恍然大悟,应该直接拿

org.xml.sax.SAXParsingException: Element type “nodeName” must be followed by either attribute specifications, “>” or “/>”.

作为搜索条件,果不其然,使用这个关键字搜索的结果比net.sf.json.JSONException和nu.xom.ParsingException的结果多多了。

最后在关于dom4j解析编码的问题,org.xml.sax.SAXParseException: Invalid byte 1 of 1-byte UTF-8 sequence找到了关联答案,在二楼有人说

UTF-8编码中中文解析有问题
将编码格式改成“GB2312”后就可以正常解析了。<?xml version=”1.0″ encoding=”GB2312″?>

马上联想,这么奇怪的问题是不是也是编码问题导致的呢?最后把encoding从UTF-8修改为GB18030,问题解决。

疑问:为什么在eclipse中测试的时候没有出现问题,部署到tomcat或者weblogic都会出现这样的问题呢?

问题的根本原因找到了: Continue reading “Element type “nodeName” must be followed by either attribute specifications, “>” or “/>”.”

Spring 3.0配置多个DispatcherServlet的方法及注意事项


项目中需要同时用到两个视图解析器,一个报表的,一个jsp的。这就产生了标题所述的需求。通过阅读Spring Framework参考手册以及示例,解决了这个问题,中间也走了不少弯路,碰到了不少问题,特记录下来。

配置多个DispatcherServlet有多种方法,一种是在DispatcherServlet中直接指定此DispatcherServlet对应的配置文件。例如:

<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/app-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>

但是这种配置方法存在一个问题:由于DispatcherServlet对应的Controller需要访问Service并且使用dataSource,而DispatcherServlet之间的上下文是分离的,势必会出现多个dataSource的情况,降低了数据库连接使用的效率。

后来找到了第二种方法,目前正在使用的:DispatcherServlet不指定具体的配置文件,并且DispatcherServlet只初始化自己需要使用到的Controller类,然后由org.springframework.web.context.ContextLoaderListener初始化除Controller以外的全部对象。这样子多个dataSource的问题解决了。配置如下: Continue reading “Spring 3.0配置多个DispatcherServlet的方法及注意事项”

Weblogic 解析JSP出现This attribute is not recognized.错误


最近碰到一个奇怪的问题,在tomcat中能够正常显示的页面,跑到weblogic中解析的时候出错,提示This attribute is not recognized.

发现weblogic对嵌套标签的使用要求更加严格。对于在标签属性中嵌套jspscriptlet代码时,引号必须单、双引号配对使用。

例如:

<c:out value=”<%=node.findAttribute(“name”) %>”/>代码在tomcat中能够正常解析,但是在weblogic中就会出错。

正确的写法应该是:<c:out value='<%=node.findAttribute(“name”) %>’/>,在外面使用单引号

出现这样的情况,主要还是开发的时候为了便利,使用tomcat,在服务器上做每日集成的时候也没有使用了tomcat,但是客户部署时使用的是weblogic,由于开发环境和最终环境不一致,但是问题直到部署时才发现。为了避免这样的问题再次出现,至少需要在每日集成时使用最终部署相同的环境,尽早暴露问题。

java.sql.Date.valueOf 使用注意事项


最近在帮同事解决了一个日期格式化的问题,总结如下,以飨读者。

java.sql.Date.valueOf()方法提供了把yyyy-mm-dd类型字符串转换成java.sql.Date类型的功能。但是在使用的时候有以下注意事项:

  1. valueOf参数必须是一个有效日期的yyyy-mm-dd格式类型的日期。
    在jdk1.4中,valueOf的参数可以设置为0000-00-00,jdk能够正确转换,不出现异常。但是在jdk 6中,使用该参数时提示IllegalArgumentException异常。修改为0001-01-01正常。
  2. valueOf参数必须严格符合yyyy-mm-dd格式。
    修正之前的代码通过Calendar类获得年月日,这时获得的年月日都是int类型的, 当月份和日小于10的时候是一位的,此时JDK源码中判断月、日位数的检查生效,不会再进行转换,直接抛出IllegalArgumentException异常。通过Calendar类获取年月日之后,要对不足位的字段进行补位,保证能够正常转换。

题外话:关于第二点问题,同事很疑惑为什么之前可以,现在不可以了。阅读jdk源代码并结合Bug发生的时间来看,没问题的时间2010年12月下旬,此时月、日都是两位;而出问题的时间是2011年1月上旬,月、日都不足位。通过这个经验教训来看系统边界测试有时候是很有必要的。

Spring MVC 如何防止XSS、SQL注入攻击


在Web项目中,通常需要处理XSS,SQL注入攻击,解决这个问题有两个思路:

  • 在数据进入数据库之前对非法字符进行转义,在更新和显示的时候将非法字符还原
  • 在显示的时候对非法字符进行转义

如果项目还处在起步阶段,建议使用第二种,直接使用jstl的<c:out>标签即可解决非法字符的问题。当然,对于Javascript还需要自己处理一下,写一个方法,在解析从服务器端获取的数据时执行以下escapeHTML()即可。

附:Javascript方法:

String.prototype.escapeHTML = function () {
return this.replace(/&/g, ‘&amp;’).replace(/>/g, ‘&gt;’).replace(/</g, ‘&lt;’).replace(/”/g, ‘&quot;’);
}

如果项目已经开发完成了,又不想大批量改动页面的话,可以采用第一种方法,此时需要借助Spring MVC的@InitBinder以及org.apache.commons.lang.PropertyEditorSupport、org.apache.commons.lang.StringEscapeUtils

public class StringEscapeEditor extends PropertyEditorSupport {
private boolean escapeHTML;
private boolean escapeJavaScript;
private boolean escapeSQL;

public StringEscapeEditor() { super(); }
public StringEscapeEditor(boolean escapeHTML, boolean escapeJavaScript, boolean escapeSQL) {
super();
this.escapeHTML = escapeHTML;
this.escapeJavaScript = escapeJavaScript;
this.escapeSQL = escapeSQL;
}

@Override
public void setAsText(String text) {
if (text == null) {
setValue(null);
} else {
String value = text;
if (escapeHTML) {   value = StringEscapeUtils.escapeHtml(value);     }
if (escapeJavaScript) {     value = StringEscapeUtils.escapeJavaScript(value);     }
if (escapeSQL) {     value = StringEscapeUtils.escapeSql(value);     }     setValue(value);     }
}

@Override
public String getAsText() {     Object value = getValue();     return value != null ? value.toString() : “”;    }
}

在使用StringEscapeUtils时需要注意escapeHtml和escapeJavascript方法会把中文字符转换成Unicode编码,如果通过<c:out>标签或者EL表达式展示时,能够正确还原,但是如果使用类似于Ext这样的前端组件来展示这部分内容时,不能正常还原,这也是我为什么放弃了第一种方法,直接使用第二种方法的原因。

在上面我们做了一个EscapeEditor,下面还要将这个Editor和Spring的Controller绑定,使服务器端接收到数据之后能够自动转移特殊字符。
下面我们在@Controller中注册@InitBinder

@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(String.class, new StringEscapeEditor(false, false, false));
}

这个方法可以直接放到abstract Controller类中,这样子每个Controller实例都能够拥有该方法。至此第二种方法完成,但是在还原的方法暂时还没有。O(∩_∩)O…