简体   繁体   English

为什么项目在不设置类路径环境变量的情况下也能正常工作?

[英]Why projects work properly without setting classpath environment variable?

I try to understand what CLASSPATH does for Java and Spring Boot projects.我试图了解 CLASSPATH 对 Java 和 Spring 引导项目的作用。 And I see that it is am environment variable and it is used to provide the root of any package hierarchy to java compiler.我看到它是一个环境变量,它用于将任何 package 层次结构的根提供给 java 编译器。 But I didn't set this CLASSPATH, it's missing from environment variables and the projects are working properly.但是我没有设置这个 CLASSPATH,环境变量中没有它,项目运行正常。 I set only the PATH environment variable and I put the location of jdk/bin.我只设置了 PATH 环境变量,我把 jdk/bin 的位置。

On the other hand, I'm working now at a multimodule Maven project on Intellij, and for example if I try to use the class ObjectMapper in a module where I don't have the dependency it says:另一方面,我现在正在 Intellij 上的多模块 Maven 项目中工作,例如,如果我尝试在没有依赖项的模块中使用 class ObjectMapper,它会说:

Cannot resolve symbol 'ObjectMapper'

Add library 'Maven com.fasterxml.jackson.core:jackson-databind.2.13.1' to classpath

在此处输入图像描述

And when I click it, it adds the jackson-databind dependency in the pom.xml at this modul.当我单击它时,它会在此模块的 pom.xml 中添加 jackson-databind 依赖项。 So in this case it seems that classpath refers to the pom.xml, not an environment variable.所以在这种情况下,类路径似乎是指 pom.xml,而不是环境变量。 Are these different types of classpath?这些是不同类型的类路径吗? And why my projects are working properly without having the classpath environment variable?为什么我的项目在没有类路径环境变量的情况下也能正常工作? Thank you!谢谢!

The IDE puts 'Maven Dependancies' on the class path. IDE 将“Maven Dependancies”放在 class 路径上。

When a jar is built for deployment Maven puts all the listed dependencies in the jar file it builds.当为部署构建 jar 时,Maven 将所有列出的依赖项放入它构建的 jar 文件中。 Java knows how to read this info and put the right locations on the classpath. Java 知道如何读取此信息并将正确的位置放在类路径中。

The locations of jars are listed in the META-INF\MANIFEST.MF jars 的位置在META-INF\MANIFEST.MF中列出

Manifest-Version: 1.0
Created-By: Maven JAR Plugin 3.2.2
Build-Jdk-Spec: 11
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.altron.ne.SpringBootApp
Spring-Boot-Version: 2.7.2
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx

In this case (Spring Boot application) the dependency jars are all in BOOT-INF/lib/ within the main jar file.在这种情况下(Spring Boot 应用程序)依赖项 jars 都在BOOT-INF/lib/主文件 jar 中。

The classpath is a feature of the JVM (actually: the built-in ClassLoader s) that allows you to specify where Java (without any extensions) should load classes from: a list of.jar files that contain classes and a list of directories that contain classes.类路径是 JVM(实际上:内置的ClassLoader s)的一个特性,它允许您指定 Java(没有任何扩展名)应该从哪里加载类:a list of .jar files that contain classes and a list of directories that包含类。

When you start a Java application with当您启动 Java 应用程序时

java -jar yourapp.jar

the classpath (as defined either through the environment variable "CLASSPATH" or through the command line argument "-cp") is ignored.忽略类路径(通过环境变量“CLASSPATH”或命令行参数“-cp”定义)。

Instead of that, Java reads the file "META-INF/MANIFEST.MF" and uses two attributes from that file:相反,Java 读取文件“META-INF/MANIFEST.MF”并使用该文件的两个属性:

  • Class-Path contains the list of jar files and directories to read class files from Class-Path包含 jar 个文件和目录的列表,以从中读取 class 个文件
  • Main-Class contains the name of the class that contains the public static void main(String... args) method Main-Class包含 class 的名称,其中包含public static void main(String... args)方法

Spring Boot is a special case because it brings its own ClassLoader implementation that loads additional classes not from Javas classpath. Spring Boot 是一种特殊情况,因为它带来了自己的ClassLoader实现,可以加载不是来自 Java 类路径的其他类。

In a Spring Boot application only the "Main-Class" attribute is set, meaning that only classes directly contained in the jar are on the classpath.在 Spring Boot 应用程序中,仅设置了“Main-Class”属性,这意味着只有直接包含在 jar 中的类才会出现在类路径中。 Among these classes is a Spring Boot specific ClassLoader (the LaunchedURLClassLoader ) and it is this special ClassLoader the interprets the "Spring-Boot-Classes" and "Spring-Boot-Lib" attributes.在这些类中有一个 Spring Boot 特定的ClassLoaderLaunchedURLClassLoader ),正是这个特殊的 ClassLoader 解释了“Spring-Boot-Classes”和“Spring-Boot-Lib”属性。

Using this method allows Spring Boot to package all dependencies into a single "yourapp.jar" file - something that Java doesn't support out-of-the-box.使用此方法允许 Spring 引导到 package 所有依赖项都放入单个“yourapp.jar”文件中 - Java 不支持开箱即用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM