- 浏览: 3053509 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
上周在写某东西的时候,要用jBPM来部署流程,数据来源是Saito同学传来的XML字符串。但是只要XML里一有中文,部署就会失败。而且在写的那东西极其不好调试——程序里很多地方都被proxy包装过的话,调试起来会很痛苦。
大概的状况是:Saito同学传来的XML字符串不包含XML声明,我这边调用jBPM新建NewDeployment,把字符串放进去,然后deploy,然后就抛出个被包装了很多层的异常,其中最内层的是MalformedByteSequenceException。
之前还有别的更头疼的问题要解决,这个问题就放在了一边。周五的时候终于有时间去修一修。
抓来jBPM 4.1的源码一看,囧了。在我调用jBPM的地方,传入的XML字符串大概经过了下面一些方法才被解析为DOM:
org.jbpm.pvm.internal.repository.DeploymentImpl:
org.jbpm.pvm.internal.stream.StringStreamInput:
org.jbpm.pvm.internal.xml.Parse:
org.jbpm.pvm.internal.xml.Parser:
总之绕了各种接口,经过层层包装、拆包、再包装再拆包,可怜的字符串终于来到SAX解析器的手上。问题是jBPM在中间调用了String.getBytes():这个方法会把Java字符串(Unicode)转换为系统默认编码并返回对应的byte[],但当InputSource中没有设置编码信息时,SAXParser默认是以UTF-8编码来读取输入流的。我的开发机的系统默认编码是GBK,于是就出问题了。jBPM用String.getBytes()让我无语了……就不能用带编码参数的版本么 T T
简单再现这个问题可以用下面这个程序:
运行它会看到:
稍微修改,加上对应本机器的系统默认编码的XML声明后,问题就解决了:
这让我想起以前在developerWorks读过的一篇文章,Tip: Always use an XML declaration。确实是应该写上XML声明的。
不过随便乱写一个XML声明却不管用。如果把上例的XML声明中的编码改为"UTF-8",在我这默认GBK的系统上跑照样是碰到MalformedByteSequenceException错误。考虑到我不应该依赖于定测试环境和线上环境的编码到底是什么,这里就用System.getProperty("file.encoding")去获取系统默认编码,以便于String.getBytes()匹配。
其实有从XML文件里读的咯,当XML文件开头的编码声明是正确的时候SAXParser就能正确解析出来。当没有开头的编码声明时,受到String.getBytes()的影响而变得是使用了系统默认编码来读。上面文中也提到了。
大概的状况是:Saito同学传来的XML字符串不包含XML声明,我这边调用jBPM新建NewDeployment,把字符串放进去,然后deploy,然后就抛出个被包装了很多层的异常,其中最内层的是MalformedByteSequenceException。
之前还有别的更头疼的问题要解决,这个问题就放在了一边。周五的时候终于有时间去修一修。
抓来jBPM 4.1的源码一看,囧了。在我调用jBPM的地方,传入的XML字符串大概经过了下面一些方法才被解析为DOM:
org.jbpm.pvm.internal.repository.DeploymentImpl:
public NewDeployment addResourceFromString(String resourceName, String text) { addResourceFromStreamInput(resourceName, new StringStreamInput(text)); return this; }
org.jbpm.pvm.internal.stream.StringStreamInput:
public class StringStreamInput extends StreamInput { String string; public StringStreamInput(String string) { this.name = "string"; this.string = string; } public InputStream openStream() { byte[] bytes = string.getBytes(); return new ByteArrayInputStream(bytes); } }
org.jbpm.pvm.internal.xml.Parse:
protected InputSource getInputSource() { if (inputSource!=null) { return inputSource; } if (streamInput!=null) { inputStream = streamInput.openStream(); return new InputSource(inputStream); } addProblem("no source specified to parse"); return null; }
org.jbpm.pvm.internal.xml.Parser:
protected Document buildDom(Parse parse) { Document document = null; try { SAXParser saxParser = saxParserFactory.newSAXParser(); XMLReader xmlReader = saxParser.getXMLReader(); // ... InputSource inputSource = parse.getInputSource(); xmlReader.parse(inputSource); } catch (Exception e) { parse.addProblem("couldn't parse xml document", e); } return document; }
总之绕了各种接口,经过层层包装、拆包、再包装再拆包,可怜的字符串终于来到SAX解析器的手上。问题是jBPM在中间调用了String.getBytes():这个方法会把Java字符串(Unicode)转换为系统默认编码并返回对应的byte[],但当InputSource中没有设置编码信息时,SAXParser默认是以UTF-8编码来读取输入流的。我的开发机的系统默认编码是GBK,于是就出问题了。jBPM用String.getBytes()让我无语了……就不能用带编码参数的版本么 T T
简单再现这个问题可以用下面这个程序:
import java.io.*; import javax.xml.parsers.*; import org.xml.sax.*; public class TestSAX { private static InputSource getInputSource(String src) { return new InputSource(new ByteArrayInputStream(src.getBytes())); } public static void main(String[] args) throws Exception { String xmlStr = "<test name=\"名称\"></test>"; System.out.println(xmlStr); SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); SAXParser saxParser = saxParserFactory.newSAXParser(); XMLReader xmlReader = saxParser.getXMLReader(); InputSource input = getInputSource(xmlStr); xmlReader.parse(input); } }
运行它会看到:
D:\temp>java TestSAX <test name="名称"></test> Exception in thread "main" com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 2 of 2-byte UTF-8 sequence. at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(Unknown Source) at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.scanLiteral(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLScanner.scanAttributeValue(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanAttribute(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$ContentDriver.scanRootElementHook(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) at TestSAX.main(TestSAX.java:19)
稍微修改,加上对应本机器的系统默认编码的XML声明后,问题就解决了:
import java.io.*; import javax.xml.parsers.*; import org.xml.sax.*; public class TestSAX { private static InputSource getInputSource(String src) { return new InputSource(new ByteArrayInputStream(src.getBytes())); } public static void main(String[] args) throws Exception { String xmlStr = "<?xml version=\"1.0\" encoding=\"" + System.getProperty("file.encoding") + "\"?><test name=\"名称\"></test>"; System.out.println(xmlStr); SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); SAXParser saxParser = saxParserFactory.newSAXParser(); XMLReader xmlReader = saxParser.getXMLReader(); InputSource input = getInputSource(xmlStr); xmlReader.parse(input); } }
这让我想起以前在developerWorks读过的一篇文章,Tip: Always use an XML declaration。确实是应该写上XML声明的。
不过随便乱写一个XML声明却不管用。如果把上例的XML声明中的编码改为"UTF-8",在我这默认GBK的系统上跑照样是碰到MalformedByteSequenceException错误。考虑到我不应该依赖于定测试环境和线上环境的编码到底是什么,这里就用System.getProperty("file.encoding")去获取系统默认编码,以便于String.getBytes()匹配。
评论
4 楼
RednaxelaFX
2010-03-16
DT1 写道
只是还是觉得有点恶心,这个编码其实应该从xml文件中读取,而不是写死,要不然人家上传的是GBK不是郁闷.
其实有从XML文件里读的咯,当XML文件开头的编码声明是正确的时候SAXParser就能正确解析出来。当没有开头的编码声明时,受到String.getBytes()的影响而变得是使用了系统默认编码来读。上面文中也提到了。
3 楼
DT1
2010-03-15
可使用以下方法解决,在你这边留个影,让其他找到的朋友可以有个解决方案:
processEngine.getRepositoryService().createDeployment() .addResourceFromInputStream("xxxx.jpdl.xml", IOUtils.toInputStream(xml, "utf-8")).deploy();
显式指定传入InputStream以及编码,将xml转成InputStream,就可以解决这个问题.
只是还是觉得有点恶心,这个编码其实应该从xml文件中读取,而不是写死,要不然人家上传的是GBK不是郁闷.
processEngine.getRepositoryService().createDeployment() .addResourceFromInputStream("xxxx.jpdl.xml", IOUtils.toInputStream(xml, "utf-8")).deploy();
显式指定传入InputStream以及编码,将xml转成InputStream,就可以解决这个问题.
只是还是觉得有点恶心,这个编码其实应该从xml文件中读取,而不是写死,要不然人家上传的是GBK不是郁闷.
2 楼
DT1
2010-03-15
看了代码了,这个问题还是在那里,使用.getBytes时,看起来是默认使用当前系统的编码集.
1 楼
DT1
2010-03-14
半夜遇到同样问题,我是4.3,我认为是它的getBytes有问题,它不应该getBytes,而应该直接将到后台去处理,因为前台已经传入是string了,而不是什么inputstream之类的.
发表评论
-
The Prehistory of Java, HotSpot and Train
2014-06-02 08:18 0http://cs.gmu.edu/cne/itcore/vi ... -
MSJVM and Sun 1.0.x/1.1.x
2014-05-20 18:50 0当年的survey paper: http://www.sym ... -
Sun JDK1.4.2_28有TieredCompilation
2014-05-12 08:48 0原来以前Sun的JDK 1.4.2 update 28就已经有 ... -
IBM JVM notes (2014 ver)
2014-05-11 07:16 0Sovereign JIT http://publib.bou ... -
class data sharing by Apple
2014-03-28 05:17 0class data sharing is implement ... -
Java 8与静态工具类
2014-03-19 08:43 16298以前要在Java里实现所谓“静态工具类”(static uti ... -
Java 8的default method与method resolution
2014-03-19 02:23 10468先看看下面这个代码例子, interface IFoo { ... -
HotSpot Server VM与Server Class Machine
2014-02-18 13:21 0HotSpot VM历来有Client VM与Server V ... -
Java 8的lambda表达式在OpenJDK8中的实现
2014-02-04 12:08 0三月份JDK8就要发布首发了,现在JDK8 release c ... -
GC stack map与deopt stack map的异同
2014-01-08 09:56 0两者之间不并存在包含关系。它们有交集,但也各自有特别的地方。 ... -
HotSpot Server Compiler与data-flow analysis
2014-01-07 17:41 0http://en.wikipedia.org/wiki/Da ... -
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22410(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
关于string,内存布局,C++ std::string,CoW
2013-10-30 20:45 0(Disclaimer:未经许可请 ... -
对C语义的for循环的基本代码生成模式
2013-10-19 23:12 21887之前有同学在做龙书(第二版)题目,做到8.4的练习,跟我对答案 ... -
Java的instanceof是如何实现的
2013-09-22 16:57 0Java语言规范,Java SE 7版 http://docs ... -
oop、klass、handle的关系
2013-07-30 17:34 0oopDesc及其子类的实例 oop : oopDesc* ... -
Nashorn各种笔记
2013-07-15 17:03 0http://bits.netbeans.org/netbea ... -
《深入理解Java虚拟机(第二版)》书评
2013-07-08 19:19 0值得推荐的中文Java虚拟机入门书 感谢作者赠与的样书,以下 ... -
豆列:从表到里学习JVM实现
2013-06-13 14:13 48399刚写了个学习JVM用的豆列跟大家分享。 豆列地址:http: ...
相关推荐
本篇主要针对jbpm4.3使用过程中遇到的问题及其解决方法进行详细阐述。 首先,我们来看"jbpm4_3表结构和表字段说明 - gamestart104的专栏 - 博客频道 - CSDN_NET.htm"这个文件,这通常包含了jbpm4.3在数据库中使用的...
jbpm4jbpm5是关于jbpm流程管理框架的专题,涵盖了jbpm4和jbpm5两个主要版本。jbpm是一个开源的工作流管理系统,用于帮助开发者实现业务流程自动化。以下是基于给定文件的信息,深入解析jbpm4和jbpm5的知识点: 1. *...
### jBPM简介与关键技术知识点 #### 一、jBPM概述 jBPM是一个开源的、纯Java的、轻量级的商业流程管理(Business Process Management, BPM)工作流引擎。它支持多种可执行流程语言,并且可以在任何JavaEE应用...
jbpm jbpm4.3.jar DDDDDDDD
jbpm使用案例,非常不错,大家都来看看吧。
通过查看JBPM的API我们发现API里并没有提供实现该功能现成的接口,不过我们可以通过自己手工编码的方式来拿到我们需要的监控信息。 通过查看JBPM的表,我们知道要实现流程监控功能就是把JBPM当中的JBPM_PROCESS...
总之,解决jbpm的Eclipse Designer插件中gpd.xml文件乱码问题的关键在于确认并保持文件和编辑器之间的一致性,确保使用的都是正确的字符编码。同时,了解Eclipse和相关插件的配置设置,以及如何正确处理XML文件,将...
在配置Jbpm的过程中,可能会遇到一系列的问题,尤其是在与数据库集成和服务器环境设置时。本文将详细探讨在配置Jbpm时需要注意的关键点,包括MySQL字符集问题、Jboss服务器的配置以及JBossJbpm的整合。 首先,MySQL...
jbpm4.3插件,解决中文乱码,主要修改org.jboss.tools.flow.jpdl4_4.3.0.v201007071649.jar中的JbpmLocationsPage 和 org.jboss.tools.jbpm.common_4.3.0.v201007071649.jar 中的JpdlSerializer和ProcessSerializer
### jBPM 白皮书:介绍 jBPM 入门 #### 一、引言与背景 在当今数字化转型的时代背景下,业务流程管理(Business Process Management,简称 BPM)成为了企业提升效率、优化流程的关键技术之一。BPM 提供了一种程序...
【jbpm】是一种开源的工作流管理系统,全称为Java Business Process Management。它主要用于处理业务流程的自动化,通过定义和执行工作流程来协调应用系统中的不同组件。jbpm不仅提供了流程建模、部署、执行的能力,...
首先,我们来看"jBPM-4.x常见问题解决方案FAQ.docx",这个文档很可能包含了用户在使用jBPM 4.3时遇到的各种问题和相应的解决办法。常见问题可能包括流程部署失败、任务无法执行、数据持久化问题、工作流引擎性能优化...
你可以通过阅读这个文档,深入了解jbPM 3.2的使用方法,解决在实际项目中遇到的问题。 总的来说,jbPM 3.2是一个强大的工作流管理系统,通过深入理解和实践,开发者可以构建出高效、灵活的业务流程,提高企业的业务...
jbpm-3.1.2.zip 文件包含了 jBpm 的一个重要版本——jBpm 3.1.2,这是一个开源的工作流管理系统,专为构建灵活且可扩展的业务流程解决方案而设计。jBpm 提供了一种方式,使得开发者能够用简单而强大的语言来表达业务...
JBPM4 SSH EXTJS JBPM SSH EXTJS JBPM4 SSH EXTJS JBPM SSH EXTJS JBPM4 SSH EXTJS JBPM SSH EXTJS JBPM4 SSH EXTJS JBPM SSH EXTJS 希望对大家有帮助。
在《jBPM4.4中文用户手册》中,用户可以找到更详细的使用指南,包括安装配置、基本操作、示例教程以及常见问题解答等内容。手册将帮助用户快速上手,实现jBPM在实际项目中的应用。 总的来说,jBPM4.4是企业级业务...
jbpm 数据库表介绍 jbpm 是一个基于 Java 的 workflow 引擎,用于管理和执行业务流程。jbpm 需要持久化流程部署、流程实例、任务、用户认证等信息,于是 jbpm 设计了一系列的数据库表来存储这些信息。在 jbpm 4.4 ...
jbpm(Java Business Process Management)是一款开源的工作流管理系统,它为业务流程自动化提供了一套全面的解决方案。jbpm不仅支持工作流的建模、执行,还提供了监控和管理功能,使得开发者可以方便地构建和部署...
在实际开发中,关键点在于解决jbpm和Hibernate的session冲突问题。jbpm需要自己的session来执行工作流操作,而SSH框架通常有自己的持久化机制。这里可以利用Spring的Transaction Management,统一管理事务和session...