热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java工具用于从jar名称自动派生模块名称的算法

如何解决《Java工具用于从jar名称自动派生模块名称的算法》经验,为你挑选了1个好方法。

Java 9+工具用于从模块路径上的非模块化jar的名称自动派生模块名称的算法是什么?



1> 小智..:

部署在模块路径上的非模块化JAR文件是自动模块.如果JAR文件具有主要属性Automatic-Module-Name(请参阅主要属性),则属性的值是模块名称,否则模块名称是从ModuleFinder.of(Path ..)中指定的JAR文件的名称派生的. .) .

如果您想了解更多信息,可以随时查找源代码:

/**
 * Treat the given JAR file as a module as follows:
 *
 * 1. The module name (and optionally the version) is derived from the file
 *    name of the JAR file
 * 2. The packages of all .class files in the JAR file are exported
 * 3. It has no module-private/concealed packages
 * 4. The contents of any META-INF/services configuration files are mapped
 *    to "provides" declarations
 * 5. The Main-Class attribute in the main attributes of the JAR manifest
 *    is mapped to the module descriptor mainClass
 */
private ModuleDescriptor deriveModuleDescriptor(JarFile jf)
    throws IOException
{
    // Derive module name and version from JAR file name

    String fn = jf.getName();
    int i = fn.lastIndexOf(File.separator);
    if (i != -1)
        fn = fn.substring(i+1);

    // drop .jar
    String mn = fn.substring(0, fn.length()-4);
    String vs = null;

    // find first occurrence of -${NUMBER}. or -${NUMBER}$
    Matcher matcher = Patterns.DASH_VERSION.matcher(mn);
    if (matcher.find()) {
        int start = matcher.start();

        // attempt to parse the tail as a version string
        try {
            String tail = mn.substring(start+1);
            ModuleDescriptor.Version.parse(tail);
            vs = tail;
        } catch (IllegalArgumentException ignore) { }

        mn = mn.substring(0, start);
    }

    // finally clean up the module name
    mn = cleanModuleName(mn);

    // Builder throws IAE if module name is empty or invalid
    ModuleDescriptor.Builder builder
        = new ModuleDescriptor.Builder(mn)
            .automatic()
            .requires(Set.of(Requires.Modifier.MANDATED), "java.base");
    if (vs != null)
        builder.version(vs);

    // scan the names of the entries in the JAR file
    Map> map = VersionedStream.stream(jf)
            .filter(e -> !e.isDirectory())
            .map(JarEntry::getName)
            .collect(Collectors.partitioningBy(e -> e.startsWith(SERVICES_PREFIX),
                                               Collectors.toSet()));

    Set resources = map.get(Boolean.FALSE);
    Set cOnfigFiles= map.get(Boolean.TRUE);

    // all packages are exported
    resources.stream()
            .map(this::toPackageName)
            .flatMap(Optional::stream)
            .distinct()
            .forEach(builder::exports);

    // map names of service configuration files to service names
    Set serviceNames = configFiles.stream()
            .map(this::toServiceName)
            .flatMap(Optional::stream)
            .collect(Collectors.toSet());

    // parse each service configuration file
    for (String sn : serviceNames) {
        JarEntry entry = jf.getJarEntry(SERVICES_PREFIX + sn);
        Set providerClasses = new LinkedHashSet<>();
        try (InputStream in = jf.getInputStream(entry)) {
            BufferedReader reader
                = new BufferedReader(new InputStreamReader(in, "UTF-8"));
            String cn;
            while ((cn = nextLine(reader)) != null) {
                if (cn.length() > 0) {
                    providerClasses.add(cn);
                }
            }
        }
        if (!providerClasses.isEmpty())
            builder.provides(sn, providerClasses);
    }

    // Main-Class attribute if it exists
    Manifest man = jf.getManifest();
    if (man != null) {
        Attributes attrs = man.getMainAttributes();
        String mainClass = attrs.getValue(Attributes.Name.MAIN_CLASS);
        if (mainClass != null)
            builder.mainClass(mainClass);
    }

    return builder.build();
}

/**
 * Patterns used to derive the module name from a JAR file name.
 */
private static class Patterns {
    static final Pattern DASH_VERSION = Pattern.compile("-(\\d+(\\.|$))");
    static final Pattern NON_ALPHANUM = Pattern.compile("[^A-Za-z0-9]");
    static final Pattern REPEATING_DOTS = Pattern.compile("(\\.)(\\1)+");
    static final Pattern LEADING_DOTS = Pattern.compile("^\\.");
    static final Pattern TRAILING_DOTS = Pattern.compile("\\.$");
}


推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了如何清除Eclipse中SVN用户的设置。首先需要查看使用的SVN接口,然后根据接口类型找到相应的目录并删除相关文件。最后使用SVN更新或提交来应用更改。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 开发笔记:Java是如何读取和写入浏览器Cookies的
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java是如何读取和写入浏览器Cookies的相关的知识,希望对你有一定的参考价值。首先我 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
author-avatar
jinshiyuan1123
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有