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函数的对象.当对象被请求过来的时候,会依次经过各个中间件进行处理 ...
随机推荐
- 常用php操作redis命令整理(五)ZSET类型
ZADD 向有序集合插入一个元素,元素关联一个数值,插入成功返回1,同时集合元素不可以重复, 如果元素已经存在返回 0 <?php var_dump($redis->zadd(,'A')) ...
- 《Java程序设计》第三章-基础语法
20145221<Java程序设计>第三章-基础语法 总结 教材学习内容总结 类型.变量与运算符 类型 Java可区分为基本类型(Primitive Type)和类类型(Class Typ ...
- POJ 3259 Wormholes(最短路&spfa正权回路)题解
题意:给你m条路花费时间(双向正权路径),w个虫洞返回时间(单向负权路径),问你他能不能走一圈回到原点之后,时间倒流. 思路:题意有点难看懂,我们建完边之后找一下是否存在负权回路,存在则能,反之不能. ...
- luogu P1017 进制转换
感觉这个题 是真的恶心 本来单纯就递归写,发现好难 后来用数组记录 然后考虑 指数为 奇和偶数 分别 <0 和 > 进制的情况 其实 用进制数为3 大概讨论四种情况就可以了 由于最近就是在 ...
- ActiveMQ(1) -- 入门案例
- JS中innerHTML和innerText,outerHTML和outerText
innerHTML 声明了元素含有的HTML文本,不包括元素本身的开始标记和结束标记 innerHTML是符合W3C标准的属性,而innerText只适用于IE浏览器(现在也适应chrome浏览器 ...
- BZOJ 1833 【ZJOI2010】 数字计数
题目链接:数字计数 没啥好说的,裸裸的数位\(dp\). 先枚举当前是算数字\(x\)出现的次数,设\(f_{i,j}\)表示从高位往低位\(dp\),\(dp\)完了前\(i\)位之后\(x\)出现 ...
- PHP--------解决网址URL编码问题
在PHP中有urlencode().urldecode().rawurlencode().rawurldecode()这些函数来解决网页URL编码解码问题. 理解urlencode: urlencod ...
- sgu 137. Funny Strings 线性同余,数论,构造 难度:3
137. Funny Strings time limit per test: 0.25 sec. memory limit per test: 4096 KB Let's consider a st ...
- jsp登录页面,展示错误信息,刷新页面后错误依然存在解决方案
在做登录页面的时候,通常使用form表单同步提交的方法进行提交的,也就是在form表单里去写action,如果登录失败,jsp通过jstl表达式获取错误信息展示在页面上,但是有一个问题就是,即使你刷新 ...