`

Tuscany SDO 中的Bug

    博客分类:
  • SOA
阅读更多

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的发布者或其他用户提供了补丁。

以下是我在ApacheJIRA上发布的四个bug:

1Bug1

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 解决方案:

通过比较defineFiledefine方法的实现,我查找到原因是SDO涉及序列化和反序列化的方法都依赖开源的C++xml解析器libxml2,而libxml2的一些方法并不是线程安全的,尽管网上的资料声称libxml22.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中找到与之对应的线程安全的解析函数进行替换,所以这些函数仍然不支持多线程环境。

2Bug2

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编码即可。

3Bug3

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

1
0
分享到:
评论

相关推荐

    Tuscany的开源项目Tuscany_sdo(C++版)

    在C++版的Tuscany SDO中,这个概念被实现为一个库,允许C++开发者轻松地处理和操作数据。 **SDO的核心特性** 1. **统一的数据模型**:SDO定义了一种统一的数据模型,无论数据来源何处,如数据库、XML文件或Web服务...

    Tuscany-SDO-学习笔记

    ### Tuscany-SDO-学习笔记 #### 1. SDO基础知识 ##### 1.1 创建DataObject **1.1.1 动态定义类型,然后创建DataObject** 在这一节中,我们将探讨如何通过动态定义类型来创建DataObject。这种方式允许我们在运行...

    tuscany-das&sdo&distribution-all.zip

    标题中的“tuscany-das&sdo&distribution-all.zip”提到了三个关键概念:Tuscany Data Access Service (Tuscany DAS),Service Data Objects (SDO) 和 Distribution。这表明该压缩包可能包含了与这些技术相关的软件...

    tuscany-sdo-1.1.1-javadoc.chm

    自制CHM版的API文档,带索引。 注:如果各位下载后打开或无法显示页面,请在CHM文件右键—属性—解除锁定即可。

    tuscany发布webservice实例

    在这个“Tuscany发布Web服务实例”中,我们将深入探讨如何利用Tuscany来配置和发布一个简单的Web服务接口。 1. **Tuscany简介** Tuscany的设计目标是支持多种服务交互协议和服务模型,如SOAP、REST、JMS等,并且...

    SDO环境的配置,安装详解

    5. 接下来,点击`Add JARs`按钮,浏览并选择所有位于`E:\tuscany-sdo-1.0-incubating-beta1\lib`目录下的JAR文件,将它们添加到用户库中。 完成上述步骤后,我们已经成功创建了一个包含所有必要SDO组件的用户库。 ...

    tuscany1.6.2

    【压缩包子文件的文件名称列表】中的 "tuscany-sca-1.6.2-src" 表明这是Apache Tuscany SCA框架的1.6.2版本的源代码文件。源代码对于开发者来说至关重要,因为它提供了项目的原始构建块,允许他们深入理解代码的工作...

    apaceh -TUSCANY 源码

    Tuscany源码的分析有助于深入理解SCA的工作原理以及如何在实际开发中应用这一框架。 SCA的核心概念包括组件、服务、绑定和配置。组件是应用程序的基本单元,可以提供或消费服务。服务是组件对外提供的接口,供其他...

    tuscany的一点文档

    Tuscany是一个开源的服务组合架构(Service Component Architecture, SCA)实现,它提供了一种方式来管理和控制应用程序中与业务逻辑正交的方面,比如日志、监控和安全性。策略在Tuscany和SCA中扮演着关键角色,它们...

    Apache Tuscany SCA 用户指南StepByStep

    在“Apache Tuscany SCA 用户指南StepByStep”中,读者可以期待获得以下关键知识点: 1. **SCA基础概念**:首先,你需要理解SCA的核心概念,包括组件(Component)、服务(Service)、引用(Reference)和绑定...

    Tuscany SCA与Spring、Hibernate整合实例-简洁方法

    由于压缩包中已删除了`lib`文件夹中的jar,你需要手动添加这些依赖到你的项目类路径中,包括Tuscany的SCA实现、Spring的核心库和Hibernate的JAR文件。 2. **创建SCA组件**:定义SCA组件,这些组件可以是Spring Bean...

    Tuscany 架构图

    Tuscany架构 Tuscany架构.jpg Tuscany架构.jpg

    sdo规范及其应用介绍

    实现SDO需要在项目中引入相应的库,如Apache Tuscany,它是开源实现SDO的一个重要框架。配置完成后,可以通过创建数据图和数据对象来开始数据访问操作。 1. **Apache Tuscany的Java SDO** - **将XML转换为Data ...

    apache-tuscany-sca-1.6.2

    在“apache-tuscany-sca-1.6.2”这个压缩包中,我们能找到Apache Tuscany的特定版本——1.6.2。这个版本包含了项目的所有源代码,这对于开发者来说是极其宝贵的资源,因为源码可以提供深入理解其内部工作原理的机会...

    Tuscany SCA in Action

    《Tuscany SCA在行动》一书深入探讨了Service Component Architecture(SCA)与Apache Tuscany项目,这是IT领域内对服务组件架构及其实现的重要研究资料。以下是基于标题、描述、部分目录和标签生成的相关IT知识点:...

    Apache tuscany SCA实例

    2. **示例代码**:实例中可能包含了演示如何使用Apache Tuscany创建和部署SCA组件的代码。这些代码可能包括服务组件、绑定接口和服务配置文件。 3. **文档**:除了代码,可能还附带了详细的文档,解释了如何理解和...

    是tuscany与spring,axis整合所有的jar包,已解决冲突问题。

    根据提供的文件信息,本文将详细解析Tuscany与Spring、Axis整合的相关知识点,以及如何解决在整合过程中可能遇到的jar包冲突问题。 ### Tuscany简介 Tuscany项目是Apache软件基金会的一个顶级项目,专注于提供一个...

    tuscany-wsdl2java-1.5

    tuscany wsdl2java tools

    soa-tuscany资料与5个小例子

    5个代码例子使用的是 Tuscany1.5版本。请在官网下载jar包。 下载地址:http://archive.apache.org/dist/tuscany/java/sca/1.5/apache-tuscany-sca-1.5.zip 5个例子从不同的角度讲解了tuscany的整体架构思想。文档...

Global site tag (gtag.js) - Google Analytics