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不存在” 问题解决

  • 相关阅读:
    工作总结(二):Web Design
    工作总结(一):Linux C
    三十分钟学会AWK
    MySQL并发复制系列二:多线程复制 2016
    修改MySQL 5.7.9版本的root密码方法以及一些新变化整理
    sync_binlog innodb_flush_log_at_trx_commit 浅析
    MariaDB的"response time"插件
    Python学习九:列表生成式
    python中的深拷贝和浅拷贝理解
    Mycat 配置
  • 原文地址:https://www.cnblogs.com/kendoziyu/p/14446030.html
Copyright © 2011-2022 走看看