结构化微内容 -

一种服务应该允许对结构化微内容进行操作。这可以是数据存储服务或数据加工服务;

外部数据 -

数据主要来自外部。因而一种服务主要关注的应该是处理微内容,而不是存储微内容。这也意味着一种服务应该允许从外部获取数据。这既可以是通过一个feed,也可以是一种导入功能。这也意味着用户对他的数据拥有全部控制权(编辑、删除,等等);

许可 -

用户决定每个微内容项的使用许可。这种许可可以区分私人数据、群组数据以及公开数据;

丰富的feed -

一种服务应该提供可供用户订阅的很多feed,这些feed应该以任何可能的方式融合并匹配于经过处理的微内容;

Web API -

一种服务应该提供很多的Web API,以便将其功能整合到其他的服务中;

桌面集成 -

一种服务应该不只依赖于网络,还应该与桌面进行紧密集成。比方说,可以通过微内容客户端实现;

单一身份 -

一个用户在所有他所使用的服务中无需多次创建他的身份,只有一个可以导出到其他服务的单一身份就够了(当然可以有多个角色);

微Web -

用户应该可以在某个领域中随意穿越微内容空间。在一个单独的领域内,用户可以从一个微内容项,转到相关的其他微内容项。何为相关由用户自己决定。就是说看到一个名字“Arnaud Leene”,就可以查阅相关的FOAF文件、blog、tag等等;

非预设结构 -

一种服务应该支持灵活的微内容结构。就是说这种结构不是预设的,而是由用户决定的。

Posted on March 3, 2007 9:47 AM | | Comments (0) | TrackBacks (0)


  导语:北京时间2月26日,美国著名博客斯科特·卡普(Scott Karp)近日发表文章称,曾经“铁板一块”的媒体行业正分裂成为两部分:其一是内容制作,其二是内容聚合和发行。


  不久前,美国博客汤姆·福里姆斯基(Tom Foremski)发表文章称,美国媒体行业正分裂成为东海岸和西海岸两部分。其中,位于东海岸的纽约是传统的出版行业中心,而位于西海岸的好莱坞则是视 频媒体行业中心。卡普认为,福里姆斯基的观点只有一半正确。媒体行业的确在分裂,但与地域无关。


Continue reading "Web2.0引发媒体行业变革:制作和发行裂变"
Posted on February 26, 2007 11:43 PM | | Comments (0) | TrackBacks (0)

Zend创建者Andi Gutmans为我们带来了一段非常精炼的Web 2.0诠释,抓住Web 2.0的几个要点,对Ajax、Blog、Wash-Up等Web2.0标志概念以及之间的关系进行了简明扼要的阐述,足以作为Web 2.0的经典定义。(感谢Chris笔录)

  “大家好,我是Zend的Andi Gutmans,今天我们将要讨论的问题是:什么是Web 2.0?
  也许你早已听说过Web 2.0的部分特征,例如Blog,Mash-up,Ajax,但是Web 2.0含义究竟是什么?Flickr、Youtube这些概念网站就可以代表Web 2.0么?其实不然,Web 2.0的定义更为深入。  

  Web 2.0由三个部分组成,第一个部分--RIA,Rich Internet Applications(丰富互联网应用程序),Flash、Ajax等网络应用技术便归于RIA旗下--改进强化用户浏览器体验,将桌面操作带入浏览器操作的方法--最典型的,在网页中支持超级托拽功能。  
  Web 2.0第二个部分--SOA,Service-Oriented Architecture(面向服务架构),也是Web 2.0的核心部分,相关词汇:Feeds、RSS、Web Services、Mash-Up。SOA的核心问题--开放、互通,如何让来自不同服务商的网络应用能够协作运行。作为SOA核心词汇之一,Mash- Up其实就在我们身边--例如,Google开放功能模块API接口的行为直接导致一系列以Google Earth为核心的第三方网络服务产生。  

  Web 2.0第三个部分--Social Web(网络社交),Web 2.0应用大大提高了终端用户的互动性,用户不再仅仅是服务的使用者,同时成为服务的创造参与者--WiKi、Blog、Tag、Podcast等用户交互行为让Web 2.0应用更能“吸引”用户,并且激发用户行为创造资源和内容。  

  如何才能创建一个成功的Web 2.0网站/产品?  

  亦有三点需要注意的问题。  

  首先,你需要规划一个出色的Ajax支持产品--Ajax特指一系列创建Web 2.0服务的关键技术,是创造丰富用户体验的技术基础,当然,在浏览器支持方面也要IE/火狐通吃。  
  其次,为你的产品选择合适的编程语言,能够完成你需要创立的网络服务--服务产品是Web 2.0关键,选择好合适的语言是产品的技术基础。  

  最后,拥有一个可迭代(Iterative)的软件架构,可非常方便地添加、部署、升级功能特性--这对拥有大量用户的情况下进行持续更新十分必要。”  

  文中关键词总结:  

  RIA--Ajax、Flash

  SOA--RSS、Feeds、Web Services、Mash-Up,API

  Social Web--Wiki、Blog、Tagging、Podcast

  Iterative

(驱动之家)

Posted on February 26, 2007 11:07 AM | | Comments (0) | TrackBacks (0)

“创建一个成功的企业的最好办法就是帮助别人赚钱。”Topix.net的Rich Skrenta解释AOL的政策时说到

  “我上许多的新闻网站,因为我不相信其中任何一个。”17岁的Sean这么解释他如何阅读在线新闻的。


  “当你上了大学以后,Myspace就算不上什么了”高中毕业生18岁的Sasha说。


  “在你发展的过程中建造,学习和犯错–你将会在做事情的过程中学到更多,而不是在你做这件事情之前。”37Signals的Jason Fried,他拥护迭代开发模式(iterative development)。


  “在5到10年内,媒体的价值将存在于那些培养用户的公司,而不是那些控制内容的公司。”Kleiner Perkins的前任合伙人Vinod Khosla说。


  “对我而言,透明度是一件具有竞争性的武器。”Sun微系统公司的CEO Jonathan Schwartz这么解释自己为什么写Blog。


  “Ebay有1.5亿的用户,理想的来说,就是1.5亿个人学会了如何相信陌生人。”Ebay的创始人Pierre Omidyar认为商业能为积极的社会变革带来动力。


  “我最喜欢Google,因为他们最干净。其他的网站则试图将你的注意力带走。去那些网站不会有任何收获。”18岁的Sasha这么解释为什么适应用户习惯比起强迫他们去适应你要来的聪明的多。


  “我们的成功与我们的总裁们的‘好主意’一点关系没有。”Google创始人Sergey Brin更喜欢群体的智慧。


  “我们96%的时间里不知道自己在做什么。”Flickr的创始人Stewart Butterfield认为剩下的4%足以让许多人非常快乐了。


  “雇用律师起诉对于那些普通公司来说,比起自己创意要简单的多”前任FCC的主席Michael Powell解释为什么那些提供内容服务的公司起诉他们的顾客。


  “我告诉我的工程师,不管你有多么聪明,在公司外有着更多比你聪明的人,所以我们需要提供给他们工具,让他们创新。”Omidyar也喜欢群体的智慧。


  传统上,人们认为越多越好。多的也许能行,但是它将会是痛苦、昂贵和冰冷的。看看那些一条路走到黑的人,无法与别人竞争。”Fried创造了几个新词。


  证明这个世界与原始的数码时代完全不同:假设你要买一个CD机,你要到哪去买?17岁的Sean困惑的说:“CD机是什么?”


  “你给一个公司越多的钱,他们越不可能成功。”Khosla说。 “一般的消费者并不知道浏览器、互联网以及搜索框之间的区别。”Mozilla基金会的Mitchell Baker提供了这样的观点。


  “我们认为任何来参加演唱会的人都是平等的,他们都参与到音乐的创作之中。”Grateful Dead乐队的Mickey Hart说道。


  “我们成功第一的要素是运气。我们跟随着自己内心而选择了搜索,因为它既有用也有趣。”Brin这么解释如何创立Google。(IT专家网)

