JAVA

详解eclipse项目中的.classpath文件原理

1.前言


在使用eclipse或者myeclipse进行java项目开发的时候,每个project(工程)下面都会有一个.classpath文件,那么这个文件究竟有什么作用?

2.作用


.classpath文件用于记录项目编译环境的所有信息,包括:源文件路径、编译后class文件存放路径、依赖的jar包路径、运行的容器信息、依赖的外部project等信息。如果把该文件删除,则eclipse不能讲该工程识别为一个正常的java工程,仅仅当做普通的文件夹而导致不能正常运行。

3.classpath内容


.classpath文件其实也是一个xml格式的内容文件,其具体内容大致如下:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" path="src"/>
    <classpathentry kind="src" path="resource"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.7">
        <attributes>
            <attribute name="owner.project.facets" value="java"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/学习 8080">
        <attributes>
            <attribute name="owner.project.facets" value="jst.web"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
    <classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
    <classpathentry kind="output" path="WebContent/WEB-INF/classes"/>
</classpath>
  • ①以”classpath”为根节点,每个“classpathentry”节点代表一个说明信息。
  • ②每个“classpathentry”以“kind”属性指明类型,“path”指明路径。
  • ③以上文件的所有内容,都是依赖项目中的“Java Build Path”内容改变而改变的,即对“Java Build Path”的所有操作都会反应到文件内容中。

现在来具体分析文件内容的每个节点含义

3.1 kind=”src”

src:即source 源文件,代表的是一个源文件,path=”src”是一个相对路径,相对.classpath文件本身,即path=”src”表示文件夹src与.classpath在同一个目录,且代表源文件。

<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="resource"/>

kind=”src”的操作对应于“Java Build Path”的“Source”tab页

如下图,增加一个文件夹bin作为源文件,则.classpath文件增加内容

内容增加如下:

<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="bin"/>
<classpathentry kind="src" path="resource"/>

当然,做相应修改或删除,同样.classpath文件内容会相应改变。

另外,当指定属性combineaccessrules=”false”是则代表引入外部project,具体如下

<classpathentry combineaccessrules="false" kind="src" path="/mybatis"/>

对应页面tab,其中path=”/mybatis”,是相对应workspace下的

绝对路径。

3.2 kind=”output”

output用于指定java源文件编译后的class文件存放路径,格式如下

<classpathentry kind="output" path="WebContent/WEB-INF/classes"/>

path:代表存放class文件路径,同样是相对.classpath文件的路径,找到“WebContent/WEB-INF/classes”,可以看到class文件的存放

假设修改输出文件路径,则相应内容也会改变

改为:spring-mybatis\WebContent\WEB-INF\newclasses

则.classpath文件内容修改为:

<classpathentry kind="output" path="WebContent/WEB-INF/newclasses"/>

实际存放class文件的路径也会改变

3.3 kind=”con”

con即是container,就是程序运行的容器,或者就说是运行环境也OK,它实际上是在Myeclipse最初的时候要配置installed JREs中指定(一般情况下我们指定的是JDK),但是这里实际使用的是JDK下的JRE中的jar包,就是JDK_HOME/jre/lib就是对应的这条语句。具体内容如下

<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.7">
        <attributes>
            <attribute name="owner.project.facets" value="java"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/学习 8080">
        <attributes>
            <attribute name="owner.project.facets" value="jst.web"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
    <classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>

对应操作tab如下

3.3.1 JRE配置

path=”XXX”用于指定jre容器的使用情况,可选择jre的不同来源,不同来源path的实际值会有些变化

①选择”Workspace default JRE(jdk1.7)”,则值为

path="org.eclipse.jdt.launching.JRE_CONTAINER"

②选择“Alternate JRE”,则值为

path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.7"

其中最后么的jdk1.7是我自定义的JRE名称

③选择”Execution environment”,即选择eclipse自带的内置jre,值为

path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"

其中最后么的JavaSE-1.7是系统内置的JRE名称

另外属性值name=”owner.project.facets”

<attribute name="owner.project.facets" value="java"/>

应该是指定JRE容器的具体使用的模板,默认使用”java”,具体的没有探究。

3.3.2 Server Runtime配置

同理,其他容器配置同上,如对Server Runtime 容器的配置,下面配置了tomcat容器运行环境

<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/学习 8080"/>

3.3.3 Web App Libraries配置

<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>

3.3.4 User Library配置

<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/tomcat7"/>

3.4 kind=”lib”


kind=”lib”用于指定project依赖的Referenced Libraries,如图增加了一个jar包

则相应.classpath文件内容增加

<classpathentry kind="lib" path="WebContent/WEB-INF/lib/commons-dbcp-1.2.1.jar"/>

其中path指定了依赖的jar的相对路径。

3.5 顺序


.classpath文件中各节点的顺序是通过tab-Order and Export 来控制的,不同的顺序可能会引起加载class文件问题,一般是源码放在最前面。

4 总结


1.classpath文件时eclipse新建web工程的时候生成的一个文件(就在工程目录下),改变java Build path的时候或者改变加载的jar包顺序的时候,这个文件也会改变。

2、.classpath文件不能随意删除。个人在将已有的工程import进入eclipse工作区的时候将.classpath文件删除了,然后再重新导入jar包,整个工程就会重新编译,也就会产生.classpath文件,但是这个重新生成的.classpath文件的内容可能就会出问题,也就有可能导致在tomcat部署的时候出现不可预料的问题。

例如:
原始的.classpath文件部分主要内容如下:

<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="WebRoot/WEB-INF/classes"/>

个人删除后,eclipse重新build的.classpath文件部分主要内容如下:

<classpathentry kind="src" path=""/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.6.0_11"/>
<classpathentry kind="output" path="/bin"/>

说明下: 表示工程源文件的地址;
表示产生的class文件地址;

比较前后两个.classpath文件可以发现,重新build的.classpath文件里面的源文件地址为

<classpathentry kind="src" path=""/>

这样,在整个工程里面就会出现所有package错误,此时eclipse默认为package src.com.test, 而工程里面正确的包名应该是 package com.test

另外,如果新生成的.classpath文件class文件地址为bin目录下的,即 ,tomcat部署工程的时候,默认去WebRoot/WEN-INF/classes这个目录查找class文件,而此时class文件去不存在于bin目录下面,故而tomcat下面没有class文件,在启动时也就会产生ClassNotFoundException错误!

如果碰到以上问题的话,则可以参考原始.classpath文件修改过来就可以了

补充:Eclipse 在导入工作区时不需要 .project 和 .classpath 文件/Eclipse 如何将项目识别为项目


Eclipse or any other IDE doesn’t required .classpath or .project files. These files will be auto created during the project import. IDE can capable to pull the artifacts from maven central repo automatically by using build descriptor file such as pom.xml or build.graddle. The files .classpath and .project will store the paths from local machine, if we carry them to another system, the artificats and other dependencies may not be present in the same directory, so it will start complaining build errors. Thats why while committing to GIT always there is .gitignore, so that local configuration will not carry to others while contributing.

https://stackoverflow.com/questions/62425247/why-sometimes-eclipse-doesnt-need-project-and-classpath-file-during-importing