TongWEB与JOnAS 对比,国产中间件战斗机东方通TongWEB源码解析
转自网址:
http://bbs.51cto.com/thread-489819-1-1.html
首先需要声明的是,本人出于技术爱好的角度,以下的文字只是对所看到的一些情况的罗列,偶尔附加个人的一些感慨,不代表其它任何组织或公司的色彩。本人也并不希望这篇贴子成为某些别有用心的人用来攻击某些厂商的武器。
作为一名有多年开发经验的J2EE技术人员,本人向来对J2EE应用服务器的相关知识比较感兴趣;或许又夹杂着一些民族感情,对号称国产中间件第一品牌东方通的应用服务器产品“TongWeb”倾慕不已。遗憾的是,东方通的网站上从来不放任何产品的下载,因此,对 TongWeb 到底是如何的庐山真面目,也无从得知。
一个很偶然的机会,由于客户指定品牌的原因,获得了一份 TongWeb 的产品包,颇有些喜出望外,极欲一探究竟。在使用TongWeb的过程中,一个很偶然的因素,本人打开了TongWeb4.6\conf\ejb\trace.properties文件,发现了这样一行:
log.config.classname org.objectweb.util.monolog.wrapper.log4j.MonologLoggerFactory
不由心中一动,objectweb,好熟悉的名字,国外的开源服务器 JOnAS 不就出自这个组织吗?
抱着疑惑的态度和本着技术人员寻根问底的精神,就开始了 TongWeb 与 JOnAS 的对比之旅。
进行Java程序的对比,自然是要对最主要的jar包进行对比了。
根据“最大的就是最主要的”原则:TongWeb中最大的jar包是:TongWeb4.6\lib\tongweb.jar;JOnAS最大的jar包是:JOnAS-4.8.3\lib\commons\jonas\ow_jonas.jar
随便翻了关于 ejb 的一个包,以下是包名截图:
看起来很像?但不能够以最坏的恶意来揣测人家,不妨用反编译工具看一下具体的内容再说。
顺手选一个,就拿图片中显示的第一个类 BeanFactory 来说吧,以下是用Jad反编译出来的内容对比:
/***************org.objectweb.jonas_ejb.container.BeanFactory***************/
package org.objectweb.jonas_ejb.container; import java.util.Hashtable;
import javax.naming.InitialContext;
import javax.transaction.Transaction;
import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
import org.objectweb.transaction.jta.TransactionManager; public interface BeanFactory { public abstract String getEJBName(); public abstract BeanDesc getDeploymentDescriptor(); public abstract int getPoolSize(); public abstract void stop(); public abstract void syncDirty(boolean flag); public abstract void reduceCache(); public abstract JHome getHome(); public abstract JLocalHome getLocalHome(); public abstract TransactionManager getTransactionManager(); public abstract JContainer getContainer(); public abstract Hashtable getEnv(); public abstract InitialContext getInitialContext(); public abstract void initInstancePool(); public abstract void restartTimers(); public abstract void storeInstances(Transaction transaction);
} /***********com.tongweb.teas_ejb.container.BeanFactory******************************/ package com.tongweb.teas_ejb.container; import com.tongweb.teas_ejb.deployment.api.BeanDesc;
import java.util.Hashtable;
import javax.naming.InitialContext;
import javax.transaction.TransactionManager; public interface BeanFactory { public abstract String getEJBName(); public abstract BeanDesc getDeploymentDescriptor(); public abstract int getPoolSize(); public abstract void stop(); public abstract void sync(); public abstract void reduceCache(); public abstract JHome getHome(); public abstract JLocalHome getLocalHome(); public abstract TransactionManager getTransactionManager(); public abstract JContainer getContainer(); public abstract Hashtable getEnv(); public abstract InitialContext getInitialContext();
}
这两个类很相像?在本人看来,何止是相像,简直就是一个模子刻出来的!只能说的是,版本不同而已!
还是不能以最坏的恶意来揣测TongWeb,不妨再换个包来看看。东方通不是号称消息中间件最强吗?不妨看看jms这个包。
不看不知道,一看吓一跳:
这个包下的所有类名称,竟然都是一模一样的,只不过一个位于org.objectweb.jonas_jms包下,一个位于com.tongweb.teas_jms 包下而已。
随便找个类JConnection来看看:
/**********************************org.objectweb.jonas_jms.JConnection***********/
package org.objectweb.jonas_jms; import java.util.LinkedList;
import javax.jms.*;
import org.objectweb.transaction.jta.TransactionManager;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger; public class JConnection
implements Connection
{ protected XAConnection xac;
protected boolean closed;
protected String user;
protected boolean globaltx;
protected static TransactionManager tm;
protected JConnectionFactory jcf;
protected LinkedList sessionlist;
protected static final String INTERNAL_USER_NAME =
"anInternalNameUsedOnlyByJOnAS"; protected JConnection(JConnectionFactory jcf, String user)
throws JMSException
{
globaltx = false;
sessionlist = new LinkedList();s
this.user = user;
this.jcf = jcf;
closed = false;
if(tm == null)
tm = JmsManagerImpl.getTransactionManager();
try
{
globaltx = tm.getTransaction() != null;
}
catch(Exception e) { }
} public JConnection(JConnectionFactory jcf, XAConnectionFactory xacf, String user, String passwd)
throws JMSException
{
this(jcf, user);
xac = xacf.createXAConnection(user, passwd);
} public JConnection(JConnectionFactory jcf, XAConnectionFactory xacf)
throws JMSException
{
this(jcf, "anInternalNameUsedOnlyByJOnAS");
xac = xacf.createXAConnection();
} protected synchronized boolean sessionOpen(Session s)
{
if(!closed)
{
sessionlist.add(s);
return true;
} else
{
return false;
}
} protected synchronized void sessionClose(Session s)
{
sessionlist.remove(s);
if(sessionlist.size() == 0 && closed)
notify();
} public String getUser()
{
return user;
} public void close()
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
if(globaltx)
{
jcf.freeJConnection(this);
} else
{
synchronized(this)
{
while(sessionlist.size() > 0)
try
{
wait();
}
catch(InterruptedException e)
{
TraceJms.logger.log(BasicLevel.ERROR, "interrupted");
}
}
closed = true;
xac.close();
}
} public void finalClose()
throws JMSException
{
if(!closed)
xac.close();
} public ConnectionConsumer createConnectionConsumer(Destination destination, String messageSelector, ServerSessionPool sessionPool, int maxMessages)
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
return xac.createConnectionConsumer(destination, messageSelector, sessionPool, maxMessages);
} public ConnectionConsumer createDurableConnectionConsumer(Topic topic, String subscriptionName, String messageSelector, ServerSessionPool sessionPool, int maxMessages)
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
return xac.createDurableConnectionConsumer(topic, subscriptionName, messageSelector, sessionPool, maxMessages);
} public Session createSession(boolean transacted, int acknowledgeMode)
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
return new JSession(this, xac);
} public String getClientID()
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
return xac.getClientID();
} public void setClientID(String clientID)
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
xac.setClientID(clientID);
} public ConnectionMetaData getMetaData()
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
return xac.getMetaData();
} public ExceptionListener getExceptionListener()
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
return xac.getExceptionListener();
} public void setExceptionListener(ExceptionListener listener)
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
xac.setExceptionListener(listener);
} public void start()
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
xac.start();
} public void stop()
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
xac.stop();
}
}
/***********************com.tongweb.teas_jms.JConnection**************************/
package com.tongweb.teas_jms; import java.util.LinkedList;
import javax.jms.*;
import javax.transaction.TransactionManager;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger; public class JConnection
implements Connection
{ protected XAConnection xac;
protected boolean closed;
protected String user;
protected boolean globaltx;
protected static TransactionManager tm;
protected JConnectionFactory jcf;
protected LinkedList sessionlist;
protected static final String INTERNAL_USER_NAME =
"anInternalNameUsedOnlyByJOnAS"; protected JConnection(JConnectionFactory jconnectionfactory, String s)
throws JMSException
{
globaltx = false;
sessionlist = new LinkedList();
user = s;
jcf = jconnectionfactory;
closed = false;
if(tm == null)
tm = JmsManagerImpl.getTransactionManager();
try
{
globaltx = tm.getTransaction() != null;
}
catch(Exception exception) { }
} public JConnection(JConnectionFactory jconnectionfactory, XAConnectionFactory xaconnectionfactory, String s, String s1)
throws JMSException
{
this(jconnectionfactory, s);
} public JConnection(JConnectionFactory jconnectionfactory, XAConnectionFactory xaconnectionfactory)
throws JMSException
{
this(jconnectionfactory, "anInternalNameUsedOnlyByJOnAS");
} protected synchronized boolean sessionOpen(Session session)
{
if(!closed)
{
sessionlist.add(session);
return true;
} else
{
return false;
}
} protected synchronized void sessionClose(Session session)
{
sessionlist.remove(session);
if(sessionlist.size() == 0 && closed)
notify();
} public String getUser()
{
return user;
} public void close()
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
if(globaltx)
{
jcf.freeJConnection(this);
} else
{
synchronized(this)
{
while(sessionlist.size() > 0)
try
{
wait();
}
catch(InterruptedException interruptedexception)
{
TraceJms.logger.log(BasicLevel.ERROR, "interrupted");
}
}
closed = true;
}
} public void finalClose()
throws JMSException
{
if(closed);
} public ConnectionConsumer createConnectionConsumer(Destination destination, String s, ServerSessionPool serversessionpool, int i)
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
return null;
} public ConnectionConsumer createDurableConnectionConsumer(Topic topic, String s, String s1, ServerSessionPool serversessionpool, int i)
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
return null;
} public Session createSession(boolean flag, int i)
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
return new JSession(this, xac);
} public String getClientID()
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
return null;
} public void setClientID(String s)
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
} public ConnectionMetaData getMetaData()
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
return null;
} public ExceptionListener getExceptionListener()
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
return null;
} public void setExceptionListener(ExceptionListener exceptionlistener)
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
} public void start()
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
} public void stop()
throws JMSException
{
TraceJms.logger.log(BasicLevel.DEBUG, "");
}
}
两个类除了包名不同,其它基本上完全一致!甚至于TongWeb中竟然还存在这样一个常量声明:protected static final String INTERNAL_USER_NAME = "anInternalNameUsedOnlyByJOnAS";
东方通啊东方通,拜托你抄袭也要有点专业精神好不好,不要用“俯卧撑”来敷衍我们!
最后,很想说点啥,但心里又堵得慌,不知道该说啥。这就是号称“国内第一品牌”的东方通的产品?我们已经见识过了汉芯,见识过了麒麟,难道还要再见识一下TongWeb?
TongWEB与JOnAS 对比,国产中间件战斗机东方通TongWEB源码解析
TongWEB与JOnAS 对比,国产中间件战斗机东方通TongWEB源码解析的更多相关文章
- react 中间件相关的一些源码解析
零.随便说说中间件 在react的使用中,我们可以将数据放到redux,甚至将一些数据相关的业务逻辑放到redux,这样可以简化我们组件,也更方便组件抽离.封装.复用,只是redux不能很好的处理异步 ...
- 大熊君大话NodeJS之 ------ Connect中间件第二季(源码分析)
一,开篇分析 大家好,大熊君又回来了,今天这篇文章主要是对"Connect"中间件以及相关辅助中间件,做一个源码分析系列,我想上一篇文章大家也看了, 介绍了使用方式及用途,而这篇也 ...
- .Net Core 中间件之主机地址过滤(HostFiltering)源码解析
一.介绍 主机地址过滤中间件相当于一个白名单,标记哪些主机地址能访问接口. 二.使用 新建WebAPI项目,修改Startup中的代码段如下所示.下面表示允许主机名为“localhost”的主机访问( ...
- AspNetCore源码解析_1_CORS中间件
概述 什么是跨域 在前后端分离开发方式中,跨域是我们经常会遇到的问题.所谓的跨域,就是处于安全考虑,A域名向B域名发出Ajax请求,浏览器会拒绝,抛出类似下图的错误. JSONP JSONP不是标准跨 ...
- AspNetCore3.1源码解析_2_Hsts中间件
title: "AspNetCore3.1源码解析_2_Hsts中间件" date: 2020-03-16T12:40:46+08:00 draft: false --- 概述 在 ...
- 【原创】express3.4.8源码解析之中间件
前言 注意:旧文章转成markdown格式. 中间件(middleware)的概念来自于TJ的connect库,express就是建立在connect之上. 就如同connect的意思是 连接 一样, ...
- redux 中间件 --- applyMiddleware 源码解析 + 中间件的实战
前传 中间件的由来 redux的操作的过程,用户操作的时候,我们通过dispatch分发一个action,纯函数reducer检测到该操作,并根据action的type属性,进行相应的运算,返回st ...
- .Net Core 中间件之静态文件(StaticFiles)源码解析
一.介绍 在介绍静态文件中间件之前,先介绍 ContentRoot和WebRoot概念. ContentRoot:指web的项目的文件夹,包括bin和webroot文件夹. WebRoot:一般指Co ...
- koa2中间件koa和koa-compose源码分析原理(一)
koa是基于nodejs平台的下一代web开发框架,它是使用generator和promise,koa的中间件是一系列generator函数的对象.当对象被请求过来的时候,会依次经过各个中间件进行处理 ...
随机推荐
- P1757 通天之分组背包 / hdu1712 ACboy needs your help (分组背包入门)
P1757 通天之分组背包 hdu1712 ACboy needs your help hdu1712题意:A[i][j]表示用j天学习第i个课程能够得到A[i][j]的收益,求m天内获得的收益最大值 ...
- Python3.x:免费代理ip的批量获取并入库
Python3.x:免费代理ip的批量获取并入库 一.简介 网络爬虫的世界,向来都是一场精彩的攻防战.现在许多网站的反爬虫机制在不断的完善,其中最令人头疼的,莫过于直接封锁你的ip.但是道高一尺魔高一 ...
- ELF文件分析
(1)文件ELF.c (2)编译: gcc -c ELF_1.c -o ELF_1.o (3)显示文件类型: (4)查看大小: (5)转换为16进制 (6)显示各段信息 (7)分析
- CONFLICT (modify delete)冲突修复
Demo git:(test) git merge feature CONFLICT (modify/delete): path/to/path/config.inc.php deleted in H ...
- Git-标签管理【转】
本文转载自:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 标签管理 发布一个版本 ...
- ubuntu 18.04 64bit如何安装GPU版本tensorflow
注:笔者的ubuntu18.04 64bit已经安装好了显卡驱动,因此没有此步操作 1.获取cuda(https://developer.nvidia.com/cuda-downloads,选择ubu ...
- fiddler几种功能强大的用法(二)
参考网址:http://blog.rekfan.com/articles/228.html http://www.cnblogs.com/tugenhua0707/p/4637771.html htt ...
- OpenDayLight Helium实验三 OpenDaylight二层转发机制实验 2
鉴于在个人笔记本上虚拟机运行ODL实在太慢,把实验的场景搬到了实验室. 实验上:OpenDayLight Helium实验三 OpenDaylight二层转发机制实验 抓包实验 紧接着,在运行Mini ...
- PHP-----------HTTP请求的第三方接口
开发中常常遇到接口请求这个功能,后台也不例外,因为遇到了,所以写一篇. 前段时间做商城后台时,需要用到第三方物流接口查询物流信息. post: /**** * @param $url * @param ...
- hdu4990矩阵快速幂
就是优化一段代码,用矩阵快速幂(刚开始想到了转移矩阵以为是错的) 在搜题解时发现了一个神奇的网站:http://oeis.org/ 用来找数列规律 的神器.... 规律就是an=an-1+2*an-2 ...