Posted on February 26, 2007 10:51 AM | | Comments (0) | TrackBacks (0)

Diggclone-开源digg类程序
官方:http://www.talkingpixels.org/diggclone/index.php
演示:同digg.com类似,

Wodig-国内的开源digg类程序
官方:http://www.wodig.com/

Pligg-开源digg类程序
官方:http://www.pligg.com
中文演示:http://pligg.yesxp.net

Aroundme-开源社会化网络程序
官方:https://savannah.nongnu.org/projects/aroundme/
演示:http://www.barnraiser.org/demos/
(社会化网络程序通常都是收费的,相信这个是目前唯一免费的social netwokr项目啦)

Lilina–开源RSS聚合器
官方:http://lilina.sourceforge.net/
演示:http://www.chedong.com/

Gregarius–开源RSS聚合程序
演示:http://rss.gregarius.net/
官方:http://gregarius.net/
插件:http://plugins.gregarius.net/
风格:http://themes.gregarius.net/
论坛http://forums.gregarius.net/
帮助:http://wiki.gregarius.net/

Sa.bros.us-开源网络书签(PHP)
官方:https://sourceforge.net/projects/sabrosus/
汉化演示:http://www.sluke.cn/demo/monousuario/

Freedmarks -开源网络书签(ASP)(国内)
官方:http://www.purewhite.cn/
演示:http://www.freedmarks.com/

Scuttle -开源网络书签(PHP)
官方:http://sourceforge.net/projects/scuttle
演示:http://scuttle.org/

Yogurt-开源社会化网络门户
官方:http://yogurt.sourceforge.net/

eyeos---开元的WEBOS,
官方:http://www.eyeos.org
演示:http://www.earn8.net
有中文版本的。

周博通个人门户-开源个人门户
官方:http://www.potu.com/index/potu_opensource.php

开源的维客系统
mediawiki
官方网站 https://secure.wikimedia.org/wikipedia/zh/wiki/
下载 https://secure.wikimedia.org/wikipedia/zh/wiki/

openwiki
官方网站 http://www.openwiki.com/
下载 http://www.openwiki.com/

DokuWiki
官方网站 http://xoops.org.cn/modules/dokuwiki/doku.php
下载 http://xoops.org.cn/modules/dokuwiki/doku.php

HoodongWIKI-国内开源的维客系统
官方:http://www.hoodong.com

Posted on February 26, 2007 10:48 AM | | Comments (0) | TrackBacks (0)

  WEB2.0大潮似乎已经过去,但是以WEB2.0的理念构建的很多小网站,却仍旧如雨后春笋一般蓬勃发展。在2006年的一年里,很多人都在 绞尽脑汁的思考或者讨论WEB2.0类网站的盈利模式,但是究竟怎样才能盈利呢?2007年已经过去一个多月了,现在我们不妨再谈一下WEB2.0网站的 盈利模式。

  到目前为止,我们所熟知的互联网公司(或者依托互联网平台进行营销的企业)的盈利模式,不外乎下面几种:

  1、 大广告(特指品牌广告,如新浪、搜狐首页面、频道页面的旗帜、文字广告,包括栏目冠名等)

  2、 小广告(特指分类广告、竞价排名广告、窄告等,如GOOGEL、百度、天下互联、搜饭网等提供的主要广告模式)

  3、 道具,QQ秀(如果大家看过腾讯公司的财报,就会知道通过购买道具、交费会员能取得多大的收入)

  4、 EC(即E-Commerce 通过电子商务取得收入的方法,如淘宝网、ebay、万网等网站,无论是B2B还是B2C还是C2C,或者提供网络服务,收费方法多种多样,我们把这些都归纳为EC)

  5、 在线游戏(盛大、网易推出的游戏产品是典型的案例,还有很多免费的在线游戏也很流行,虽然对于玩家不收费,但是其中的特殊道具购买、晋级均可进行收费;其中的场景还可以卖给相关企业取得收入)

  6、 提供(代)收费服务(很多电影、歌曲下载的网站,考虑到很多类似网站涉及到版权问题,这里就不举例了;注册会员缴费享受服务的网站,如百合网等;帮助传统企业进行在线营销的网站,如e龙、携程等,这类盈利模式似乎与上述第4条有些类似,但是还是有细微的区别)

  7、 SP相关(太多了,空中网、掌上灵通、及众多的SP公司)

   以上就是几乎所有的互联网相关的收费模式了。门户网站有其中大部或者全部的营收方法,所以门户能够顺利的发展。而垂直网站,如果其中一点或者两点做得 专,做得细,同样可以获得稳定的收入。用排除法,如果你能想到除了上述营收模式的方法,也许就是WEB2.0网站的盈利模式。但是很明显,目前国内互联网 再没有其它的营收模式了。所以,我们自然认为,WEB2.0的网站也脱不开上述互联网营收模式的其中一种、或者兼有多种的收费模式。

  其实,由于每个网站的产品、构架、内容及受众均有不同,所以,结合自身网站产品特色考虑构建何种盈利模式至关重要。

   Myspace 的神话大家都已经知道,其实经常使用Myspace的用户都知道,对于网站的收入取得,并没有特别的好方法。它的网站构架和产品设计都是WEB2.0的理 念,但是为什么GOOGEL和YAHOO都会急于取得它的广告经营权呢?因为它们看重的是MYSPACE的及其庞大的用户,和可以与YAHOO媲美的 PV.有了这些,GOOGEL可以很轻易的在Myspace上做Adsense的广告,并且取得巨大的收入;它还可以在每个Myspace的个人页面上放 旗帜广告、文字链接广告,这点很容易理解。

  同样,Youtube凭借其庞大的视频文件库、详细的内容分类、巨大的每日视频播放量一样会吸引广告主的目光。想象一下,如果把所有的视频文件结尾都放上一个可口可乐的品牌广告,那每天这款广告的展示量,会远远超过全美热播电视片插片广告的展示量。

  但是这种盈利模式新么?不新,我们大家都熟知。

   所以,每当人们问到:WEB2.0的盈利模式是什么?我都会很头疼的告诉他,WEB2.0本来就没有特殊的盈利模式,WEB2.0类网站的当务之急,不 是考虑盈利模式,而是利用WEB2.0的先进理念,设计好其产品逻辑关系,最快的进行技术革新,自动、精准的内容分类,从而提供给其用户最佳的上网体验, 进一步获得最多的注册用户、最大的PV,才是构建好盈利模式的关键。如果再能利用病毒营销的方法在最短时间获得最多用户,更是成功的关键。说得更透彻些, 获得了最多的眼球,盈利模式自然就会有了,根本上就是WEB1.0的眼球经济的延续。

  6年前,王志东、张朝杨、丁磊在每一场演讲的时候,眼球经济是必须要提到的词汇。到了今天,眼球经济终于被证实为互联网的成功模式。我们讲,在WEB2.0的大潮中,众多网站的盈利模式,仍旧将会为眼球经济做最好的诠释。

