`
BucketLi
  • 浏览: 195874 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
5a76a659-f8e6-3bf3-b39a-8ae8f7a0f9d9
Percolator与分布...
浏览量:5686
社区版块
存档分类
最新评论

java获取类版本和检查重复代码

 
阅读更多
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/xxx/xxx.class");

    private static final boolean COMPATIBLE = hasResource("com/xxx/xxx.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包名获取版本号
                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);
		}
	}

}
分享到:
评论

相关推荐

    java 工具类代码集合

    Java工具类代码集合是Java开发中非常重要的组成部分,它们提供了许多通用的功能,使得开发者能够更加高效地编写代码,避免重复劳动。在这个集合中,我们通常会看到各种实用的方法,涵盖字符串处理、数组操作、日期...

    java代码检测工具

    4. **重复的代码(Duplicate Code)**:PMD可以检测出代码中重复的部分,鼓励开发者将重复代码抽象成可重用的方法或类,以提高代码复用性。 5. **无效的空检查**:如果检测到对null对象的空检查,但该对象在检查之前...

    基于JavaParser的代码调用链分析,可以用于分析Java代码的方法调用链.zip

    - **重构建议**:提供自动化重构的建议,如提取重复代码,简化调用链,优化接口设计等。 JavaParser库还提供了其他功能,例如修改和生成新的Java源代码。结合其他工具和框架,如Lombok或ASM,可以实现更高级的代码...

    java集合类的代码

    这个压缩包文件“Collection”很可能包含了关于Java集合类的一些示例代码,这些代码可以用于理解和学习如何在实际项目中应用这些集合。 Java集合框架主要由两个接口层次构成:Collection和Map。Collection是所有单...

    JAVA 数独游戏代码

    本Java数独游戏程序通过Swing框架构建了一个图形界面,用户可以通过点击按钮和选择菜单项来生成新的数独题目、查看答案、获取提示等操作。程序还支持自定义难度等级,使得游戏更具挑战性和趣味性。此外,通过实现...

    java常用代码方法

    - `Class` 类允许运行时检查和操作类的信息,如获取构造函数、方法和字段。 - `newInstance()` 方法可以动态创建对象,`getMethod()` 和 `invoke()` 用于调用方法。 8. **IO 流和 NIO**: - Java I/O 流提供了...

    Java学习基本代码

    继承允许子类继承父类的属性和方法,减少代码重复。多态是指同一种行为在不同对象上有不同的表现形式,是Java实现抽象和泛化的关键。 6. **异常处理**:Java提供了异常处理机制,通过`try-catch-finally`块捕获和...

    常用Java工具类

    以上工具类在实际开发中都有着广泛的应用,它们提高了代码的可复用性和可维护性,减少了重复的工作,使得程序员能够更专注于业务逻辑的实现。通过熟练掌握和使用这些工具类,可以提升Java开发的效率和质量。

    java日常处理工具类part1-代码

    Java日常处理工具类是开发过程中不可或缺的部分,它们通常包含了各种常用功能的静态方法,能够极大地提高开发效率,减少代码重复。Part1中的"java日常处理工具类part1-代码"很可能是对Java基础工具类的一个初步介绍...

    数据库连接池java代码实现

    总结来说,数据库连接池通过Java代码实现的核心包括连接池的初始化、连接的获取与释放、以及资源的管理和监控。通过自定义连接池,我们可以控制连接的生命周期,优化资源使用,从而提高应用的性能和稳定性。在实际...

    java中的一个简单游戏代码

    在这个场景中,"java中的一个简单游戏代码"可能是指一个用Java编写的教学示例,它可能包含了一个获取随机不重复数字的算法。这个特性在很多游戏中非常常见,比如抽奖、猜数字等类型的游戏。 首先,我们来看一下如何...

    java utils 工具类

    - 使用工具类可以减少重复代码,提高代码质量。 - 在处理特定问题时,如字符串格式化、日期转换等,可以快速找到相应的工具方法。 - 通过引入第三方工具库,可以利用其封装好的复杂功能,节省开发时间。 总的来...

    Java开发工具代码库

    Java开发工具代码库是Java程序员日常工作中不可或缺的资源集合,它包含了各种常用的功能模块和工具类,旨在提高开发效率,减少重复劳动。这个代码库通常会涵盖字符串处理、日期时间操作、集合操作、IO流、网络通信、...

    JAVA斗地代码模拟

    【JAVA斗地主代码模拟】是一个实用的教学案例,旨在帮助学习者深入理解和运用Java编程语言中的Map数据结构。斗地主是一种在中国广受欢迎的扑克游戏,它的规则复杂且有趣,涉及策略、概率和技巧。在Java中实现斗地主...

    PMD--java代码检视工具

    PMD通过定义一系列规则来检查代码,这些规则涵盖了设计、效率、命名规范、重复代码等多个方面,为编写整洁、高效的代码提供了有力支持。 **PMD的工作原理** PMD通过解析Java源代码文件,生成抽象语法树(Abstract ...

    java核心技术的源代码

    8. **反射**:Java反射API允许在运行时动态获取类的信息,包括类名、字段、方法等,并能动态创建对象、调用方法。这对于框架开发、元编程和插件系统非常有用。 9. **JVM内部机制**:了解Java虚拟机的工作原理,如...

    sql自动生成java代码

    当提到"SQL自动生成Java代码",通常是指通过执行特定的SQL查询,自动生成对应的Java实体类,这些实体类包含了字段(对应数据库表的列)和注解(用于ORM框架识别和映射)。例如,`@Entity`表示这是一个实体类,`@...

    Java集合详解代码.zip

    本资料“Java集合详解代码.zip”涵盖了Java集合框架的主要组成部分,包括List、Set、Map以及Collections工具类,通过代码实现来帮助理解和掌握这些概念。 1. **List接口**:List是有序的集合,允许重复元素,支持...

    30个java工具类

    2. **时间工具类(TimeUtil.java)**:这类工具类主要用于处理时间和日期,可能包括获取当前时间、时间戳转换、日期格式化、时间间隔计算等功能。在处理与时间相关的业务逻辑时,这些方法非常实用。 3. **日期工具类...

    Java虚拟机类装载的原理及实现

    类装载是Java虚拟机中一个至关重要的过程,它不仅决定了类如何被加载到内存中,还涉及到一系列的安全检查和初始化操作。通过深入了解类装载的过程和机制,开发者可以更好地利用这一特性来优化和增强Java应用程序的...

Global site tag (gtag.js) - Google Analytics