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函数的对象.当对象被请求过来的时候,会依次经过各个中间件进行处理 ...
随机推荐
- Mysql索引结构与索引原理
Mysql索引主要包括四种,Btree索引.Hash索引.full-text全文索引.R-tree索引,因为作为一名PHP开发者,并不是专业的DBA,在这里只需要了解第一种开发相关的BTree索引. ...
- 20145204Android开发基础
实验四 20145204Android开发基础 实验名称 Android开发基础 实验内容 基于Android Studio开发简单的Android应用并部署测试; 了解Android组件.布局管理器 ...
- 20145311王亦徐 实验三 "敏捷开发与XP实践"
20145311王亦徐 实验三 "敏捷开发与XP实践"程序设计过程 实验内容 使用 git 上传代码 使用 git 相互更改代码 实现代码的重载 git 上传代码 查看代码是否有修 ...
- 在pom.xml中使用distributionManagement将项目打包上传到nexus私服
本文介绍 如何在pom.xml中使用distributionManagement将项目打包上传到nexus私服 1.pom.xml文件添加distributionManagement节点 <!- ...
- 如何解决Nginx php 50x 错误
SEO反馈百度爬虫经常504,一般情况下是由nginx默认的fastcgi进程响应慢引起的,但也有其他情况,这里我总结了一些解决办法供大家参考. 方法/步骤 一般50x状态码问题分析: Nginx ...
- try catch finally return
public override bool Start(IServerConfig config) { bool flag = true; listenSocket = new Socket(Liste ...
- python 返回系统名称,系统平台,系统版本
import platform import os print(os.name) print(platform.system()) print(platform.release())
- Getting 'The AWS Access Key Id you provided does not exist in our records' error with Amazon MWS
I upgraded from one version of Amazon MWS (marketplace web service) version https://mws.amazonservic ...
- 深入理解javascript之typeof和instanceof
1.https://blog.csdn.net/mevicky/article/details/50353881 (深入理解javascript之typeof和instanceof)
- 本地RUN Page时报无法显示该网页
经检查,是我本地安装了浏览器广告屏蔽插件引起的,关闭该插件即可.