Posted on February 25, 2007 6:15 PM | | Comments (0) | TrackBacks (0)

  导语:北京时间2月25日,国外媒体今天发表分析文章称,随着Google以价值16.5亿美元的股票收购YouTube,很多Web2.0创业者都面临着一个艰难的选择:应当将自己一手创建的公司出售,还是继续发展?

   很多业内人士认为,Facebook创始人马克·扎克伯格(Mark Zuckerberg)现在正坐在一座金矿上,他很有可能成为硅谷下一个亿万富翁。不过,如果错失机会,今年仅有22岁的扎克伯格也有可能变得一文不名。 Facebook是美国第二大社交网站,预计今年的营收将超过1亿美元。由于Facebook的发展前景看好,扎克伯格去年多次拒绝了其它公司的收购请 求,其中包括雅虎10亿美元的报价。他说:“与出售相比,我们更倾向于自我发展。我们认为Facebook还有更大的价值。”

  面临艰难选择

   与扎克伯格一样,很多Web2.0创业者都面临着发展还是出售的艰难抉择。除Facebook之外,传闻中可能会成为收购目标的Web2.0公司还包括 视频共享网站Metacafe和图片共享网站Photobucket。对于这些公司而言,如果选择继续发展,Friendster.com可能会成为它们 的前车之鉴。Friendster.com是美国第一个大型社交网站,该公司一直坚持自我发展的道路,而没有选择出售。现在看来,这是硅谷最失误的决策之 一。

  由于从电视、报纸和其它传统媒体吸引来大量用户,新兴Web2.0公司的热度持续增长,其中尤以视频共享和社交网站最为突出。为了 涉足这一高增长领域,很多传统媒体公司都展开了收购。受此影响,Web2.0公司的售价“水涨船高”。2005年,新闻集团以5.8亿美元的价格收购了美 国第一大社交网站MySpace;2006年,Google以价值16.5亿美元的股票收购了美国第一大视频共享网站YouTube。

  Web2.0公司价格攀升

   硅谷投资者雷德·霍夫曼(Reid Hoffman)表示:“目前还有如此多的Web2.0公司没有被收购,这令我非常吃惊。再过一两年,这些公司的价格肯定会更高。”根据Thomson Financial和美国风险投资协会公布的数据,2006年有风投背景的新兴公司平均售价为1.14亿美元,比2005年增长19%,达到2000年以 来的新高。在互联网泡沫时期,这一数字曾经高达3.37亿美元。

  如果这一趋势延续下去,扎克伯格拒绝雅虎和维亚康母的报价当然是一个明 智的选择。如果Facebook实现自己的财务目标,该公司的售价将超过10亿美元,或者也可以像Google、雅虎、eBay和亚马逊那样,通过首次公 开招股获得更多收益。Facebook最终一定会走上出售或上市的道路,因为该公司的早期投资者希望从中获益。2004年,扎克伯格在创建 Facebook时获得了3850万美元的启动资金,其中绝大部分是风险投资。

  扎克伯格可以灵活地选择出售或上市的时间,因为 Facebook已经实现盈利。他说:“我们并不排除出售或上市的可能,但这并不是Facebook的最终目标。我们的目标是为用户提供革命性的产品,推 动公司继续向前发展。”有消息称,扎克伯格持有Facebook三分之一的股份。Netscape联合创始人马克·安德里森(Marc Andreessen)也认为,未来一两年Facebook的价值将继续增长。他说:“Facebook的策略十分明智。既然拥有社交网络这样巨大的市 场,就不必急于将公司出售。如果MySpace继续保持独立,现在的价值将超过50亿美元。”

  失败前车之鉴

   当然,如果最终陷入困境,Facebook将重蹈Friendster的覆辙。Friendster曾经是美国最热门的社交网站之一,由于对自身的发展 前景充满信心,该公司于2003年拒绝了Google的收购请求。如果当初接受Google的报价,Friendster创始人乔纳森·艾布拉姆 (Jonathan Abrams)和其它早期投资者可以获得价值3000万美元的股票,而这些股票目前的价值已经超过10亿美元。

  由 于同风险投资者不和,艾布拉姆于2004年离开了Friendster。自那之后,Friendster已经换了四任CEO,但一直未能重现当年辉煌。根 据市场研究公司comScore Media Metrix公布的最新数据,Friendster仅吸引了130万名美国独立访问者,远远落后于MySpace(6150万人)和Facebook (1900万人),仅同Bebo.com、MyYearbook.com 和Hi5.com等新兴公司相当。纽约投资银行家肯·马尔林(Ken Marlin)表示:“很多公司因为等待时间过久而错过了出售的最佳时机,我认为互联网收购热潮至多再持续一到两年。”

  其它潜在收购目标

   Google去年10月宣布收购YouTube之后,Metacafe联合创始人埃里克·泽尔尼克(Arik Czerniak)随即表示:“我们肯定会继续发展自己的业务。”但不久之前,泽尔尼克辞去了Metacafe首席执行长一职,继任者为前电子艺界高管埃 里克·汉克伯格(Erick Hachenburg)。泽尔尼克目前仍然是Metacafe的主要股东之一。

  Photobucket创 始人阿列克斯·韦尔奇(Alex Welch)不久前表示,该公司也倾向于独立发展。他预计,Photobucket今年的注册用户人数有望增长近一倍,达到6000万人。自2003年创 建以来,Photobucket已经吸引了1500万美元的风险投资。Photobucket目前共有3500万名用户,每天上传的图片数量达到700万 张,视频片段数量达到3.5万个,仅次于MySpace和YouTube。

  其它可能会成为收购目标的Web2.0公司还包括:虚拟世界 《第二人生》的运营商Linden Research、聚合新闻网站Digg和图片共享网站Slide。不过,最吸引潜在收购者的Web2.0公司仍然是Facebook,它从大学起步,目 前已经发展成为美国最热门的社交网站之一。Facebook目前共有1700万名注册用户,其中绝大部分在35岁以下。由于Facebook每天的页面访 问量达到近10亿次,因此吸引了广告客户的高度关注。去年夏天,Facebook同微软建立了广告合作伙伴关系,这意味着该公司可以获得稳定的广告营收。 (奥托)

