blob: 9e8e5fbd5cd7d958ac80887db39460e4968ebfc3 [file] [log] [blame]
/*
* 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.common;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
/**
* Version
*
* @author william.liangf
*/
public final class Version {
private Version() {}
private static final Logger logger = LoggerFactory.getLogger(Version.class);
private static final String VERSION = getVersion(Version.class, "2.0.0");
private static final boolean INTERNAL = hasResource("com/alibaba/dubbo/registry/support/remote/RemoteRegistry.class");
private static final boolean COMPATIBLE = hasResource("com/alibaba/dubbo/rpc/dubbo/internal/DubboRequest.class");
static {
// 检查是否存在重复的jar包
Version.checkDuplicate(Version.class);
}
public static String getVersion(){
return VERSION;
}
public static boolean isInternalVersion() {
return INTERNAL;
}
public static boolean isCompatibleVersion() {
return COMPATIBLE;
}
private static boolean hasResource(String path) {
try {
return Version.class.getClassLoader().getResource(path) != null;
} catch (Throwable t) {
return false;
}
}
public static String getVersion(Class<?> cls, String defaultVersion) {
try {
// 首先查找MANIFEST.MF规范中的版本号
String version = cls.getPackage().getImplementationVersion();
if (version == null || version.length() == 0) {
version = cls.getPackage().getSpecificationVersion();
}
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))) {
i = file.indexOf("-");
if (i >= 0) {
file = file.substring(i + 1);
} else {
break;
}
}
version = file;
}
}
// 返回版本号,如果为空返回缺省版本号
return version == null || version.length() == 0 ? defaultVersion : version;
} catch (Throwable e) { // 防御性容错
// 忽略异常,返回缺省版本号
logger.error(e.getMessage(), e);
return defaultVersion;
}
}
public static void checkDuplicate(Class<?> cls) {
checkDuplicate(cls.getName().replace('.', '/') + ".class");
}
public static void checkDuplicate(String path) {
try {
// 在ClassPath搜文件
Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(path);
Set<String> files = new HashSet<String>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
if (url != null) {
String file = url.getFile();
if (file != null && file.length() > 0) {
files.add(file);
}
}
}
// 如果有多个,就表示重复
if (files.size() > 1) {
logger.error("Duplicate class " + path + " in " + files.size() + " jar " + files);
}
} catch (Throwable e) { // 防御性容错
logger.error(e.getMessage(), e);
}
}
}