Tuscany SDO 中的Bug
作者:ling091 时间:2008-12-16
我正在参与的ESB(企业服务总线)项目使用Tuscany的开源组件SDO(C++版),在使用过程中,我和其他项目组员发现了SDO存在的几个bug,这些bug我已经通过Apache网站的JIRA:
http://issues.apache.org/jira/browse/Tuscany
进行了发布,从该网站可以看到C++ SDO的所有使用者发布的bug和新特性,有些bug已经由该bug的发布者或其他用户提供了补丁。
以下是我在Apache的JIRA上发布的四个bug:
1.Bug1
1.1 概要:
SDO的几个与序列化相关的方法不支持多线程
1.2 运行环境:
Windows XP
Visual C++6.0
cpp_tuscany_sdo-M3
libxml2-2.7.2
iconv-1.7.2
zlib-1.2.3
boost-1.33.1
1.3 描述:
在多线程环境中对SDO对象进行序列化和反序列化时,只有第一个线程的运行是好的,从第二个线程开始SDO对象的序列化和反序列化都失败了(多线程环境是通过开源库boost_1_33_1实现的)。这些在多线程中运行失败的方法包括:
//used when antiserializing a SDO object from a character string
const char* XSDHelperImpl::define(
const char* schema,
bool loadImportNamespace= "")
//used when serializing a SDO object into a character string
char* XMLHelperImpl::save(
DataObjectPtr dataObject,
const char* rootElementURI,
const char* rootElementName,
int indent= -1)
// used when serializing a SDO object into a xml file
void XMLHelperImpl::save(
DataObjectPtr dataObject,
const char* rootElementURI,
const char* rootElementName,
const char* xmlFile,
int indent = -1)
//used when getting a SOD object's shcema character string
char* XSDHelperImpl::generate(
const TypeList& types,
const char* targetNamespaceURI = "",
int indent = -1)
//used when getting a SDO object's schema file
void XSDHelperImpl::generateFile(
const TypeList& types,
const char* fileName,
const char* targetNamespaceURI = "",
int indent = -1)
但是与对象序列化或反序列化相关的方法中,通过文件来反序列化创建SDO对象的方法都是线程安全的:
const char* XSDHelperImpl::defineFile(
const char* schema,
bool loadImportNamespace = false)
1.4 解决方案:
通过比较defineFile和define方法的实现,我查找到原因是SDO涉及序列化和反序列化的方法都依赖开源的C++的xml解析器libxml2,而libxml2的一些方法并不是线程安全的,尽管网上的资料声称libxml2从2.4.7版已经做到线程安全了。通过将define方法依赖的解析函数替换为libxml2中的其他线程安全的解析函数,补丁程序的define方法已经不存在线程不安全问题。
defineFile方法依赖的libxml2中的方法是:
XMLPUBFUN int XMLCALL xmlSAXUserParseFile (
xmlSAXHandlerPtr sax,
void *user_data,
const char *filename);
对该方法的调用位于SAX2Parser类的parse_twice方法
define方法依赖的libxml2中的方法是:
XMLPUBFUN int XMLCALL xmlParseChunk (
xmlParserCtxtPtr ctxt,
const char *chunk,
int size,
int terminate);
对该方法的调用位于SAX2Parser类的stream_twice方法,在补丁程序中,将xmlParserChunk方法替换为与xmlSAXUserParseFile对应的下列方法:
XMLPUBFUN int XMLCALL xmlSAXUserParseMemory (
xmlSAXHandlerPtr sax,
void *user_data,
const char *buffer,
int size);
补丁程序只修改了SAX2Parser类的stream_twice,修改后的实现为:
void SAX2Parser::stream_twice(std::istream& input)
{
//begin 将input流读到char*
input.seekg(0, std::ios_base::end);
int size = input.tellg();
char* buffer = new char[size];
input.seekg(std::ios_base::beg);
input.read(buffer, size);
//end
parserError = false;
xmlSAXHandlerPtr handler = &SDOSAX2HandlerStruct;
//int rc = xmlSAXUserParseFile(handler, this, filename);
int rc = xmlSAXUserParseMemory(handler, this, buffer, size);
if (rc == -1)
{
sdo_error(this, "xmlSAXUserParseFile returned an error %d", rc);
SDO_THROW_EXCEPTION("parse", SDOFileNotFoundException,messageBuffer);
}
// parse twice - first was for groups
if (setter)setter->clearErrors();
//rc = xmlSAXUserParseFile(handler, this, filename);
rc = xmlSAXUserParseMemory(handler, this, buffer, size);
if (rc == -1)
{
sdo_error(this, "xmlSAXUserParseFile returned an error %d", rc);
SDO_THROW_EXCEPTION("parse", SDOFileNotFoundException,messageBuffer);
}
delete buffer;
}
对于上面提到的其他的不支持多线程的方法,由于没有在libxml2中找到与之对应的线程安全的解析函数进行替换,所以这些函数仍然不支持多线程环境。
2.Bug2
2.1 概要:
有些反序列化方法不支持中文,或者不可用,或者中文变为乱码。
2.2 运行环境:
Windows XP
Visual C++6.0
cpp_tuscany_sdo-M3
libxml2-2.7.2
iconv-1.7.2
zlib-1.2.3
2.3 描述:
从一个字符串反序列化成一个SDO对象时,如果字符串中存在中文字符,则反序列化为SDO对象存在问题,不同的使用方式或者不可用、或者中文变为乱码。
下面的方法是对SDO进行封装后的从字符串反序列化为SDO对象:
DataObjectPtr generateSDOFromStr(
const char* xsdStr, const char* xmlStr,
const char* nameSpace = "")
{
DataObjectPtr root=NULL;
try
{
DataFactoryPtr mdg=DataFactory::getDataFactory();
XSDHelperPtr xsdHelper=HelperProvider::getXSDHelper(mdg);
xsdHelper->define(xsdStr);
XMLHelperPtr xmlHelper = HelperProvider::getXMLHelper(mdg);
XMLDocumentPtr xmlDoc = xmlHelper->load(xmlStr,nameSpace);
root = xmlDoc->getRootDataObject();
}
catch(SDORuntimeException e)
{
cout << "Exception in generateSDOFromStr"<< endl;
cout<< e<<endl;
}
catch(...)
{
cout<<"Exception not SDORuntimeException"<<endl;
}
return root;
}
这是对该方法的两种调用方式:
void testGenerateSDOFromStr()
{
//直接使用字符串
string xsdStr = "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\"><xs:element name=\"company\">";
xsdStr += "<xs:complexType><xs:attribute name=\"name\" type=\"xs:string\" /></xs:complexType></xs:element></xs:schema>";
string xmlStr = "<?xml version=\"1.0\" encoding=\"GB2312\"?><company name = \"中国xidian\"/>";
//--------------第一种调用方式-------------
//xmlStr写为GB2312或UTF-8结果都是乱码 但是创建sdo对象都是正确的
//DataObjectPtr dob = generateSDOFromStr(xsdStr.c_str(), xmlStr.c_str() );
//--------------第二种调用方式----------
//只要第二个参数中有中文,构造的sdo对象就是null
DataObjectPtr dob = generateSDOFromStr(xsdStr.c_str(),
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><company name = \"中国xidian\"/>");
if(dob != NULL)
{
cout<<dob->getCString("name")<<endl;//涓浗xidian
}
else
{
cout<<"null"<<endl;
}
}
2.4 解决方案:
造成乱码的原因是SDO使用的libxml2对中文的支持很差,经过libxml2解析后,SDO得到的内容已经是乱码。解决方法是可以使用iconv提供的编码转换函数进行编码转换,在遇到带中文的字符串需要显示时,将其转换为GB2312编码即可。
3.Bug3
3.1 概要:
反序列化为SDO对象的schema文件与从该SDO对象生成的schema文件不一致。
3.2 运行环境:
Windows XP
Visual C++6.0
cpp_tuscany_sdo-M3
libxml2-2.7.2
iconv-1.7.2
zlib-1.2.3
3.3 描述:
从schema文件和xml文件反序列化成一个SDO对象,然后再从这个对象生成schema文件,前后两个schema文件的定义不一致,在后面的schema文件中,属性attribute变成了元素element。
下面是测试用例:
Tuscany SDO中的Bug续: http://ling091.iteye.com/admin/blogs/295580
分享到:
相关推荐
在C++版的Tuscany SDO中,这个概念被实现为一个库,允许C++开发者轻松地处理和操作数据。 **SDO的核心特性** 1. **统一的数据模型**:SDO定义了一种统一的数据模型,无论数据来源何处,如数据库、XML文件或Web服务...
### Tuscany-SDO-学习笔记 #### 1. SDO基础知识 ##### 1.1 创建DataObject **1.1.1 动态定义类型,然后创建DataObject** 在这一节中,我们将探讨如何通过动态定义类型来创建DataObject。这种方式允许我们在运行...
标题中的“tuscany-das&sdo&distribution-all.zip”提到了三个关键概念:Tuscany Data Access Service (Tuscany DAS),Service Data Objects (SDO) 和 Distribution。这表明该压缩包可能包含了与这些技术相关的软件...
自制CHM版的API文档,带索引。 注:如果各位下载后打开或无法显示页面,请在CHM文件右键—属性—解除锁定即可。
在这个“Tuscany发布Web服务实例”中,我们将深入探讨如何利用Tuscany来配置和发布一个简单的Web服务接口。 1. **Tuscany简介** Tuscany的设计目标是支持多种服务交互协议和服务模型,如SOAP、REST、JMS等,并且...
5. 接下来,点击`Add JARs`按钮,浏览并选择所有位于`E:\tuscany-sdo-1.0-incubating-beta1\lib`目录下的JAR文件,将它们添加到用户库中。 完成上述步骤后,我们已经成功创建了一个包含所有必要SDO组件的用户库。 ...
【压缩包子文件的文件名称列表】中的 "tuscany-sca-1.6.2-src" 表明这是Apache Tuscany SCA框架的1.6.2版本的源代码文件。源代码对于开发者来说至关重要,因为它提供了项目的原始构建块,允许他们深入理解代码的工作...
Tuscany源码的分析有助于深入理解SCA的工作原理以及如何在实际开发中应用这一框架。 SCA的核心概念包括组件、服务、绑定和配置。组件是应用程序的基本单元,可以提供或消费服务。服务是组件对外提供的接口,供其他...
Tuscany是一个开源的服务组合架构(Service Component Architecture, SCA)实现,它提供了一种方式来管理和控制应用程序中与业务逻辑正交的方面,比如日志、监控和安全性。策略在Tuscany和SCA中扮演着关键角色,它们...
在“Apache Tuscany SCA 用户指南StepByStep”中,读者可以期待获得以下关键知识点: 1. **SCA基础概念**:首先,你需要理解SCA的核心概念,包括组件(Component)、服务(Service)、引用(Reference)和绑定...
由于压缩包中已删除了`lib`文件夹中的jar,你需要手动添加这些依赖到你的项目类路径中,包括Tuscany的SCA实现、Spring的核心库和Hibernate的JAR文件。 2. **创建SCA组件**:定义SCA组件,这些组件可以是Spring Bean...
Tuscany架构 Tuscany架构.jpg Tuscany架构.jpg
实现SDO需要在项目中引入相应的库,如Apache Tuscany,它是开源实现SDO的一个重要框架。配置完成后,可以通过创建数据图和数据对象来开始数据访问操作。 1. **Apache Tuscany的Java SDO** - **将XML转换为Data ...
在“apache-tuscany-sca-1.6.2”这个压缩包中,我们能找到Apache Tuscany的特定版本——1.6.2。这个版本包含了项目的所有源代码,这对于开发者来说是极其宝贵的资源,因为源码可以提供深入理解其内部工作原理的机会...
《Tuscany SCA在行动》一书深入探讨了Service Component Architecture(SCA)与Apache Tuscany项目,这是IT领域内对服务组件架构及其实现的重要研究资料。以下是基于标题、描述、部分目录和标签生成的相关IT知识点:...
2. **示例代码**:实例中可能包含了演示如何使用Apache Tuscany创建和部署SCA组件的代码。这些代码可能包括服务组件、绑定接口和服务配置文件。 3. **文档**:除了代码,可能还附带了详细的文档,解释了如何理解和...
根据提供的文件信息,本文将详细解析Tuscany与Spring、Axis整合的相关知识点,以及如何解决在整合过程中可能遇到的jar包冲突问题。 ### Tuscany简介 Tuscany项目是Apache软件基金会的一个顶级项目,专注于提供一个...
tuscany wsdl2java tools
5个代码例子使用的是 Tuscany1.5版本。请在官网下载jar包。 下载地址:http://archive.apache.org/dist/tuscany/java/sca/1.5/apache-tuscany-sca-1.5.zip 5个例子从不同的角度讲解了tuscany的整体架构思想。文档...