Posted on February 25, 2007 5:52 PM | | Comments (0) | TrackBacks (0)

    (台北特稿)网络时代瞬息万变,正当许多人还未完全了解Web 2.0是什么的时候,Web 3.0已然悄悄现身,准备带领网络世界迈向全新的领域。
    网络从最早的Web 1.0逐步发展到Web 2.0,再到即将来临的与Web 3.0。Web 2.0和Web 3.0之间究竟有何不同?对我们的生活又会产生什么样的影响?


    一九八九年,任职于欧洲科学机构的英国专家柏内兹李发明了网页程式语法,揭开网络时代序幕,他在去年第十五届全球资讯网国际会议中指出:「网络只会有越来越多革命。」但是,他却当今广为流传的Web 2.0这个名词不表认同。
   
    诚如许多专家所言,Web 2.0并非一种技术标准,而是一种广泛的代称,Web 1.0意味着使用者打开浏览器上网浏览网页,单方面汲取或下载自己有兴趣的文字或影音资讯。Web 2.0则加入互动元素,网络族可以根据本身的需求量身制作网页,与其他人进行互动,同时以更多的多媒体资讯丰富网页内容。
   
    社交功能在Web 2.0便因此大大提升,譬如当今已经相当盛行的部落格 (网志),奇摩知识,及影音分享网站Youtube等等。
   
    那么,Web 3.0究竟又是什么?根据柏内兹李所描绘的蓝图,自Web 1.0时期便采用的mark-up网页语法,将能透过网络渗透到无数个规格一致的资料库,进行交互参照(cross-reference),提供使用者更 为完善的资讯,简单来说,便是举一反三。
   
    举例来说,用户在网页上点选即将参加的讨论会网页连结,这个动作看似简单,不过却能将讨论会时间、地点的资讯同步传给用户所持有的PDA;讨论会地点的经纬度、高度,也将传到用户的GPS卫星定位系统,而与会来宾资料、生平背景,也将一并传送至即时通讯软体上。
   
    诚如柏内兹李所说,大家都在问Web 3.0是什么,尽管业界仍无法提供具体描述,不过他替Web 3.0下了一个注脚:把Web 2.0所有的东西重新整理,结合语义网络和庞大资料空间,所产生的无以计数的资料来源。
   
    Web 3.0结合网络、网页、超连结、媒体与资料库,更加聪明,能自动传递比今天单纯浏览网页更多的讯息。此外,它同样也不是一种规格或技术,而是网络演变过程的一种通称,代表网络在演化发展之际与用户互动的紧密结合。

Posted on February 24, 2007 12:48 PM | | Comments (0) | TrackBacks (0)

  导语:美国《Business 2.0》杂志近日评出了2007年25大网络新锐,涵盖了目前最具发展前景、最热门的新兴Web2.0公司,包括Stumbleupon、Slide和Bebo等等。

  12个月之前,《Business 2.0》评出了2006年25大网络新锐,这是该杂志首次推出这一榜单。Web2.0当时的发展前景一片光明,硬件价格持续走低、宽带继续普及、开放源代 码渐成潮流、以及风险投资公司再次为硅谷“输血”,这些都是Web2.0公司的利好因素。在《Business 2.0》选出的25家公司中,Digg、Trulia、Technorati、JotSpot和Writely都获得了成功。当然,最为成功的还是被 Google以16.5亿美元收购的视频共享网站YouTube。

  不论好坏,Web2.0都于2006年成为了主流,这使评选2007年网络新锐变得更加艰难。August Capital公司合伙人大卫·霍尼克(David Hornik)表示:“对于Web2.0公司而言,2007年是至关重要的一年,要么获得成功,要么以失败告终。毫无疑问,很多公司都将退出市场。”尽管 风险投资总额持续增长,但新兴Web2.0公司要获得投资非常困难。天使投资者杰夫·克拉维尔(Jeff Clavier)表示:“2007年我将削减投资,因为已经存在太多泡沫。”(摩尔)

  《Business 2.0》评出的2007年25大网络新锐如下:

  1.www.stumbleupon.com(社交媒体)

  公司总部:旧金山

  员工人数:12人

  创建时间:2001年

  创始人:格夫·史密斯(Geoff Smith)、加里特·坎普(Garrett Camp)、贾斯丁·拉弗朗斯(Justin LaFrance)

  商业模式:广告、付费用户

  2007年目标:推出内容控制和移动视频推荐等新功能

  2.www.slide.com(社交媒体)

  公司总部:旧金山

  员工人数:45人

  创建时间:2004年

  创始人:马克斯·莱齐恩(Max Levchin)

  商业模式:广告、付费用户

  2007年目标:增加员工、进军亚洲市场、加入手机功能

  3.www.bebo.com(社交媒体)

  公司总部:旧金山

  员工人数:28人

  创建时间:2005年

  创始人:迈克尔·波奇(Michael Birch)、西奥琪·波奇(Xochi Birch)

  商业模式:广告

  2007年目标:推广Bebo作家频道、招聘销售团队

  4.www.meebo.com(社交媒体)

  员工人数:12人

  创始人:辛迪·简(Sandy Jen)、塞斯·斯特恩伯格(Seth Sternberg)、埃莱尼·维利(Elaine Wherry)

  商业模式:广告

  2007年目标:增加员工

  5.www.wikia.com(社交媒体)

  公司总部:圣马蒂奥

  员工人数:33人

  创建时间:2004年

  创始人:安吉拉·比斯利(Angela Beesley)、吉米·维尔斯(Jimmy Wales)

  商业模式:广告

  2007年目标:增加员工、进军日本市场、支持更多语言、开发开放源代码搜索引擎

  6.www.joost.com(视频)

  公司总部:卢森堡

  员工人数:100人

  创建时间:2006年

  创始人:贾努斯·弗里斯(Janus Friis)、尼克拉斯·曾特罗姆(Niklas Zennstrom)

  商业模式:广告

  2007年目标:签署更多内容协议

  7.www.dabble.com(视频)

  公司总部:伯克利

  员工人数:11人

  创建时间:2005年

  创始人:玛丽·霍德尔(Mary Hodder)

  商业模式:广告

  2007年目标:增加员工和新功能

  8.www.metacafe.com(视频)

  公司总部:帕罗阿尔托

  员工人数:65人

  创建时间:2003年

  创始人:埃里克·汉切伯格(Erick Hachenburg)

  商业模式:广告

  2007年目标:增加员工、同电影公司合作

  9.www.revision3.com(视频)

  公司总部:旧金山

  员工人数:7人

  创建时间:2005年

  创始人:杰·阿德尔森(Jay Adelson)

  商业模式:广告

  2007年目标:增加新节目

  10.www.blip.tv(视频)

  公司总部:纽约

  员工人数:12人

  创建时间:2005年

  创始人:迪纳·卡普兰(Dina Kaplan)、迈克·哈代克(Mike Hudack)

  商业模式:授权、广告

  2007年目标:增加员工

  11.www.fon.com(移动)

  公司总部:马德里

  员工人数:90人

  创建时间:2006年

  创始人:马丁·瓦萨维斯基(Martin Varsavsky)

  商业模式:付费用户、路由器销售

  2007年目标:同美国移动通信运营商谈判

  12.www.loopt.com(移动)

  公司总部:帕罗阿尔托

  员工人数:18人

  创建时间:2005年

  创始人:萨姆·奥特曼(Sam Altman)

  商业模式:广告、付费用户

  2007年目标:同赞助商签约、同美国二级运营商谈判

  13.www.getmobio.com(移动)

  公司总部:库珀蒂诺

  员工人数:40人

  创建时间:2005年

  创始人:拉姆尼克·巴辛(Ramneek Bhasin)

  商业模式:广告

  2007年目标:推出服务

  14.www.tinypictures.com(移动)

  公司总部:旧金山

  员工人数:12人

  创建时间:2005年

  创始人:约翰·波伊森(John Poisson)

  商业模式:客户端下载、广告

  2007年目标:增加用户、同更多运营商签约、加入高级付费服务

  15.www.soonr.com(移动)

  公司总部:坎普贝尔

  员工人数:30人

  创建时间:2005年

  创始人:马丁·弗里德-尼尔森(Martin Frid-Nielsen)

  商业模式:付费用户

  2007年目标:推出高级服务

  16.www.turn.com(广告)

  公司总部:圣马蒂奥

  员工人数:26人

  创建时间:2005年

  创始人:吉姆·巴莱特(Jim Barrett)、约翰·埃里斯(John Ellis)

  商业模式:广告

  2007年目标:同更多发行人签约

  17.www.adify.com(广告)

  公司总部:圣布鲁诺

  员工人数:40人

  创建时间:2005年

  创始人:拉里·布雷曼(Larry Braitman)

  商业模式:广告

  2007年目标:同更多发行人签约

  18.www.admob.com(广告)

  公司总部:圣马蒂奥

  员工人数:22人

  创建时间:2006年

  创始人:奥马尔·哈姆伊(Omar Hamoui)

  商业模式:广告

  2007年目标:开发手机交户广告技术

  19.www.spotrunner.com(广告)

  公司总部:洛杉矶

  员工人数:150人

  创建时间:2004年

  创始人:尼克·格鲁夫(Nick Grouf)、大卫·维克斯曼(David Waxman)

  商业模式:广告

  2007年目标:进军电视、广播等其它媒体

  20.www.vitrue.com(广告)

  公司总部:亚特兰大

  员工人数:38人

  创建时间:2006年

  创始人:雷吉·布拉福德(Reggie Bradford)

  商业模式:广告

  2007年目标:开发面向特定媒体客户的新网站

  21.www.successfactors.com(企业)

  公司总部:圣马蒂奥

  员工人数:约为400人

  创建时间:2001年

  创始人:拉斯·达尔加德(Lars Dalgaard)

  商业模式:付费用户

  2007年目标:进军亚洲和欧洲市场、开发面向特定行业的网络服务

  22.www.janrain.com(企业)

  公司总部:波特兰

  员工人数:11人

  创建时间:2006年

  创始人:斯科特·凯维顿(Scott Kveton)

  商业模式:广告

  2007年目标:同大网站合作、推出新产品

  23.www.logoworks.com(企业)

  公司总部:林顿

  员工人数:120人

  创建时间:2001年

  创始人:摩根·林奇(Morgan Lynch)

  商业模式:服务费用

  2007年目标:向小公司销售服务

  24.www.reardencommerce.com(企业)

  公司总部:福斯特城

  员工人数:155人

  创建时间:2000年

  创始人:帕特里克·格拉迪(Patrick Grady)

  商业模式:付费用户

  2007年目标:进军移动市场

  25.www.simulscribe.com(企业)

  公司总部:纽约

  员工人数:8人

  创建时间:2003年

  创始人:詹姆斯·西米诺夫(James Siminoff)

  商业模式:付费用户

  2007年目标:同全国性(美国)运营商合作

