diff --git a/.gitignore b/.gitignore
index 59f507d15802..af3d4f9128b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,9 @@ target/
*.diff
*.patch
*.tmp
+*.java~
+*.properties~
+*.xml~
# system ignore
.DS_Store
diff --git a/README b/README
deleted file mode 100644
index 8610835f160e..000000000000
--- a/README
+++ /dev/null
@@ -1,193 +0,0 @@
-Dubbo is a distributed service framework enpowers applications with service import/export capability with high performance RPC.
-
-It's composed of three kernel parts:
-
-Remoting: a network communication framework provides sync-over-async and request-response messaging.
-
-Clustering: a remote procedure call abstraction with load-balancing/failover/clustering capabilities.
-
-Registry: a service directory framework for service registration and service event publish/subscription
-
-For more, please refer to:
-
- http://code.alibabatech.com/wiki/display/dubbo
-
-================================================================
-Quick Start
-================================================================
-
-Export remote service:
-
-
-
-
-
-Refer remote service:
-
-
-
-
-
-
-
-================================================================
-Source Building
-================================================================
-
-0. Install the git and maven command line:
-
- yum install git
- or: apt-get install git
-
- cd ~
- wget http://www.apache.org/dist//maven/binaries/apache-maven-2.2.1-bin.tar.gz
- tar zxvf apache-maven-2.2.1-bin.tar.gz
- vi .bash_profile
- - edit: export PATH=$PATH:~/apache-maven-2.2.1/bin
- source .bash_profile
-
-1. Checkout the dubbo source code:
-
- cd ~
- git clone https://github.com/AlibabaTech/dubbo.git dubbo
-
- git checkout -b dubbo-2.4.0
- git checkout master
-
-2. Import the dubbo source code to eclipse project:
-
- cd ~/dubbo
- mvn eclipse:eclipse
- Eclipse -> Menu -> File -> Import -> Exsiting Projects to Workspace -> Browse -> Finish
-
- Context Menu -> Run As -> Java Application:
- dubbo-demo-provider/src/test/java/com.alibaba.dubbo.demo.provider.DemoProvider
- dubbo-demo-consumer/src/test/java/com.alibaba.dubbo.demo.consumer.DemoConsumer
- dubbo-monitor-simple/src/test/java/com.alibaba.dubbo.monitor.simple.SimpleMonitor
- dubbo-registry-simple/src/test/java/com.alibaba.dubbo.registry.simple.SimpleRegistry
-
- Edit Config:
- dubbo-demo-provider/src/test/resources/dubbo.properties
- dubbo-demo-consumer/src/test/resources/dubbo.properties
- dubbo-monitor-simple/src/test/resources/dubbo.properties
- dubbo-registry-simple/src/test/resources/dubbo.properties
-
-3. Build the dubbo binary package:
-
- cd ~/dubbo
- mvn clean install -Dmaven.test.skip
- cd dubbo/target
- ls
-
-4. Install the demo provider:
-
- cd ~/dubbo/dubbo-demo-provider/target
- tar zxvf dubbo-demo-provider-2.4.0-assembly.tar.gz
- cd dubbo-demo-provider-2.4.0/bin
- ./start.sh
-
-5. Install the demo consumer:
-
- cd ~/dubbo/dubbo-demo-consumer/target
- tar zxvf dubbo-demo-consumer-2.4.0-assembly.tar.gz
- cd dubbo-demo-consumer-2.4.0/bin
- ./start.sh
- cd ../logs
- tail -f stdout.log
-
-6. Install the simple monitor:
-
- cd ~/dubbo/dubbo-simple-monitor/target
- tar zxvf dubbo-simple-monitor-2.4.0-assembly.tar.gz
- cd dubbo-simple-monitor-2.4.0/bin
- ./start.sh
- http://127.0.0.1:8080
-
-7. Install the simple registry:
-
- cd ~/dubbo/dubbo-simple-registry/target
- tar zxvf dubbo-simple-registry-2.4.0-assembly.tar.gz
- cd dubbo-simple-registry-2.4.0/bin
- ./start.sh
-
- cd ~/dubbo/dubbo-demo-provider/conf
- vi dubbo.properties
- - edit: dubbo.registry.adddress=dubbo://127.0.0.1:9090
- cd ../bin
- ./restart.sh
-
- cd ~/dubbo/dubbo-demo-consumer/conf
- vi dubbo.properties
- - edit: dubbo.registry.adddress=dubbo://127.0.0.1:9090
- cd ../bin
- ./restart.sh
-
- cd ~/dubbo/dubbo-simple-monitor/conf
- vi dubbo.properties
- - edit: dubbo.registry.adddress=dubbo://127.0.0.1:9090
- cd ../bin
- ./restart.sh
-
-8. Install the zookeeper registry:
-
- cd ~
- wget http://www.apache.org/dist//zookeeper/zookeeper-3.3.3/zookeeper-3.3.3.tar.gz
- tar zxvf zookeeper-3.3.3.tar.gz
- cd zookeeper-3.3.3/conf
- cp zoo_sample.cfg zoo.cfg
- vi zoo.cfg
- - edit: dataDir=/home/xxx/data
- cd ../bin
- ./zkServer.sh start
-
- cd ~/dubbo/dubbo-demo-provider/conf
- vi dubbo.properties
- - edit: dubbo.registry.adddress=zookeeper://127.0.0.1:2181
- cd ../bin
- ./restart.sh
-
- cd ~/dubbo/dubbo-demo-consumer/conf
- vi dubbo.properties
- - edit: dubbo.registry.adddress=zookeeper://127.0.0.1:2181
- cd ../bin
- ./restart.sh
-
- cd ~/dubbo/dubbo-simple-monitor/conf
- vi dubbo.properties
- - edit: dubbo.registry.adddress=zookeeper://127.0.0.1:2181
- cd ../bin
- ./restart.sh
-
-9. Install the redis registry:
-
- cd ~
- wget http://redis.googlecode.com/files/redis-2.4.8.tar.gz
- tar xzf redis-2.4.8.tar.gz
- cd redis-2.4.8
- make
- nohup ./src/redis-server redis.conf &
-
- cd ~/dubbo/dubbo-demo-provider/conf
- vi dubbo.properties
- - edit: dubbo.registry.adddress=redis://127.0.0.1:6379
- cd ../bin
- ./restart.sh
-
- cd ~/dubbo/dubbo-demo-consumer/conf
- vi dubbo.properties
- - edit: dubbo.registry.adddress=redis://127.0.0.1:6379
- cd ../bin
- ./restart.sh
-
- cd ~/dubbo/dubbo-simple-monitor/conf
- vi dubbo.properties
- - edit: dubbo.registry.adddress=redis://127.0.0.1:6379
- cd ../bin
- ./restart.sh
-
-10. Install the admin console:
-
- cd ~/dubbo/dubbo-admin
- mvn jetty:run -Ddubbo.registry.address=zookeeper://127.0.0.1:2181
- http://root:root@127.0.0.1:8080
-
diff --git a/README.md b/README.md
new file mode 100644
index 000000000000..74856b9e19bc
--- /dev/null
+++ b/README.md
@@ -0,0 +1,202 @@
+Dubbox now means Dubbo eXtensions. If you know java, javax and dubbo, you know what dubbox is :)
+
+Dubbox adds features like RESTful remoting, Kyro/FST serialization, etc to the popular [dubbo service framework](http://github.com/alibaba/dubbo). It's been used by several projects of [dangdang.com](http://www.dangdang.com), which is one of the major e-commerce companies in China.
+
+## 主要贡献者
+
+* 沈理 [当当网](http://www.dangdang.com/) shenli@dangdang.com
+* 王宇轩 [当当网](http://www.dangdang.com/) wangyuxuan@dangdang.com
+* 马金凯 [韩都衣舍](http://www.handu.com/) majinkai@handu.com
+* Dylan 独立开发者 dinguangx@163.com
+* Kangfoo 独立开发者
+
+有技术问题请移步此处讨论 https://github.com/dangdangdotcom/dubbox/issues
+
+## Dubbox当前的主要功能
+
+* **支持REST风格远程调用(HTTP + JSON/XML)**:基于非常成熟的JBoss [RestEasy](http://resteasy.jboss.org/)框架,在dubbo中实现了REST风格(HTTP + JSON/XML)的远程调用,以显著简化企业内部的跨语言交互,同时显著简化企业对外的Open API、无线API甚至AJAX服务端等等的开发。事实上,这个REST调用也使得Dubbo可以对当今特别流行的“微服务”架构提供基础性支持。 另外,REST调用也达到了比较高的性能,在基准测试下,HTTP + JSON与Dubbo 2.x默认的RPC协议(即TCP + Hessian2二进制序列化)之间只有1.5倍左右的差距,详见文档中的基准测试报告。
+
+* **支持基于Kryo和FST的Java高效序列化实现**:基于当今比较知名的[Kryo](https://github.com/EsotericSoftware/kryo)和[FST](https://github.com/RuedigerMoeller/fast-serialization)高性能序列化库,为Dubbo默认的RPC协议添加新的序列化实现,并优化调整了其序列化体系,比较显著的提高了Dubbo RPC的性能,详见文档中的基准测试报告。
+
+* **支持基于Jackson的JSON序列化**:基于业界应用最广泛的[Jackson](http://jackson.codehaus.org/)序列化库,为Dubbo默认的RPC协议添加新的JSON序列化实现。
+
+* **支持基于嵌入式Tomcat的HTTP remoting体系**:基于嵌入式tomcat实现dubbo的HTTP remoting体系(即dubbo-remoting-http),用以逐步取代Dubbo中旧版本的嵌入式Jetty,可以显著的提高REST等的远程调用性能,并将Servlet API的支持从2.5升级到3.1。(注:除了REST,dubbo中的WebServices、Hessian、HTTP Invoker等协议都基于这个HTTP remoting体系)。
+
+* **升级Spring**:将dubbo中Spring由2.x升级到目前最常用的3.x版本,减少版本冲突带来的麻烦。
+
+* **升级ZooKeeper客户端**:将dubbo中的zookeeper客户端升级到最新的版本,以修正老版本中包含的bug。
+
+* **支持完全基于Java代码的Dubbo配置**:基于Spring的Java Config,实现完全无XML的纯Java代码方式来配置dubbo
+
+* **调整Demo应用**:暂时将dubbo的demo应用调整并改写以主要演示REST功能、Dubbo协议的新序列化方式、基于Java代码的Spring配置等等。
+
+* **修正了dubbo的bug** 包括配置、序列化、管理界面等等的bug。
+
+**注:dubbox和dubbo 2.x是兼容的,没有改变dubbo的任何已有的功能和配置方式(除了升级了spring之类的版本)**
+
+## 文档资料
+
+[在Dubbo中开发REST风格的远程调用(RESTful Remoting)](https://dangdangdotcom.github.io/dubbox/rest.html)
+
+[在Dubbo中使用高效的Java序列化(Kryo和FST)](https://dangdangdotcom.github.io/dubbox/serialization.html)
+
+[使用JavaConfig方式配置dubbox](https://dangdangdotcom.github.io/dubbox/java-config.html)
+
+[Dubbo Jackson序列化使用说明](https://dangdangdotcom.github.io/dubbox/jackson.html)
+
+[Demo应用简单运行指南](https://dangdangdotcom.github.io/dubbox/demo.html)
+
+[Dubbox@InfoQ](http://www.infoq.com/cn/news/2014/10/dubbox-open-source)
+
+[Dubbox Wiki](https://github.com/dangdangdotcom/dubbox/wiki) (由社区志愿者自由编辑的)
+
+## 版本
+
+详见:https://github.com/dangdangdotcom/dubbox/releases
+
+* **dubbox-2.8.0**:主要支持REST风格远程调用、支持Kryo和FST序列化、升级了Spring和Zookeeper客户端、调整了demo应用等等
+* **dubbox-2.8.1**:主要支持基于嵌入式tomcat的http-remoting,优化了REST客户端性能,在REST中支持限制服务端接纳的最大HTTP连接数等等
+* **dubbox-2.8.2**:
+ * 支持REST中的HTTP logging,包括HTTP header的字段和HTTP body中的消息体,方便调试、日志纪录等等
+ * 提供辅助类便于REST的中文处理
+ * 改变使用`@Reference` annotation配置时的异常处理方式,即当用annotation配置时,过去dubbo在启动期间不抛出依赖服务找不到的异常,而是在具体调用时抛出NPE,这与用XML配置时的行为不一致。
+ * 较大的充实了Dubbo REST的文档
+* **dubbox-2.8.3**:
+ * 在REST中支持dubbo统一的方式用bean validation annotation作参数校验(沈理)
+ * 在RpcContext上支持获取底层协议的Request/Response(沈理)
+ * 支持采用Spring的Java Config方式配置dubbo(马金凯)
+ * 在Dubbo协议中支持基于Jackson的json序列化(Dylan)
+ * 在Spring AOP代理过的对象上支持dubbo annotation配置(Dylan)
+ * 修正Dubbo管理界面中没有consumer时出现空指针异常(马金凯)
+ * 修正@Reference annotation中protocol设置不起作用的bug(沈理)
+ * 修正@Reference annotation放在setter方法上即会出错的bug(Dylan)
+
+## 依赖
+
+从dubbox-2.8.4开始,所有依赖库的使用方式将和dubbo原来的一样:即如果要使用REST、Kyro、FST、Jackson等功能,需要用户自行手工添加相关的依赖。例如:
+
+### REST风格远程调用
+
+```xml
+
+ org.jboss.resteasy
+ resteasy-jaxrs
+ 3.0.7.Final
+
+
+ org.jboss.resteasy
+ resteasy-client
+ 3.0.7.Final
+
+
+ javax.validation
+ validation-api
+ 1.0.0.GA
+
+
+
+
+ org.jboss.resteasy
+ resteasy-jackson-provider
+ 3.0.7.Final
+
+
+
+
+ org.jboss.resteasy
+ resteasy-jaxb-provider
+ 3.0.7.Final
+
+
+
+
+ org.jboss.resteasy
+ resteasy-netty
+ 3.0.7.Final
+
+
+
+
+ org.jboss.resteasy
+ resteasy-jdk-http
+ 3.0.7.Final
+
+
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-core
+ 8.0.11
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-logging-juli
+ 8.0.11
+
+```
+
+### Kyro序列化
+
+```xml
+
+ com.esotericsoftware.kryo
+ kryo
+ 2.24.0
+
+
+ de.javakaffee
+ kryo-serializers
+ 0.26
+
+```
+
+### FST序列化
+
+```xml
+
+ de.ruedigermoeller
+ fst
+ 1.55
+
+```
+
+### Jackson序列化
+
+```xml
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.3.3
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.3.3
+
+```
+
+## FAQ(暂存)
+
+### Dubbox需要什么版本的JDK?
+
+目前最好在JDK 1.7以上运行
+
+### Dubbo REST的服务能和Dubbo注册中心、监控中心集成吗?
+
+可以的,而且是自动集成的,也就是你在dubbo中开发的所有REST服务都会自动注册到服务册中心和监控中心,可以通过它们做管理。
+
+但是,只有当REST的消费端也是基于dubbo的时候,注册中心中的许多服务治理操作才能完全起作用。而如果消费端是非dubbo的,自然不受注册中心管理,所以其中很多操作是不会对消费端起作用的。
+
+### Dubbo REST中如何实现负载均衡和容错(failover)?
+
+如果dubbo REST的消费端也是dubbo的,则Dubbo REST和其他dubbo远程调用协议基本完全一样,由dubbo框架透明的在消费端做load balance、failover等等。
+
+如果dubbo REST的消费端是非dubbo的,甚至是非java的,则最好配置服务提供端的软负载均衡机制,目前可考虑用LVS、HAProxy、 Nginx等等对HTTP请求做负载均衡。
+
+### JAX-RS中重载的方法能够映射到同一URL地址吗?
+
+http://stackoverflow.com/questions/17196766/can-resteasy-choose-method-based-on-query-params
+
+### JAX-RS中作POST的方法能够接收多个参数吗?
+
+http://stackoverflow.com/questions/5553218/jax-rs-post-multiple-objects
diff --git a/dubbo-admin/pom.xml b/dubbo-admin/pom.xml
index ff5051f716ea..ec2a30be84ad 100644
--- a/dubbo-admin/pom.xml
+++ b/dubbo-admin/pom.xml
@@ -19,7 +19,7 @@
com.alibaba
dubbo-parent
- 2.4.3
+ 2.8.4
dubbo-admin
war
@@ -41,16 +41,12 @@
com.alibaba.citrus
citrus-webx-all
-
- org.springframework
- spring
-
org.javassist
javassist
- org.jboss.netty
+ io.netty
netty
@@ -86,7 +82,7 @@
zkclient
- com.netflix.curator
+ org.apache.curator
curator-framework
@@ -103,7 +99,7 @@
javax.servlet
- servlet-api
+ javax.servlet-api
provided
diff --git a/dubbo-admin/src/main/java/com/alibaba/dubbo/governance/service/impl/ConsumerServiceImpl.java b/dubbo-admin/src/main/java/com/alibaba/dubbo/governance/service/impl/ConsumerServiceImpl.java
index bd236c293293..106d3c0a1655 100644
--- a/dubbo-admin/src/main/java/com/alibaba/dubbo/governance/service/impl/ConsumerServiceImpl.java
+++ b/dubbo-admin/src/main/java/com/alibaba/dubbo/governance/service/impl/ConsumerServiceImpl.java
@@ -76,6 +76,8 @@ public List findAddresses() {
public List findAddressesByApplication(String application) {
List ret = new ArrayList();
ConcurrentMap> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY);
+ if(consumerUrls == null) return ret;
+
for(Map.Entry> e1 : consumerUrls.entrySet()) {
Map value = e1.getValue();
for(Map.Entry e2 : value.entrySet()) {
diff --git a/dubbo-admin/src/main/java/com/alibaba/dubbo/governance/service/impl/RouteServiceImpl.java b/dubbo-admin/src/main/java/com/alibaba/dubbo/governance/service/impl/RouteServiceImpl.java
index 8907888938c0..152b3d569573 100644
--- a/dubbo-admin/src/main/java/com/alibaba/dubbo/governance/service/impl/RouteServiceImpl.java
+++ b/dubbo-admin/src/main/java/com/alibaba/dubbo/governance/service/impl/RouteServiceImpl.java
@@ -72,8 +72,8 @@ public void enableRoute(Long id) {
return;
}
- URL newRoute = oldRoute.removeParameter("enabled");
- registryService.unregister(oldRoute);
+ registryService.unregister(oldRoute);
+ URL newRoute= oldRoute.addParameter("enabled", true);
registryService.register(newRoute);
}
diff --git a/dubbo-admin/src/main/java/com/alibaba/dubbo/governance/web/home/module/control/Menu.java b/dubbo-admin/src/main/java/com/alibaba/dubbo/governance/web/home/module/control/Menu.java
index 9961e0e27019..92408bc53bd0 100644
--- a/dubbo-admin/src/main/java/com/alibaba/dubbo/governance/web/home/module/control/Menu.java
+++ b/dubbo-admin/src/main/java/com/alibaba/dubbo/governance/web/home/module/control/Menu.java
@@ -49,7 +49,7 @@ public void execute(HttpSession session, Context context, CookieParser parser) {
context.put("bucLogoutAddress", rootContextPath.getURI("logout"));
}
if (! context.containsKey("helpUrl")) {
- context.put("helpUrl", "http://code.alibabatech.com/wiki/display/dubbo");
+ context.put("helpUrl", "https://github.com/dangdangdotcom/dubbox/wiki");
}
context.put(WebConstants.CURRENT_USER_KEY, user);
context.put("language", parser.getString("locale"));
diff --git a/dubbo-cluster/pom.xml b/dubbo-cluster/pom.xml
index fbb592f97398..ec6af560cb05 100644
--- a/dubbo-cluster/pom.xml
+++ b/dubbo-cluster/pom.xml
@@ -19,7 +19,7 @@
com.alibaba
dubbo-parent
- 2.4.3
+ 2.8.4
dubbo-cluster
jar
diff --git a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/RuleConverter.java b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/RuleConverter.java
new file mode 100644
index 000000000000..ec089690a42b
--- /dev/null
+++ b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/RuleConverter.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1999-2012 Alibaba Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.dubbo.rpc.cluster;
+
+import java.util.List;
+
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.common.extension.SPI;
+
+/**
+ * @author kimi
+ */
+@SPI
+public interface RuleConverter {
+
+ List convert(URL subscribeUrl, Object source);
+
+}
diff --git a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/directory/AbstractDirectory.java b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/directory/AbstractDirectory.java
index 017af5940ae5..622cc06d03f4 100644
--- a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/directory/AbstractDirectory.java
+++ b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/directory/AbstractDirectory.java
@@ -1,66 +1,67 @@
-/*
- * Copyright 1999-2011 Alibaba Group.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+/*
+ * Copyright 1999-2011 Alibaba Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.alibaba.dubbo.rpc.cluster.directory;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.alibaba.dubbo.common.Constants;
-import com.alibaba.dubbo.common.URL;
-import com.alibaba.dubbo.common.extension.ExtensionLoader;
-import com.alibaba.dubbo.common.logger.Logger;
-import com.alibaba.dubbo.common.logger.LoggerFactory;
-import com.alibaba.dubbo.rpc.Invocation;
-import com.alibaba.dubbo.rpc.Invoker;
-import com.alibaba.dubbo.rpc.RpcException;
-import com.alibaba.dubbo.rpc.cluster.Directory;
-import com.alibaba.dubbo.rpc.cluster.Router;
-import com.alibaba.dubbo.rpc.cluster.RouterFactory;
-import com.alibaba.dubbo.rpc.cluster.router.MockInvokersSelector;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.common.extension.ExtensionLoader;
+import com.alibaba.dubbo.common.logger.Logger;
+import com.alibaba.dubbo.common.logger.LoggerFactory;
+import com.alibaba.dubbo.rpc.Invocation;
+import com.alibaba.dubbo.rpc.Invoker;
+import com.alibaba.dubbo.rpc.RpcException;
+import com.alibaba.dubbo.rpc.cluster.Directory;
+import com.alibaba.dubbo.rpc.cluster.Router;
+import com.alibaba.dubbo.rpc.cluster.RouterFactory;
+import com.alibaba.dubbo.rpc.cluster.router.MockInvokersSelector;
/**
- * 增加router的Directory
+ * 增加router的Directory
*
* @author chao.liuc
*/
public abstract class AbstractDirectory implements Directory {
-
- // 日志输出
- private static final Logger logger = LoggerFactory.getLogger(AbstractDirectory.class);
- private final URL url ;
+ // 日志输出
+ private static final Logger logger = LoggerFactory.getLogger(AbstractDirectory.class);
+
+ private final URL url ;
private volatile boolean destroyed = false;
-
- private volatile URL consumerUrl ;
-
+
+ private volatile URL consumerUrl ;
+
private volatile List routers;
public AbstractDirectory(URL url) {
this(url, null);
- }
-
- public AbstractDirectory(URL url, List routers) {
- this(url, url, routers);
+ }
+
+ public AbstractDirectory(URL url, List routers) {
+ this(url, url, routers);
}
public AbstractDirectory(URL url, URL consumerUrl, List routers) {
if (url == null)
throw new IllegalArgumentException("url == null");
- this.url = url;
+ this.url = url;
this.consumerUrl = consumerUrl;
setRouters(routers);
}
@@ -69,19 +70,19 @@ public List> list(Invocation invocation) throws RpcException {
if (destroyed){
throw new RpcException("Directory already destroyed .url: "+ getUrl());
}
- List> invokers = doList(invocation);
- List localRouters = this.routers; // local reference
- if (localRouters != null && localRouters.size() > 0) {
- for (Router router: localRouters){
- try {
+ List> invokers = doList(invocation);
+ List localRouters = this.routers; // local reference
+ if (localRouters != null && localRouters.size() > 0) {
+ for (Router router: localRouters){
+ try {
if (router.getUrl() == null || router.getUrl().getParameter(Constants.RUNTIME_KEY, true)) {
- invokers = router.route(invokers, getConsumerUrl(), invocation);
- }
- } catch (Throwable t) {
- logger.error("Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(), t);
+ invokers = router.route(invokers, getConsumerUrl(), invocation);
+ }
+ } catch (Throwable t) {
+ logger.error("Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(), t);
}
- }
- }
+ }
+ }
return invokers;
}
@@ -91,38 +92,39 @@ public URL getUrl() {
public List getRouters(){
return routers;
- }
-
- public URL getConsumerUrl() {
- return consumerUrl;
- }
-
- public void setConsumerUrl(URL consumerUrl) {
- this.consumerUrl = consumerUrl;
- }
+ }
+
+ public URL getConsumerUrl() {
+ return consumerUrl;
+ }
- protected void setRouters(List routers){
- // copy list
- routers = routers == null ? new ArrayList() : new ArrayList(routers);
- // append url router
- String routerkey = url.getParameter(Constants.ROUTER_KEY);
- if (routerkey != null && routerkey.length() > 0) {
- RouterFactory routerFactory = ExtensionLoader.getExtensionLoader(RouterFactory.class).getExtension(routerkey);
- routers.add(routerFactory.getRouter(url));
- }
- // append mock invoker selector
- routers.add(new MockInvokersSelector());
+ public void setConsumerUrl(URL consumerUrl) {
+ this.consumerUrl = consumerUrl;
+ }
+
+ protected void setRouters(List routers){
+ // copy list
+ routers = routers == null ? new ArrayList() : new ArrayList(routers);
+ // append url router
+ String routerkey = url.getParameter(Constants.ROUTER_KEY);
+ if (routerkey != null && routerkey.length() > 0) {
+ RouterFactory routerFactory = ExtensionLoader.getExtensionLoader(RouterFactory.class).getExtension(routerkey);
+ routers.add(routerFactory.getRouter(url));
+ }
+ // append mock invoker selector
+ routers.add(new MockInvokersSelector());
+ Collections.sort(routers);
this.routers = routers;
}
-
- public boolean isDestroyed() {
- return destroyed;
- }
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
public void destroy(){
destroyed = true;
- }
-
- protected abstract List> doList(Invocation invocation) throws RpcException ;
+ }
+
+ protected abstract List> doList(Invocation invocation) throws RpcException ;
}
\ No newline at end of file
diff --git a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/loadbalance/AbstractLoadBalance.java b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/loadbalance/AbstractLoadBalance.java
index f7adbb14eba6..8f53582e2e03 100644
--- a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/loadbalance/AbstractLoadBalance.java
+++ b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/loadbalance/AbstractLoadBalance.java
@@ -41,7 +41,23 @@ public Invoker select(List> invokers, URL url, Invocation invo
protected abstract Invoker doSelect(List> invokers, URL url, Invocation invocation);
protected int getWeight(Invoker> invoker, Invocation invocation) {
- return invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT);
+ int weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT);
+ if (weight > 0) {
+ long timestamp = invoker.getUrl().getParameter(Constants.TIMESTAMP_KEY, 0L);
+ if (timestamp > 0L) {
+ int uptime = (int) (System.currentTimeMillis() - timestamp);
+ int warmup = invoker.getUrl().getParameter(Constants.WARMUP_KEY, Constants.DEFAULT_WARMUP);
+ if (uptime > 0 && uptime < warmup) {
+ weight = calculateWarmupWeight(uptime, warmup, weight);
+ }
+ }
+ }
+ return weight;
+ }
+
+ static int calculateWarmupWeight(int uptime, int warmup, int weight) {
+ int ww = (int) ( (float) uptime / ( (float) warmup / (float) weight ) );
+ return ww < 1 ? 1 : (ww > weight ? weight : ww);
}
}
\ No newline at end of file
diff --git a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/support/ClusterUtils.java b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/support/ClusterUtils.java
index 646329edf86c..9d31824b0979 100644
--- a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/support/ClusterUtils.java
+++ b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/support/ClusterUtils.java
@@ -38,10 +38,22 @@ public static URL mergeUrl(URL remoteUrl, Map localMap) {
//线程池配置不使用提供者的
map.remove(Constants.THREAD_NAME_KEY);
+ map.remove(Constants.DEFAULT_KEY_PREFIX + Constants.THREAD_NAME_KEY);
+
+ map.remove(Constants.THREADPOOL_KEY);
+ map.remove(Constants.DEFAULT_KEY_PREFIX + Constants.THREADPOOL_KEY);
+
map.remove(Constants.CORE_THREADS_KEY);
+ map.remove(Constants.DEFAULT_KEY_PREFIX + Constants.CORE_THREADS_KEY);
+
map.remove(Constants.THREADS_KEY);
+ map.remove(Constants.DEFAULT_KEY_PREFIX + Constants.THREADS_KEY);
+
map.remove(Constants.QUEUES_KEY);
+ map.remove(Constants.DEFAULT_KEY_PREFIX + Constants.QUEUES_KEY);
+
map.remove(Constants.ALIVE_KEY);
+ map.remove(Constants.DEFAULT_KEY_PREFIX + Constants.ALIVE_KEY);
}
if (localMap != null && localMap.size() > 0) {
@@ -79,7 +91,8 @@ public static URL mergeUrl(URL remoteUrl, Map localMap) {
localMap.put(Constants.INVOKER_LISTENER_KEY, remoteListener + "," + localListener);
}
}
- return remoteUrl.addParameters(map);
+
+ return remoteUrl.clearParameters().addParameters(map);
}
private ClusterUtils() {}
diff --git a/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/loadbalance/LoadBalanceTest.java b/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/loadbalance/LoadBalanceTest.java
index cc09aba64e12..55e2a0417d09 100644
--- a/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/loadbalance/LoadBalanceTest.java
+++ b/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/loadbalance/LoadBalanceTest.java
@@ -28,6 +28,7 @@
import org.junit.BeforeClass;
import org.junit.Test;
+import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.rpc.Invocation;
@@ -144,7 +145,24 @@ public Map getInvokeCounter(int runs,String loadbalanceName)
counter.get(sinvoker).incrementAndGet();
}
return counter;
+ }
+
+ @Test
+ public void testLoadBalanceWarmup() {
+ Assert.assertEquals(1, AbstractLoadBalance.calculateWarmupWeight(0, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(1, AbstractLoadBalance.calculateWarmupWeight(13, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(1, AbstractLoadBalance.calculateWarmupWeight(6 * 1000, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(2, AbstractLoadBalance.calculateWarmupWeight(12 * 1000, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(10, AbstractLoadBalance.calculateWarmupWeight(60 * 1000, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(50, AbstractLoadBalance.calculateWarmupWeight(5 * 60 * 1000, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(50, AbstractLoadBalance.calculateWarmupWeight(5 * 60 * 1000 + 23, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(50, AbstractLoadBalance.calculateWarmupWeight(5 * 60 * 1000 + 5999, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(51, AbstractLoadBalance.calculateWarmupWeight(5 * 60 * 1000 + 6000, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(90, AbstractLoadBalance.calculateWarmupWeight(9 * 60 * 1000, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(98, AbstractLoadBalance.calculateWarmupWeight(10 * 60 * 1000 - 12 * 1000, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(99, AbstractLoadBalance.calculateWarmupWeight(10 * 60 * 1000 - 6 * 1000, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(100, AbstractLoadBalance.calculateWarmupWeight(10 * 60 * 1000, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ Assert.assertEquals(100, AbstractLoadBalance.calculateWarmupWeight(20 * 60 * 1000, Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
}
-
}
\ No newline at end of file
diff --git a/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/support/ClusterUtilsTest.java b/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/support/ClusterUtilsTest.java
new file mode 100644
index 000000000000..4c7e51a1f939
--- /dev/null
+++ b/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/support/ClusterUtilsTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2012 Alibaba Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.rpc.cluster.support;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.common.URL;
+
+/**
+ * @author kimi
+ */
+public class ClusterUtilsTest {
+
+ @Test
+ public void testMergeUrl() throws Exception {
+ URL providerURL = URL.valueOf("dubbo://localhost:55555");
+ providerURL = providerURL.setPath("path")
+ .setUsername("username")
+ .setPassword("password");
+
+ providerURL = providerURL.addParameter(Constants.GROUP_KEY, "dubbo")
+ .addParameter(Constants.VERSION_KEY, "1.2.3")
+ .addParameter(Constants.DUBBO_VERSION_KEY, "2.3.7")
+ .addParameter(Constants.THREADPOOL_KEY, "fixed")
+ .addParameter(Constants.THREADS_KEY, Integer.MAX_VALUE)
+ .addParameter(Constants.THREAD_NAME_KEY, "test")
+ .addParameter(Constants.CORE_THREADS_KEY, Integer.MAX_VALUE)
+ .addParameter(Constants.QUEUES_KEY, Integer.MAX_VALUE)
+ .addParameter(Constants.ALIVE_KEY, Integer.MAX_VALUE)
+ .addParameter(Constants.DEFAULT_KEY_PREFIX + Constants.THREADS_KEY, Integer.MAX_VALUE)
+ .addParameter(Constants.DEFAULT_KEY_PREFIX + Constants.THREADPOOL_KEY, "fixed")
+ .addParameter(Constants.DEFAULT_KEY_PREFIX + Constants.CORE_THREADS_KEY, Integer.MAX_VALUE)
+ .addParameter(Constants.DEFAULT_KEY_PREFIX + Constants.QUEUES_KEY, Integer.MAX_VALUE)
+ .addParameter(Constants.DEFAULT_KEY_PREFIX + Constants.ALIVE_KEY, Integer.MAX_VALUE)
+ .addParameter(Constants.DEFAULT_KEY_PREFIX + Constants.THREAD_NAME_KEY, "test");
+
+ URL consumerURL = URL.valueOf("dubbo://localhost:55555");
+ consumerURL = consumerURL.addParameter(Constants.PID_KEY, "1234");
+ consumerURL = consumerURL.addParameter(Constants.THREADPOOL_KEY, "foo");
+
+ URL url = ClusterUtils.mergeUrl(providerURL, consumerURL.getParameters());
+
+ Assert.assertFalse(url.hasParameter(Constants.THREADS_KEY));
+ Assert.assertFalse(url.hasParameter(Constants.DEFAULT_KEY_PREFIX + Constants.THREADS_KEY));
+
+ Assert.assertFalse(url.hasParameter(Constants.DEFAULT_KEY_PREFIX + Constants.THREADPOOL_KEY));
+
+ Assert.assertFalse(url.hasParameter(Constants.CORE_THREADS_KEY));
+ Assert.assertFalse(url.hasParameter(Constants.DEFAULT_KEY_PREFIX + Constants.CORE_THREADS_KEY));
+
+ Assert.assertFalse(url.hasParameter(Constants.QUEUES_KEY));
+ Assert.assertFalse(url.hasParameter(Constants.DEFAULT_KEY_PREFIX + Constants.QUEUES_KEY));
+
+ Assert.assertFalse(url.hasParameter(Constants.ALIVE_KEY));
+ Assert.assertFalse(url.hasParameter(Constants.DEFAULT_KEY_PREFIX + Constants.ALIVE_KEY));
+
+ Assert.assertFalse(url.hasParameter(Constants.THREAD_NAME_KEY));
+ Assert.assertFalse(url.hasParameter(Constants.DEFAULT_KEY_PREFIX + Constants.THREAD_NAME_KEY));
+
+ Assert.assertEquals(url.getPath(), "path");
+ Assert.assertEquals(url.getUsername(), "username");
+ Assert.assertEquals(url.getPassword(), "password");
+ Assert.assertEquals(url.getParameter(Constants.PID_KEY), "1234");
+ Assert.assertEquals(url.getParameter(Constants.THREADPOOL_KEY), "foo");
+ }
+
+}
diff --git a/dubbo-common/pom.xml b/dubbo-common/pom.xml
index 809b17d72cba..0d5e9f761de7 100644
--- a/dubbo-common/pom.xml
+++ b/dubbo-common/pom.xml
@@ -14,57 +14,77 @@
- limitations under the License.
-->
- 4.0.0
-
- com.alibaba
- dubbo-parent
- 2.4.3
-
- dubbo-common
- jar
- ${project.artifactId}
- The common module of dubbo project
-
- true
-
-
-
- org.slf4j
- slf4j-api
- provided
-
-
- commons-logging
- commons-logging-api
- provided
-
-
- log4j
- log4j
-
-
- org.javassist
- javassist
-
-
- com.alibaba
- hessian-lite
-
-
- com.alibaba
- fastjson
- provided
-
-
- org.jvnet.sorcerer
- sorcerer-javac
- provided
-
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ 4.0.0
+
+ com.alibaba
+ dubbo-parent
+ 2.8.4
+
+ dubbo-common
+ jar
+ ${project.artifactId}
+ The common module of dubbo project
+
+ true
+
+
+
+ org.slf4j
+ slf4j-api
+ provided
+
+
+ commons-logging
+ commons-logging-api
+ provided
+
+
+ log4j
+ log4j
+
+
+ org.javassist
+ javassist
+
+
+ com.alibaba
+ hessian-lite
+
+
+ com.alibaba
+ fastjson
+ provided
+
+
+ org.jvnet.sorcerer
+ sorcerer-javac
+ provided
+
cglib
cglib-nodep
test
-
+
+ com.esotericsoftware.kryo
+ kryo
+ provided
+
+
+ de.javakaffee
+ kryo-serializers
+ provided
+
+
+ de.ruedigermoeller
+ fst
+ provided
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ provided
+
+
\ No newline at end of file
diff --git a/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java b/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java
index 82af4beb9461..2c712237bc62 100644
--- a/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java
+++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java
@@ -118,6 +118,8 @@ public class Constants {
public static final int DEFAULT_THREADS = 200;
+ public static final boolean DEFAULT_KEEP_ALIVE = true;
+
public static final int DEFAULT_QUEUES = 0;
public static final int DEFAULT_ALIVE = 60 * 1000;
@@ -134,6 +136,8 @@ public class Constants {
public static final int DEFAULT_CONNECT_TIMEOUT = 3000;
+ public static final int DEFAULT_REGISTRY_CONNECT_TIMEOUT = 5000;
+
public static final int DEFAULT_RETRIES = 2;
// default buffer size is 8k.
@@ -260,6 +264,16 @@ public class Constants {
public static final String SERIALIZATION_KEY = "serialization";
+ // modified by lishen
+ public static final String EXTENSION_KEY = "extension";
+
+ // modified by lishen
+ public static final String KEEP_ALIVE_KEY = "keepalive";
+
+ // modified by lishen
+ // TODO change to a better name
+ public static final String OPTIMIZER_KEY = "optimizer";
+
public static final String EXCHANGER_KEY = "exchanger";
public static final String TRANSPORTER_KEY = "transporter";
@@ -295,6 +309,10 @@ public class Constants {
public static final String PID_KEY = "pid";
public static final String TIMESTAMP_KEY = "timestamp";
+
+ public static final String WARMUP_KEY = "warmup";
+
+ public static final int DEFAULT_WARMUP = 10 * 60 * 1000;
public static final String CHECK_KEY = "check";
@@ -324,7 +342,7 @@ public class Constants {
public static final String HESSIAN_VERSION_KEY = "hessian.version";
- public static final String DISPATHER_KEY = "dispather";
+ public static final String DISPATCHER_KEY = "dispatcher";
public static final String CHANNEL_HANDLER_KEY = "channel.handler";
@@ -573,6 +591,8 @@ public class Constants {
public static final String GENERIC_SERIALIZATION_DEFAULT = "true";
+ public static final String GENERIC_SERIALIZATION_BEAN = "bean";
+
/*
* private Constants(){ }
*/
diff --git a/dubbo-common/src/main/java/com/alibaba/dubbo/common/Version.java b/dubbo-common/src/main/java/com/alibaba/dubbo/common/Version.java
index 70b37e6cb903..80ee7a652496 100644
--- a/dubbo-common/src/main/java/com/alibaba/dubbo/common/Version.java
+++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/Version.java
@@ -16,6 +16,7 @@
package com.alibaba.dubbo.common;
import java.net.URL;
+import java.security.CodeSource;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
@@ -75,42 +76,52 @@ public static String getVersion(Class> cls, String defaultVersion) {
}
if (version == null || version.length() == 0) {
// 如果规范中没有版本号,基于jar包名获取版本号
- String file = cls.getProtectionDomain().getCodeSource().getLocation().getFile();
- if (file != null && file.length() > 0 && file.endsWith(".jar")) {
- file = file.substring(0, file.length() - 4);
- int i = file.lastIndexOf('/');
- if (i >= 0) {
- file = file.substring(i + 1);
- }
- i = file.indexOf("-");
- if (i >= 0) {
- file = file.substring(i + 1);
- }
- while (file.length() > 0 && ! Character.isDigit(file.charAt(0))) {
+ CodeSource codeSource = cls.getProtectionDomain().getCodeSource();
+ if(codeSource == null) {
+ logger.info("No codeSource for class " + cls.getName() + " when getVersion, use default version " + defaultVersion);
+ }
+ else {
+ String file = codeSource.getLocation().getFile();
+ if (file != null && file.length() > 0 && file.endsWith(".jar")) {
+ file = file.substring(0, file.length() - 4);
+ int i = file.lastIndexOf('/');
+ if (i >= 0) {
+ file = file.substring(i + 1);
+ }
i = file.indexOf("-");
if (i >= 0) {
file = file.substring(i + 1);
- } else {
- break;
}
+ while (file.length() > 0 && ! Character.isDigit(file.charAt(0))) {
+ i = file.indexOf("-");
+ if (i >= 0) {
+ file = file.substring(i + 1);
+ } else {
+ break;
+ }
+ }
+ version = file;
}
- version = file;
}
}
// 返回版本号,如果为空返回缺省版本号
return version == null || version.length() == 0 ? defaultVersion : version;
} catch (Throwable e) { // 防御性容错
// 忽略异常,返回缺省版本号
- logger.error(e.getMessage(), e);
+ logger.error("return default version, ignore exception " + e.getMessage(), e);
return defaultVersion;
}
}
+ public static void checkDuplicate(Class> cls, boolean failOnError) {
+ checkDuplicate(cls.getName().replace('.', '/') + ".class", failOnError);
+ }
+
public static void checkDuplicate(Class> cls) {
- checkDuplicate(cls.getName().replace('.', '/') + ".class");
+ checkDuplicate(cls, false);
}
- public static void checkDuplicate(String path) {
+ public static void checkDuplicate(String path, boolean failOnError) {
try {
// 在ClassPath搜文件
Enumeration urls = ClassHelper.getCallerClassLoader(Version.class).getResources(path);
@@ -126,7 +137,12 @@ public static void checkDuplicate(String path) {
}
// 如果有多个,就表示重复
if (files.size() > 1) {
- logger.error("Duplicate class " + path + " in " + files.size() + " jar " + files);
+ String error = "Duplicate class " + path + " in " + files.size() + " jar " + files;
+ if (failOnError) {
+ throw new IllegalStateException(error);
+ } else {
+ logger.error(error);
+ }
}
} catch (Throwable e) { // 防御性容错
logger.error(e.getMessage(), e);
diff --git a/dubbo-common/src/main/java/com/alibaba/dubbo/common/beanutil/JavaBeanAccessor.java b/dubbo-common/src/main/java/com/alibaba/dubbo/common/beanutil/JavaBeanAccessor.java
new file mode 100644
index 000000000000..f01442585c7a
--- /dev/null
+++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/beanutil/JavaBeanAccessor.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1999-2012 Alibaba Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.common.beanutil;
+
+/**
+ * @author kimi
+ */
+public enum JavaBeanAccessor {
+
+ /** Field accessor. */
+ FIELD,
+ /** Method accessor.*/
+ METHOD,
+ /** Method prefer to field. */
+ ALL;
+
+ public static boolean isAccessByMethod(JavaBeanAccessor accessor) {
+ return METHOD.equals(accessor) || ALL.equals(accessor);
+ }
+
+ public static boolean isAccessByField(JavaBeanAccessor accessor) {
+ return FIELD.equals(accessor) || ALL.equals(accessor);
+ }
+
+}
diff --git a/dubbo-common/src/main/java/com/alibaba/dubbo/common/beanutil/JavaBeanDescriptor.java b/dubbo-common/src/main/java/com/alibaba/dubbo/common/beanutil/JavaBeanDescriptor.java
new file mode 100644
index 000000000000..376ebb43ff49
--- /dev/null
+++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/beanutil/JavaBeanDescriptor.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 1999-2012 Alibaba Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.dubbo.common.beanutil;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author kimi
+ */
+public final class JavaBeanDescriptor implements Serializable, Iterable> {
+
+ private static final long serialVersionUID = -8505586483570518029L;
+
+ public static final int TYPE_CLASS = 1;
+
+ public static final int TYPE_ENUM = 2;
+
+ public static final int TYPE_COLLECTION = 3;
+
+ public static final int TYPE_MAP = 4;
+
+ public static final int TYPE_ARRAY = 5;
+
+ /** @see com.alibaba.dubbo.common.utils.ReflectUtils#isPrimitive(Class) */
+ public static final int TYPE_PRIMITIVE = 6;
+
+ public static final int TYPE_BEAN = 7;
+
+ private static final String ENUM_PROPERTY_NAME = "name";
+
+ private static final String CLASS_PROPERTY_NAME = "name";
+
+ private static final String PRIMITIVE_PROPERTY_VALUE = "value";
+
+ /**
+ * Used to define a type is valid.
+ * @see #isValidType(int)
+ */
+ private static final int TYPE_MAX = TYPE_BEAN;
+
+ /**
+ * Used to define a type is valid.
+ * @see #isValidType(int)
+ */
+ private static final int TYPE_MIN = TYPE_CLASS;
+
+ private String className;
+
+ private int type;
+
+ private Map