珠海企业网站设计公司,wordpress去谷歌插件,国外对网站开发的研究,成都网页设计培训机构java launcher自从我开始学习Java以来#xff0c;我几乎已经知道#xff0c; 清单文件中的Class-Path标头字段为可执行JAR #xff08;具有由另一个称为Main-Class清单指定应用程序起点的 JAR#xff09;指定了相对运行时类路径。 一个同事最近碰到一个让我感到惊讶我几乎已经知道 清单文件中的Class-Path标头字段为可执行JAR 具有由另一个称为Main-Class清单指定应用程序起点的 JAR指定了相对运行时类路径。 一个同事最近碰到一个让我感到惊讶因为它证明了一个问题JAR文件的清单的Class-Path条目也影响编译时类路径时包含在类路径中包含JAR在运行javac的 。 这篇文章演示了这种新变化。 Java教程的部署跟踪的“ 将类添加到JAR文件的类路径 ”部分指出“您指定要包含在applet或应用程序清单文件中的Class-Path头字段中的Class-Path 。” 该部分还指出“通过使用清单中的Class-Path标头可以避免在调用Java运行应用程序时指定长的-classpath标志。” 这两个句子从本质上总结了我一直如何想到清单文件中的Class-Path标头作为包含的JAR的类路径是通过Java应用程序启动器 java可执行文件执行的。 事实证明JAR清单中的Class-Path条目会影响Java编译器 javac 就像它会影响Java应用程序启动器 java 一样。 为了演示这一点我将使用一个简单的接口 PersonIF 一个实现该接口的简单类 Person 和一个简单的Main类该类使用实现该接口的类。 接下来显示这些的代码清单。 PersonIF.java public interface PersonIF
{void sayHello();
} 人.java import static java.lang.System.out;public class Person implements PersonIF
{public void sayHello(){out.println(Hello!);}
} Main.java public class Main
{public static void main(final String[] arguments){final Person person new Person();person.sayHello();}
} 从上面的代码清单可以看出 Main类依赖于使用 Person类而Person类依赖于实现 PersonIF 。 我将把PersonIF.class文件放在它自己的名为PersonIF.jar JAR中并将该JAR存储在不同的子目录中。 Person.class文件将存在于其自己的Person.jar JAR文件中并且该JAR文件包括MANIFEST.MF file 该MANIFEST.MF file的Class-Path标头引用了相对子目录中的PersonIF.jar 。 现在我将尝试仅使用类路径中的当前目录从Main.java编译Main.class 。 当javac在单独的子目录中找不到PersonIF.jar时我以前曾期望编译会失败。 但是它不会失败 这让我感到惊讶。 当我没有明确指定PersonIF.class 或包含它的JAR作为通过-cp标志提供的classpath的值时为什么要编译此文件 通过使用带有-verbose标志的javac可以看到答案。 javac -verbose的输出提供“ 源文件的搜索路径”和“ 类文件的搜索路径”。 在这种情况下“类文件的搜索路径”很重要因为我已经将PersonIF.java和Person.java源文件移到了一个完全不相关的目录中而不是在那些指定的搜索路径中。 有趣的是即使我没有在-cp的值中指定此JAR甚至目录类文件的搜索路径以及源文件的搜索路径仍包含archive/PersonIF.jar 。 这表明Oracle提供的Java编译器考虑在类Class-Path上指定的任何JAR的MANIFEST.MF的Class-Path头中指定的类路径内容。 下一个屏幕快照演示了如何运行新编译的Main.class类以及PersonIF.class从archive/PersonIF.jar获取依赖PersonIF.class archive/PersonIF.jar而无需在传递给Java应用程序启动程序的java -cp标志的值中指定依赖PersonIF.class 。 我希望运行时行为是这种方式尽管坦白地说我从未尝试过甚至从未考虑过使用其MANIFEST.MF文件没有Main-Class标头不可执行的JAR的JAR来执行此操作。 在此示例中 Person.jar清单文件未指定Main-Class头而仅指定了Class-Path头但是在使用java调用时仍能够在运行时使用此类路径内容。 本文的最终演示涉及从JAR文件中删除Class-Path标头和关联的值并尝试使用javac和相同的命令行指定的classpath进行编译。 在这种情况下包含Person.class的JAR被称为Person2.jar 下面的屏幕快照演示了其MANIFEST.MF文件没有Class-Path标头。 下一个屏幕快照展示了使用javac现在失败的原因这是因为正如预期的那样没有在类路径上显式指定PersonIF.class 并且不再通过引用JAR的MANIFEST.MF Class-Path头使它可用。类路径。 从上一个屏幕快照中我们可以看到源文件和类文件的搜索路径不再包含archive/PersonIF.jar 。 没有可用的JAR javac将无法找到PersonIF.class并报告错误消息“找不到PersonIF.class类文件。” 一般观察 MANIFEST.MF文件中的Class-Path标头不依赖于存在于同一JAR的MANIFEST.MF文件中的Main-Class标头。 具有Class-Path清单标头的JAR将使这些类路径条目可用于Java类加载器而不管该JAR是使用java -jar ...执行还是仅放置在较大Java应用程序的类路径上。 因为在JAR清单文件中使用Class-Path的范围并不限于正在执行其Main-Class JAR所以这些依赖可能潜在地无意中满足了类依赖即使版本不正确而不是解析明确指定的classpath条目。 在构造带有指定Class-Path清单的JAR时或在清单文件中使用带有Class-Path的第三方JAR时建议谨慎。 有时低估了JAR清单文件的重要性但是该主题提醒人们了解特定JAR清单文件中的内容的有用性。 本主题提醒您可以不时运行javac而无需-verbose来查看其最新信息即可收集的见解。 每当将JAR放置在javac编译器或java应用程序启动器的类路径上时您不仅在类路径中的那个JAR中放置了更多的类定义 您还将在该编译器或应用程序启动器的Class-Path上放置该JAR清单清单的Class-Path引用的所有类和JAR。 结论 Java类加载器可以在许多地方加载用于构建和运行Java应用程序的类。 正如本文所展示的JAR的MANIFEST.MF文件的Class-Path标头是另一个影响点可以影响类加载器在运行时和编译时加载的类。 使用Class-Path不会只影响“可执行”的JAR在清单文件中指定了Main-Class标头并使用java -jar ...运行但可能会影响已加载的类以进行编译以及任何Java应用程序执行其中带有包含Class-Path标头的清单文件的JAR位于类路径上。 翻译自: https://www.javacodegeeks.com/2015/09/jar-manifest-class-path-is-not-for-java-application-launcher-only.htmljava launcher