Posted on February 24, 2007 12:46 PM | | Comments (0) | TrackBacks (0)

Introduction

There are a variety of approaches to interoperability between .NET and Java. One of the most popular approaches is to use web services and craft WSDL and XML Schema that can work in both environments. As you would expect, web services are best suited for internet based applications. If you are writing an intranet application that works on a LAN within a single department or organization then other middleware technologies become attractive. Specifically, message oriented middleware (MOM) has long been a popular choice to integrate diverse platforms within a company. Using MOM as a basis for communication between .NET and Java this article demonstrates interoperability between a .NET client and a Java middle tier in the context of a simple stock application running on a local LAN. The implementation uses the JMS support in the Spring framework, available for .NET as well as Java, to provide a common programming model across both tiers of the application.

Why Messaging?

In many ways, message oriented middleware can be considered an elder-statesman of interoperability. Vendors such as IBM and TIBCO have been providing messaging middleware for over 20 years that work on heterogeneous operating systems and have multiple language bindings. In 1999 the Java Message Service (JMS) specification breathed new life into the messaging space by defining a common set of APIs and behavior for messaging vendors to implement. Given the heritage, it is not surprising that JMS implementations run on multiple operating systems and most, but not all, provide a .NET API 1. The examples in this article use TIBCO's JMS implementation which provides Java, .NET, .NET Compact Framework, and C++ client APIs. As a side note, there are a few options available to access JMS from .NET even if your preferred vendor does not provide a .NET client. One of these is to use an interoperability product such as JNBridge 2 or Codemesh 3.

While interoperability is a compelling reason to use messaging there are a variety of other areas that make it a very attractive, if not a de facto, choice for use in an application's architecture. In short, MOM excels in providing asynchronous communication between processes, publish-subscribe (one-to-many) message delivery semantics, and high levels of reliability. If your application can benefit from these features you will quite often find a messaging solution to be a natural fit. If your company is already using messaging for some of these reasons but only within Java or C++ based applications, extending its role to include .NET clients a logical extension of the existing architecture. No matter the motivating factors, creating a JMS based solution has its own learning curve and collection of best practices. This article uses the Spring framework on .NET and Java to demonstrate how to quickly get started creating JMS applications. It also provides guidance on some of the issues that naturally arise when using messaging to communicate between .NET and Java.

Introducing Spring.NET

While most people are familiar with the Spring Framework for building Java applications many are not aware of its .NET counterpart, Spring.NET 4. Spring.NET is a .NET version of the Spring framework built "from the ground up" in C# that carries over to .NET the Spring design and approach to application development. It contains the same set of core functionality as its Java counterparts, i.e. Inversion of Control, Aspect Oriented Programming, Web Framework, RPC Exporters, Declarative Transaction Management, and an ADO.NET framework. In short, if you are already a "Spring.Java" user, you will feel right at home with Spring.NET.

Unlike Spring.Java which bundles many third party libraries in its base offing, Spring.NET separates support for third party libraries into separately downloadable modules. One of these modules provides JMS support based on TIBCO's JMS implementation. If you would like to run the article's examples you should download an evaluation version of TIBCO EMS (Enterprise Message Service) from TIBCO's web site 5.

