package com.github.ltsopensource.core.support; import com.github.ltsopensource.core.commons.utils.ClassHelper; import com.github.ltsopensource.core.logger.Logger; import com.github.ltsopensource.core.logger.LoggerFactory; import java.net.URL; import java.security.CodeSource; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; /** * 参考dubbo * @author Robert HG (254963746@qq.com) on 5/19/15. */ public final class Version { private Version() {} private static final Logger LOGGER = LoggerFactory.getLogger(Version.class); private static final String VERSION = getVersion(Version.class, "1.7.1-SNAPSHOT"); static { // 检查是否存在重复的jar包 Version.checkDuplicate(Version.class); } public static String getVersion(){ return VERSION; } 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包名获取版本号 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); } 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("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, false); } public static void checkDuplicate(String path, boolean failOnError) { try { // 在ClassPath搜文件 Enumeration<URL> urls = ClassHelper.getCallerClassLoader(Version.class).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) { 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); } } }