zoukankan      html  css  js  c++  java
  • 用Intellij idea创建Maven项目JDK8源码阅读环境问题整理

    搭建Java源码阅读环境,有两种类型,一种是调试 Java API 代码,另一种是深入 Java 底层编译 C++ 代码。本文主要还停留在 API 层面,搭建的是阅读 Java API 代码的环境。

    本文使用的 JDK 是 1.8.0_131。

    创建项目和首次编译:

    关于步骤,网上很多可以找到的,我这里就提供两个链接:

    创建 Java 项目源码阅读环境 here

    创建 Maven 项目源码阅读环境 here

    主要流程:

    1. 创建空项目(Java 或者 Maven 项目)
    2. 拷贝安装jdk的目录中拷贝 src.zip 解压到新建的空项目中
    3. Build 项目

    问题一:源值1.5已过时

    Error:(131, 21) java: -source 1.5 中不支持 diamond 运算符 (请使用 -source 7 或更高版本以启用 diamond 运算符),如下图所示:

    原因解析:
    Java 版本不对。

    解决方法:
    1.首先,修改 Settings 中 Java Compiler 配置:

    2.然后,修改项目 Modules 模块中的 Language Level 配置:

    关于修改 Language Leve 后的警告:

    解决建议:
    pom.xml 中增加这段配置:

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <encoding>UTF-8</encoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    

    问题一解决参考博客:
    git下载的项目报错:Warning:java: 源值1.5已过时, 将在未来所有发行版中删除;找不到或无法加载主类...
    maven 指定java版本1.8

    问题二:UNIXToolkit和FontConfigManager 找不到

    Error:(27, 15) java: 找不到符号 符号: 类 UNIXToolkit 位置: 程序包 sun.awt
    Error:(33, 16) java: 找不到符号 符号: 类 FontConfigManager 位置: 程序包 sun.font

    因为Windows环境下缺少了两个文件导致的,我们需要自己去OpenJDK网站下载 OpenJDK

    给你们 2 个链接:

    下载地址由 JDK8源码阅读-WINDOWS下环境搭建 提供!

    问题三:com.sun.tools.javac.api不存在

    Error:(40, 31) java: 程序包com.sun.tools.javac.api不存在。

    1.拷贝 JDK安装目录/lib/tools.jarMaven项目根目录/lib/tools.jar
    2.打开 Project Structure -> Libraries 新增本地依赖 tools.jar

    引入Junit源码调试

    我不太想在 src/main/java 添加太多的类,所以我选择引入单元测试,你们可以选择引入 Junit4,这样比较简单

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    

    我最近了解了 Junit5 和 AssertJ 想要尝试一下,所以我用的是

    <dependencies>
        <!-- JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage -->
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-launcher</artifactId>
            <version>1.0.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.0.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <version>4.12.1</version>
            <scope>test</scope>
        </dependency>
        <!--AssertJ 流式断言-->
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.17.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    

    然后创建一个测试用例,我这里用的 Junit5 + AssertJ 的测试用例哦,Junit4 使用时会编译错误。

    import org.junit.Test;
    import org.junit.jupiter.api.DisplayName;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import static org.assertj.core.api.Assertions.assertThat;
    
    public class FirstTest {
    
        @Test
        @DisplayName("首次测试")
        public void first_test() {
            List<String> list = new ArrayList<>();
            list.add("张三");
            list.add("李四");
            list.add("王五");
            assertThat(list).hasSize(3)
                    .contains("张三");
        }
    }
    

    关于引入 Junit5 时如何配置 pom.xml
    官网:Junit5 user-guide
    GitHub:junit5-jupiter-starter-maven/pom.xml
    如果你访问不了 GitHub:解决mvn test运行Junit5测试用例时检测不到测试类的问题 ,有截图。

    问题四:Debug总是进入反编译class

    既然是源码阅读,我们肯定希望代码能够进入我们的类中,而不是进入反编译的 class 类。

    4.1 创建移除 rt.jar 的 Platform SDK

    首先,打开 Project Structure,在 SDKs 点击 + 选择 JDK8 安装目录,创建一个名为 1.8-without-rt 的 SDK, 并从 ClassPath 中移除 rt.jar。

    项目之间是共享 SDK 的,因此建议保留原来的 SDK 1.8,然后创建一个新的 1.8-without-rt 来做调试之用

    4.2 修改 Project SDK

    在 Project Structure 中,切换到 Project Settings 下的 Project 栏,选择 Project SDK 为刚才新建的 1.8-without-rt

    4.3 引入 lib/rt.jar 为本地依赖

    引入 lib/rt.jar 是为了解决切换到 1.8-without-rt 导致找不到 sun.misc.Unsafe 等类的问题。

    现在,我们的源码项目的代码变成首选了。

    问题五:程序包sun.reflect.misc不存在

    Error:(72,24) java: 程序包sun.reflect.misc不存在
    Error:(152,24) java: 程序包javax.crypto不存在
    Error:(40,31) java: 程序包com.sun.tools.javac.api不存在

    【官方解释】:javac uses a special symbol table that does not include all Sun-proprietary classes. When javac is compiling code it doesn't link against rt.jar by default. Instead it uses special symbol file lib/ct.sym with class stubs.大意是:javac在编译时,并不引用 rt.jar,用的是一个特别的symbol table(lib/ct.sym),这个symbol table不包含所有的sun包的类。

    【具体原因】:J2SE中的类大致可以划分为以下的各个包:java.,javax.,org.,sun.;除了“sun”包,其它各个包都是Java平台的标准实现,并且今后也将被继续支持。一般说来,“sun”之类的包并不包含在Java平台的标准中,它与操作系统相关,在不同的操作系统(如Solaris,Windows,Linux,Mac等等)中的实现也各不相同,并且可能随着J2SE版本不定期变化。因此,直接调用“sun”包的程序代码并不是100%的Java实现。也就是说:“sun.*”包并不是API公开接口的一部分,调用“sun”包的程序并不能确保工作在所有Java平台上,事实上,这样的程序并不能工作在今后的Java平台上。

    5.1 保证 rt.jar 和 jce.jar 在 lib 中

    首先,从 JDK8 安装目录jrelib 把 jce.jar 和 rt.jar 拷贝到 项目根目录lib;
    另外,从 JDK8 安装目录lib 把 tools.jar 拷贝到 项目根目录lib;
    然后,把这 3 个 lib 加入到本地依赖中,和之前 2 次的操作相似

    5.2 编辑POM文件

    关键的是这一段:

    <compilerArguments>
      <bootclasspath>${project.basedir}/lib/rt.jar;${project.basedir}/lib/jce.jar;${project.basedir}/lib/tools.jar</bootclasspath>
    </compilerArguments>
    

    完整的 build 标签如下:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                    <compilerArguments>
                        <bootclasspath>${project.basedir}/lib/rt.jar;${project.basedir}/lib/jce.jar;${project.basedir}/lib/tools.jar</bootclasspath>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <!-- JUnit 5 requires Surefire version 2.22.0 or higher -->
                <version>2.22.2</version>
            </plugin>
        </plugins>
    </build>
    

    参考博客 Maven编译项目显示 程序包com.sun.*包不存在 【原因及三种解决方案】
    参考博客 maven编译时javax.crypto程序包不存在的错误
    参考博客 “程序包com.sun.tools.javac.util不存在” 问题解决

  • 相关阅读:
    11111 Generalized Matrioshkas
    Uva 442 Matrix Chain Multiplication
    Uva 10815 Andy's First Dictionary
    Uva 537 Artificial Intelligence?
    Uva 340 MasterMind Hints
    SCAU 9508 诸葛给我牌(水泥题)
    Uva 10420 List of Conquests(排序水题)
    Uva 409 Excuses, Excuses!
    10/26
    11/2
  • 原文地址:https://www.cnblogs.com/kendoziyu/p/14446030.html
Copyright © 2011-2022 走看看