A natural question to ask is "Why does Spring.NET just support TIBCO's JMS and not <insert provider name here>?" There is no fundamental reason why other vendors are not supported. It has just been a practical reason at this time since there isn't a de facto JMS API in .NET that each vendor is required to implement. As such, each vendor ends up creating their own .NET inspired copy of the Java JMS API. The open source project .Net Message Service API (NMS) goal is to provide such a common API and it will very likely be used for future JMS work in Spring.NET 6. Since I am very familiar with TIBCO's JMS product I selected it out of convenience as the first provider to support in Spring.NET.

Messaging with the Spring Framework

The goals of Spring's JMS support are to raise the level of abstraction when using JMS and to support messaging best practices. Spring achieves these goals by providing easy to use messaging classes that make common operations simple and creating a "plain old object" (POJO/POCO) programming model for messaging via the use of MessageConverters. MessageConverters are responsible for conversion between JMS messages and "plain old objects" and are identical in spirit to XML/Object mappers but with a JMS twist. Using message converters give you the benefit of keeping JMS artifacts constrained to the outermost layers of your application thus allowing the bulk of your application to remain technology agnostic. Should you decide to switch middleware, the refactoring required will be significantly less than if the JMS MapMessage found its way into your business processing.

Like JDBC, JMS is a low level API requiring you to create and manage multiple intermediary objects even for the most basic of JMS tasks. For sending messages, Spring's JmsTemplate manages these intermediary objects on your behalf and makes common JMS operations "one-liners". On the receiving side, Spring's MessageListenerContainer implementations allow you to easily create the infrastructure to support concurrent asynchronous consumption of messages. Both JmsTemplate and MessageListenerContainer can be associated with a MessageConverter to translate between the JMS and POJO/POCO worlds.

JmsTemplate, MessageListenerContainers, and MessageConverters are the central artifacts in Spring's JMS support. This article uses them extensively and explains them in some detail but is not a definitive reference. For more details refer to the Spring reference documentation or another Spring resource.

Hello World in Spring JMS

Before diving into the details of interoperability and Spring JMS, here is a quick example in .NET that sends a "Hello World" TextMessage to the JMS queue named "test.queue" using JmsTemplate.

ConnectionFactory factory = new ConnectionFactory("tcp://localhost:7222");
JmsTemplate template = new JmsTemplate(factory);
template.ConvertAndSend("test.queue", "Hello world!");

If you are all familiar with the JMS API, you can immediately see how simple it is to use JmsTemplate as compared to direct use of the JMS API. This is primarily because JmsTemplate is providing all the boilerplate resource management of JMS Connections, Sessions and MessageProducers that you would otherwise need to code. It also adds other conveniences such as translating checked exceptions to unchecked in Java, resolving string based JMS destinations to JMS destination objects, and delegating to a MessageConverter to convert objects to JMS messages. If you want to send messages without a conversion JmsTemplate has a simple Send method.

When calling the ConvertAndSend method, JmsTemplate uses the default MessageConverter implementation, SimpleMessageConverter, to convert the string "Hello World!" to a JMS TextMessage. SimpleMessageConverter also supports converting between a byte array and a ByteMessage and a hash table and a JMS MapMessage. Providing your own custom MessageConverter implementation lies at the heart of creating a complex Spring JMS application. The general approach is to create a converter for objects that you are already using in your application code and simply want to marhsall/unmarshall them onto JMS.

JMS Interoperability in a Nutshell

With Spring as a common framework on both .NET and Java the issues around interoperability boil down to the implementation of compatible MessageConverters and "plain old objects" that are exchanged between .NET and Java. For convenience let's call these plain old objects "business objects". They may in fact be full fledged domain objects, data transfer objects, or a UI-optimized version of your domain objects suitable for presentation. In this approach the business objects themselves essentially become the data contract between the two tiers. The fields and properties included as part of that data contract is dependent on the implementation of the converter. Note that specific data types are not explicitly shared. The data types on each side of the fence need to be compatible with each other only in as much as their associated message converter can successfully perform its job.

While this approach is certainly less prescriptive than using up front contracts as in web services there are several techniques that one can use to significantly constrain the data that is exchanged and reduce trivial mismatches. One non technological issue that helps in this regard is that in intranet or departmental applications it is often the same group (or even person) that develops both the .NET client and Java middle tier. Communication and frequent integration testing can therefore substitute to a large extent the use of up front contacts intended for consumption by disparate development groups. If you are a fan of using up front formal contracts to define the interaction between tiers, then the proposed JMS approach will probably not be to your liking. That being said, this looser and certainly less standardized approach to interoperability has been successfully used to my knowledge in several projects.

The following sections take an increasingly sophisticated approach to using MessageConverters and keeping business objects in sync between .NET and Java. The example applications starts off by using the SimpleMessageConverter included with Spring to exchange hash tables. Then we create a .NET and Java implementation of a simple business object and a corresponding pair of custom MessageConverters. Finally, we will show some techniques to reduce the duplication of effort involved in creating converters and business objects by hand on each platform through the use of a source code translator and a general "all-purpose" MessageConverter than converts arbitrary object types. The various pros and cons of each approach are discussed along the way.

Stock Trading Example

The context of the example is a simplified stock trading application. Our application will have three main pieces of functionality - the distribution of real-time market data information, the creation of new trades, and the retrieval of a portfolio of trades.

Starting with the distribution of market data, we create the JMS infrastructure to send messages from the Java middle tier to the .NET client. On the Java middle tier a JmsTemplate is created for sending messages and on the client side a SimpleMessageListenerContainer for receiving messages. Both classes use an instance of SimpleMessageConverter by default. Since market data is essentially a collection of key value pairs, i.e. PRICE=28.5, TICKER="CSCO", it is reasonable to use the default converter and exchange a simple hash table between .NET/Java.

The configuration for both JmsTemplate and SimpleMessageListenerContainer requires a JMS connection factory and the JMS destination name and type. SimpleMessageListenerContainer also requires a reference to an implementation of a JMS MessageListener callback for processing the messages. Spring provides a MessageListenerAdapter class that implements the JMS MessageListener interface and uses a MessageConverter to convert the received JMS Message to an object. The MessageListenerAdapter then uses this object to call a method on a user provided handler class that has a matching method signature.

The preceding flow is best explained with an example. If the MessageListenerAdapter is configured to use the SimpleMessageConverter, then an incoming JMS MapMessage will be converted to a .NET IDictionary and a method on the handler class with the signature "void handle(IDictionary data)" will be invoked. If the converter produced an object of type Trade, then the handler class must contain a method named handle(Trade trade). The sequence diagram below shows the flow of events.

This delegation scheme is what is commonly referred to in the Java world as "Message-Driven POJOs" or "Message-Driven objects" since it is a "plain old object" and not a JMS MessageListener that acts as the messaging callback. One advantage of this approach is that you can easily create integration style test cases that exercise the flow of the application by directly calling the handler methods. Another advantage is that the MessageListenerAdapter acts as a replacement for if/else or switch/case blocks commonly found in messaging applications. SimpleMessageListenerContainer contains many other features, such as automatic sending of a reply message based on the return value of the handler method and is intended to be subclassed for customization of the processing flow. Refer to the Spring reference documentation for more details.

