Windows 上安装与配置 jdk1.6.0_06:环境变量、多版本共存与避坑指南 简介本资源为面向32位Windows系统的Java Development Kit 1.6.0_06完整安装包适合需要在旧版Windows环境下进行Java开发、测试或维护遗留项目的开发者与学习者。JDK作为Java编程的核心工具集内含编译器、调试器、文档生成器及Java虚拟机等组件可满足从代码编写、编译到运行调试的完整开发需求。压缩包共690个文件以exe可执行程序、dll动态链接库、jar包、properties配置文件和rtf说明文档为主另含html指南、ttf字体及大量时区数据文件整体约40.89MB目录结构清晰涵盖bin、jre、include、db等标准模块。已有324人学习下载。通过README与LICENSE文件可快速了解安装步骤与许可条款JRE部分则为运行Java应用提供必要环境便于读者在32位平台上搭建稳定的Java 6开发环境并开展实际项目调试。1. 老 JDK 的考古现场为什么还有人要碰 jdk1.6.0_06如果你在维护一套十年前甚至更早的 Java 业务系统大概率会遇到一个绕不开的东西jdk1.6.0_06。这个版本号看着不起眼但它是 Java 6 早期的一个更新版本很多老项目的编译产物、依赖库、甚至应用服务器的启动脚本都跟它绑得死死的。你拿 JDK 8 或 JDK 11 去跑轻则UnsupportedClassVersionError重则类加载器行为不一致日志里一堆看不懂的NoSuchMethodError。这篇文章要解决的就是在 Windows 上把jdk1.6.0_06跑起来并且让它跟现代开发环境共存。适合谁适合那些接手了遗留系统、需要本地复现生产环境、或者要给老项目做最小化补丁的工程师。不是讲 Java 历史是讲怎么让这个老古董在你的机器上不翻车。2. 在 Windows 上把 jdk1.6.0_06 装明白路径、变量与共存策略2.1 为什么不能直接双击安装包一路下一步jdk1.6.0_06的 Windows 安装包通常是.exe或.msi默认会往C:\Program Files\Java\下面塞。问题在于这个版本的安装程序对现代 Windows 的权限模型和路径长度都不太友好。我一般会选自定义安装把路径改成短路径比如C:\Java\jdk1.6.0_06。原因有两个一是避免空格和括号在后续脚本里被转义搞死二是方便你同时放多个 JDK 版本用的时候直接切。安装类型选“自定义”取消掉公共 JRE 的安装。老项目的 JRE 通常跟 JDK 一起用单独装一个公共 JRE 反而会让JAVA_HOME和PATH打架。安装完成后目录结构应该是这样的C:\Java\jdk1.6.0_06\ ├── bin\ │ ├── java.exe │ ├── javac.exe │ └── ... ├── jre\ │ ├── bin\ │ └── lib\ └── lib\注意jre是 JDK 自带的不要删。有些老应用启动脚本会直接引用%JAVA_HOME%\jre\bin\java.exe删了就跑不起来。2.2 环境变量怎么配才不干扰其他 JDK现代开发机通常已经装了 JDK 8、11 或 17JAVA_HOME指向的是新版本。你不可能为了一个老项目把全局变量改掉否则其他工具链全乱。我的做法是全局JAVA_HOME保持不动给老项目单独写一个setenv.bat在启动脚本里临时覆盖。echo off REM 老项目专用环境不影响全局 JDK set JAVA_HOMEC:\Java\jdk1.6.0_06 set PATH%JAVA_HOME%\bin;%PATH% set CLASSPATH.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar REM 验证版本 java -version逻辑说明set只在当前命令行窗口生效关掉就恢复。PATH把老 JDK 的bin放在最前面确保java和javac优先命中 1.6。CLASSPATH里的dt.jar和tools.jar是 JDK 1.6 时代编译和工具链需要的现代 JDK 已经移除了这两个包但老项目编译时可能还在引用。参数说明JAVA_HOME必须指向 JDK 根目录不是bin也不是jre。PATH的顺序很关键如果新 JDK 的路径在前面java -version会显示新版本。CLASSPATH里的.表示当前目录老项目有时候会把配置文件放在工作目录下直接读。提示如果你用 PowerShellset命令不适用要用$env:JAVA_HOMEC:\Java\jdk1.6.0_06但CLASSPATH的分隔符在 PowerShell 里仍然是分号不要改成冒号。2.3 验证安装是否真的可用装完别急着跑项目先做三个最小验证。第一个java -version输出应该是java version 1.6.0_06。第二个javac -version输出javac 1.6.0_06。第三个写一个最简单的Hello.java编译运行public class Hello { public static void main(String[] args) { System.out.println(JDK 1.6.0_06 is working); System.out.println(System.getProperty(java.version)); } }编译命令javac Hello.java运行命令java Hello。如果输出里版本号是1.6.0_06说明环境没问题。如果报UnsupportedClassVersionError说明你用的javac和java不是同一个版本回去检查PATH顺序。3. 让老 JDK 跑现代代码编译参数、依赖与工具链的妥协方案3.1 源码级别和目标字节码怎么设JDK 1.6 的javac支持-source和-target参数但取值范围有限。-source 1.6是默认值-target 1.6也是默认值。如果你拿 JDK 1.6 去编译一个写了Override在接口实现上的代码会报错因为 Java 6 不允许在接口实现方法上加Override。这是最常见的翻车点之一。javac -source 1.6 -target 1.6 -encoding UTF-8 -d ./classes ./src/com/example/*.java逻辑说明-source 1.6告诉编译器按 Java 6 语法检查-target 1.6生成 50.0 版本的字节码Java 6 的 class 文件版本号是 50。-encoding UTF-8防止中文注释乱码老项目里 GBK 和 UTF-8 混用很常见统一成 UTF-8 能省很多事。-d ./classes指定输出目录不要跟源码混在一起。参数说明-source和-target必须成对出现只写一个会警告。-encoding如果不指定Windows 默认用 GBK源码里有 UTF-8 字符就会编译失败。-d目录必须提前存在javac不会自动创建。3.2 依赖库的版本锁定与冲突排查老项目依赖的第三方库比如日志组件、JSON 解析、数据库驱动版本都很旧。你拿 Maven 中央仓库最新的 jar 包塞进去大概率NoSuchMethodError。我的做法是先把项目WEB-INF/lib或lib目录下所有 jar 列出来用jar tf看每个包的类结构确认没有重复类。REM 列出所有 jar 包并检查重复类 for %%f in (lib\*.jar) do ( echo %%f jar tf %%f | findstr /C:.class | sort %%f.txt )逻辑说明这个脚本会把每个 jar 包里的 class 文件列表导出成同名 txt然后你可以用fc命令两两对比看有没有同一个全限定类名出现在两个 jar 里。老项目最常见的冲突是commons-logging和log4j同时存在或者不同版本的xerces打架。参数说明jar tf列出 jar 内容findstr过滤 class 文件sort排序方便对比。如果发现重复类优先保留版本号低的那个因为老代码通常是按低版本 API 写的。3.3 用现代 IDE 挂老 JDK 的配置要点IntelliJ IDEA 和 Eclipse 都支持多 JDK 配置。IDEA 里在File - Project Structure - SDKs添加C:\Java\jdk1.6.0_06然后在Project里把Project SDK和Project language level都设成 6。Eclipse 里在Window - Preferences - Java - Installed JREs添加然后在项目属性里把Java Compiler的Compiler compliance level设成 1.6。注意IDEA 高版本对 JDK 1.6 的支持在逐渐减弱某些新版本 IDEA 已经无法识别 1.6 的tools.jar。如果遇到 IDE 报错但命令行能编译就用命令行编译IDE 只用来写代码和调试。调试时远程附加-agentlib:jdwptransportdt_socket,servery,suspendn,address8000这个参数在 JDK 1.6 里是支持的。4. 避坑jdk1.6.0_06 在 Windows 上的五个血泪教训4.1 现象java -version显示正确但运行报NoClassDefFoundError原因CLASSPATH里包含了当前目录.但实际运行的 class 文件不在当前目录或者CLASSPATH被其他脚本覆盖了。老项目的启动脚本经常在中间重新set CLASSPATH把你之前设的冲掉了。解决在启动脚本最后加一行echo %CLASSPATH%确认最终生效的值。如果被覆盖把set CLASSPATH放到脚本最前面或者直接用java -cp参数指定不依赖环境变量。4.2 现象编译时报编码 GBK 的不可映射字符原因源码文件是 UTF-8 编码但javac默认用平台编码Windows 中文版是 GBK去读。老项目里有些文件是 GBK有些是 UTF-8混在一起必炸。解决统一用-encoding UTF-8编译。如果有个别文件确实是 GBK先用iconv或记事本转成 UTF-8。不要试图用-encoding GBK去兼容因为 UTF-8 文件会反过来报错。4.3 现象keytool或jarsigner命令找不到原因JDK 1.6 的keytool在%JAVA_HOME%\bin下但如果你只把%JAVA_HOME%\jre\bin加进了PATH就会找不到。jre\bin里只有java、javaw等运行时命令没有开发工具。解决PATH里必须包含%JAVA_HOME%\bin不是%JAVA_HOME%\jre\bin。检查方法where keytool如果输出路径在jre\bin下说明配错了。4.4 现象应用启动后中文日志乱码原因JDK 1.6 的file.encoding默认跟随系统区域设置中文 Windows 是 GBK。但日志框架可能按 UTF-8 写文件两边不一致就乱码。解决启动参数加-Dfile.encodingUTF-8同时确认日志配置文件里的编码也是 UTF-8。如果老代码里硬编码了new String(bytes, GBK)那就只能改代码没有别的办法。4.5 现象OutOfMemoryError: PermGen space原因JDK 1.6 的永久代PermGen默认上限很小通常是 64MB 或 82MB。老项目如果用了大量反射、动态代理、JSP 编译很容易撑爆。解决启动参数加-XX:PermSize128m -XX:MaxPermSize256m。注意这两个参数在 JDK 8 以后被 Metaspace 取代但在 1.6 里必须显式设置。设置多少取决于项目规模我一般从 128m 起步观察几天再调。5. 进阶用 jdk1.6.0_06 做远程调试与字节码验证5.1 远程调试参数与连接步骤老项目跑在生产环境的 Windows Server 上你不可能直接在上面装 IDE。远程调试是最实用的手段。在启动脚本里加set JAVA_OPTS%JAVA_OPTS% -agentlib:jdwptransportdt_socket,servery,suspendn,address8000逻辑说明transportdt_socket表示用 socket 通信servery表示应用作为调试服务端suspendn表示启动时不暂停等待调试器连接address8000是监听端口。如果suspendy应用会卡在启动阶段直到你连上生产环境千万别这么干。参数说明端口不要用 8000 以下避免跟系统服务冲突。如果服务器有防火墙需要放行该端口。JDK 1.6 不支持address*:8000这种写法只能写address8000默认绑定所有网卡。然后在本地 IDEA 里新建Remote JVM Debug配置主机填服务器 IP端口填 8000JDK 选 1.6。连接成功后你可以在本地源码里打断点观察变量值。注意本地源码必须和服务器上的 class 文件版本一致否则断点行号对不上。5.2 用 javap 验证字节码版本有时候你怀疑编译出来的 class 文件不是 1.6 的可以用javap -verbose看版本号javap -verbose Hello.class | findstr major输出major version: 50表示是 Java 6 的字节码。如果是 51 就是 Java 752 是 Java 8。这个检查在排查UnsupportedClassVersionError时特别有用能快速定位是哪个 jar 包或哪个 class 文件版本不对。5.3 一个我常犯的错误我刚开始维护老项目时总觉得 JDK 版本差不多就行拿 JDK 8 去跑 1.6 编译的代码大部分时候没问题但遇到sun.misc.Unsafe或者内部 API 调用时就会炸。后来我养成了一个习惯只要项目pom.xml或build.gradle里写的source和target是 1.6本地环境就一定切到 1.6不偷懒。这个习惯帮我省掉了至少三次通宵排查NoSuchMethodError的时间。希望帮到你。本文还有配套的精品资源点击获取