The Spring configuration for these objects is shown below.

The middle tier publisher:

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory"><ref bean="connectionFactory"/></property>
<property name="pubSubDomain" value="true"/>
<property name="defaultDestinationName" value="APP.STOCK"/>
</bean>

and client consumer

<object id="jmsContainer"
type="Spring.Messaging.Tibco.Ems.Listener.SimpleMessageListenerContainer, Spring.Messaging.Tibco.Ems">
<property name="ConnectionFactory" ref="connectionFactory"/>
<property name="PubSubDomain" value="true"/>
<property name="DestinationName" value="APP.STOCK"/>
<property name="ConcurrentConsumers" value="1"/>
<property name="MessageListener" ref="messageListenerAdapter"/>
</object>

<object
id="messageListenerAdapter"
type="Spring.Messaging.Tibco.Ems.Listener.Adapter.MessageListenerAdapter, Spring.Messaging.Tibco.Ems">
<property name="DelegateObject">
<object type="Spring.JmsInterop.Handlers.SimpleHandler, Spring.JmsInterop"/>
</property>
<property name="DefaultListenerMethod" value="HandleObject"/>
</object>

Note that Spring.NET uses the XML element 'object' instead of 'bean' to define object definitions. The handler object has the unfortunate name from the .NET perspective of "DelegateObject". This property has nothing to do with .NET delegates.

All data sent to the client is on the JMS topic APP.STOCK and all data sent from the client to the middle tier is on the JMS queue APP.STOCK.REQUEST.

Sending a JMS message is straightforward as shown below with some contrived market data

Map marketData = new HashMap();
marketData.Add("TICKER","CSCO");
marketData.Add("PRICE", new Float(23.54));
... jmsTemplate.send(marketData);

On the receiving side the processing is done inside the handle method of StockAppHandler.

public class SimpleHandler
{
public void HandleObject(IDictionary data)
{
log.InfoFormat("Received market data. Ticker = {0}, Price = {1}", data["TICKER"], data["PRICE"]);
// forward to controller to update view
. . .

}
}

This minimal amount of infrastructure code is all that is needed to get started. However, while exchanging a hash table is easy and supported out of the box, it is only appropriate to use in the most simple of interoperability scenarios. I take simple to mean less than ~5 data exchanges each with less than ~10 key, value pairs. The reason it doesn't scale to more complex scenarios is fairly obvious, the data contract is too loose and it becomes hard to ensure there are no mismatches in key, value pairs between the two tiers. A more natural approach is to use classes to encapsulate the data. The classes themselves can ensure to a large extent that the data content is correct, for example by providing parameterized constructors, or through the use of third party validation libraries. Validation issues aside, it is simply easier to deal directly with the objects used in the middle tier for business processing as compared to introducing hash tables to meet the requirements of the MessageConverter. As such, in order to work directly with objects, custom message converters need to be created and plugged into the Spring JMS infrastructure.

Using a Custom Converter

Spring's MessageConverter interface is very simple. It contains just the two methods shown below,

public interface IMessageConverter
{
Message ToMessage(object objectToConvert, .Session session);
object FromMessage(Message message);
}

In case of failure to convert a message, a MessageConversionException is thrown.

We will create a custom message converter to send a trade creation request message from the client to the middle tier. The class TradeRequest collects the information entered by the user when filling in a create trade from and also contains a validation method. The TradeRequest class contains the following properties, Symbol, # shares, price, OrderType, AccountName, action (buy/sell), requestid, and user name. The converter implementation is straightforward to code as it simply adds these properties to corresponding fields of a JMS MapMessage. The implementation of "ToMessage" on the client is shown below.

public class TradeRequestConverter : IMessageConverter
{
public Message ToMessage(object objectToConvert, Session session)
{
TradeRequest tradeRequest = objectToConvert as TradeRequest;
if (tradeRequest == null)
{
throw new MessageConversionException("TradeRequestConverter can not convert object of type " +
objectToConvert.GetType());
}
try
{
MapMessage mm = session.CreateMapMessage();
mm.SetString("accountName", tradeRequest.AccountName);
mm.SetBoolean("buyRequest", tradeRequest.BuyRequest);
mm.SetString("orderType", tradeRequest.OrderType);
mm.SetDouble("price", tradeRequest.Price);
mm.SetLong("quantity", tradeRequest.Quantity);
mm.SetString("requestId", tradeRequest.RequestId);
mm.SetString("ticker", tradeRequest.Ticker);
mm.SetString("username", tradeRequest.UserName);

return mm;

} catch (Exception e)
{
throw new MessageConversionException("Could not convert TradeRequest to message", e);
}
}

... (FromMessage not shown)
}

The "FromMessage" implementation simply creates a TradeRequest object and sets its properties using values obtained from the message. See the code for details. Note that if you are using properties to marshall/unmarshall the data make sure there are no side effects of calling these properties in a marshalling context.

To send data from the client to the middle tier we need to create a mirror image of the previous JMS infrastructure, a JmsTemplate in the client and a SimpleMessageListenerContainer in the middle tier. The middle tier's message container is configured to use a Java version of the TradeRequestConverter and a message handler class, StockAppHandler, which has a method "void handle(TradeRequest). The client configuration is shown below.

<object name="jmsTemplate" type="Spring...JmsTemplate, Spring.Messaging.Tibco.Ems">
<property name="ConnectionFactory" ref="connectionFactory"/>
<property name="DefaultDestinationName" value="APP.STOCK.REQUEST"/>
<property name="MessageConverter">
<object type="Spring.JmsInterop.Converters.TradeRequestConverter, Spring.JmsInterop"/>
</property>
</object>

The hard coded client use of the template is shown below.

public void SendTradeRequest()
{
TradeRequest tradeRequest = new TradeRequest();
tradeRequest.AccountName = "ACCT-123";
tradeRequest.BuyRequest = true;
tradeRequest.OrderType = "MARKET";
tradeRequest.Quantity = 314000000;
tradeRequest.RequestId = "REQ-1";
tradeRequest.Ticker = "CSCO";
tradeRequest.UserName = "Joe Trader";

jmsTemplate.ConvertAndSend(tradeRequest);
}

A sequence diagram for sending a message on the client is shown below:

The middle tier configuration is shown below along with a simple implemention of the POJO message handler.

<bean id="jmsContainer" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destinationName" value="APP.STOCK.REQUEST"/>
<property name="concurrentConsumers" value="10"/>
<property name="messageListener" ref="messageListenerAdapter"/>
</bean>

<bean id="messageListenerAdapter" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<property name="delegate">
<bean class="org.spring.jmsinterop.handlers.StockAppHandler"/>
</property>
<property name="defaultListenerMethod" value="handleObject"/>
<property name="messageConverter">
<bean class="org.spring.jmsinterop.converters.TradeRequestConverter"/>
</property>
</bean>

public class StockAppHandler {
protected final Log logger = LogFactory.getLog(getClass());
public void handleObject(TradeRequest tradeRequest)
{
logger.info("Recieved TradeRequest object");
}
}

The advantage of this approach is that client and middle tier developers can essentially "share" a class, in this case TradeRequest, which contains both data and functionality. One disadvantage to sharing classes, especially in large projects, is the duplication of effort in creating pairs of business objects and converters. If the data exchanged between tiers is relatively stable, this duplication can be considered a one time cost. However, if the data exchanged is changing on a weekly or daily basis as is commonly the case during active development, it can become a tedious task.

An effective way to deal with these issues is to create a single all-purpose MessageConverter than can handle multiple message types and to write the business objects once in Java and use a source code conversion tool to get the C# equivalent. The next section discusses this approach is more detail.

General Message Converter

As you can see in the previous listing of TradeRequestConverter the implementation is calling out *not* to be coded by hand. A solution that uses code generation or reflection can be used instead. The example code includes an 'XStream' inspired reflection based converter, ReflectionMessageConverter, which can convert a wide range of objects. This converter has the following features and limitations.

  • All objects are marshaled by value via reflection of all field members. This choice was taken to avoid any side effects due to additional code that may reside in property setter/getters. (Adding support to control which fields are included/excluded either through external configuration or attributes/annotations similar to WCF's DataContract/DataMember attributes would be a nice enhancement.)
  • The field types supported are: primitives (int, string, etc), Date, Timestamp, as well as objects composed of primitives, hashmaps, and collections (non-generic) of objects. Circular references are detected.
  • The wire representation is a JMS MapMessage with an easy to understand format. This allows for other processes that do not use this converter to easily participate in the JMS message exchanges.
  • The JMS provider must support nested map messages to convert collection classes.
  • Provides the ability to register additional converters for arbitrary object types.
  • Reduced coupling between .NET/Java since a converter does not need to know their alter-ego type. A type identifier is placed in the message that indicates which type to create. On each side the type identifier is independently mapped to a specific data type. As a convenience the case where all business objects are named similarly but only differ in terms of the namespace/package is handled with minimal configuration

The converter should be considered a work in progress and updates to it will be available on the Spring.NET website.

Some other alternative approaches to a single all purpose MessageConverter is to delegate the hard work to an existing marshalling technology. For example, you can delegate an XML/Object converter and send the XML string as the payload of the JMS Message. Recently Tangosol introduced a platform and language-neutral Portable Object Format (POF) as part of Coherence that could also be used for this same purpose.

The example application uses the ReflectionMessageConverter to send a Trade object to the client in response to the TradeRequest. As an example of sending a more complex object the client sends a PortfolioRequest and will receive a Portfolio object that contains a User and a list of Trade objects in response. The configuration of the converters is shown below.

<object name="reflectionMessageConverter"
type="Spring.JmsInterop.Converters.ReflectionMessageConverter, Spring.JmsInterop">
property name="ConversionContext" ref="conversionContext"/>
</object>

<object name="conversionContext" type="Spring.JmsInterop.Converters.ConversionContext, Spring.JmsInterop">
<property name="TypeMapper" ref="typeMapper"/>
</object>

<object name="typeMapper" type="Spring.JmsInterop.Converters.SimpleTypeMapper, Spring.JmsInterop">

<!-- use simple configuation style -->
<property name="DefaultNamespace" value="Spring.JmsInterop.Bo"/>
<property name="DefaultAssemblyName" value="Spring.JmsInterop"/>

<!--
<property name="IdTypeMapping">
<dictionary>
<entry key="1" value="Spring.JmsInterop.Bo.Trade, Spring.JmsInterop"/>
</dictionary>
</property>

-->
</object>

The simple configuration style of the TypeMapper used above uses the last part of the fully qualified type name as the type identifier that is placed into the message on the wire when marshalling. The DefaultNamespace and DefaultAssemblyName properties are used to construct the fully qualified type name when unmarshalling. The corresponding definition of the mapper on the Java side is shown below.

<bean id="classMapper" class="org.spring.jmsinterop.converters.SimpleClassMapper">
<property name="defaultPackage" value="org.spring.jmsinterop.bo"/>

<!--
<property name="idClassMapping">
<map>
<entry key="1" value="org.spring.jmsinterop.bo.Trade"/>
</map>
</property>
-->


</bean>

The IdTypeMapping/IdClassMapping properties (commented out) show how you can avoid the use of class names completely and use an arbitrary identifier to specify the type.

Sharing Business Objects

One technique that can reduce the effort in keeping business objects in sync is to use the Java Language Converter (JLCA) to automatically convert Java classes to C# 7. While this tool is intended for use as a "one-time" translation of a Java code base it can be incorporated into an automated build process and used to synchronize your business objects between Java and .NET. Business objects are actually a very good candidate for this converter since they do not contain technology specific APIs such as those for data access or web programming which are difficult for the convert correctly without subsequent manual tweaking.

However, the JLCA is not without its warts. There are a variety of limitations and quirks but you can nevertheless create complex C# classes that convert successfully to Java without manual intervention. One of the most noticeable quirks is that method names are left as lowercase but on the plus side, JavaBean get/set methods are converted to .NET properties. Other limitations are that annotations are not converted to attributes and there is no support for generics. Namespaces are left as the java package name but a simple regex post processing fixes that easily. The converter also creates C# implementations of some supporting classes if needed, for example a C# equivalent to java.util.Set. With a little experimenting you will see how far you can use this technology on your own project. A "cheat sheet" summarizing the abilities of the converter are available on Gaurav Seth's blog 8. One last tidbit of JLCA information is that the company behind the JLCA, ArtinSoft also sells a product, JLCA Companion, which allows you to change or add the transformation rules 9.

Running the JLCA on the Java classes in this example works very well. You can toggle the use of the hand coded C# business objects and the JLCA generated ones by including/excluding the "Bo" and "Jlca" directories in the .NET solution. In particular look/modify the validation method in the TradeRequest class which uses simple conditional logic and collection class manipulation. An ant script is provided to run the JLCA on the Java business objects and change the package name to the correct .NET namespace.

A screenshot of the client after having received a few market data events and sending both a TradeRequest and PortfolioRequest is shown below.

Conclusion

If you are already in a messaging environment or are drawn to the features of messaging such as asynchronous communication and publish/subscribe delivery, using Spring's JMS support in both Java and .NET provides you with a powerful starting point to create interop solutions. Spring isn't very prescriptive in terms of the contracts used to ensure compatibility between JMS producers and consumers but it does provide a simple extension point, the MessageConverter, for you to introduce a contract of your own devising. The sophistication of the converters and associated objects should match the complexity of your application. The stock trading application and ReflectionMessageConverter lay the foundation for easy experimentation of your own.

To reiterate a commonly mentioned description of the Spring framework - "it makes the easy stuff easy and the hard stuff possible". I hope that you will agree that this also applies to Spring's JMS support in a mixed .NET/Java environment. At the end of the day, no matter what route you choose for interoperability, you will find that using Spring on both .NET and Java is beneficial since the same programming model and best practices can easily be shared between the two worlds.

The source code accompanying this article can be downloaded HERE.


Posted on February 23, 2007 9:16 PM | | Comments (0) | TrackBacks (0)
上一页 1 2 3 4 5