平常在项目中会分模块进行开发,读写文件时使用的都是绝对路径,测试程序也是使用idea直接执行程序。在学习jetty源码时,由于需要在start模块中启动项目,但需要动态加载依赖的其他模块,此时代码中使用的是相对路径,在使用idea启动程序的时候,可以正常执行,但在命令行中使用java命令启动程序时,总是会报java.lang.ClassNotFoundException,分析原因见下:
1. 打开idea的run配置:
虽然是在start模块中启动程序,但idea会自动将运行时的程序根路径设置为working directory中设置的目录,此时项目中使用的相对路径就是依据working directory路径的相对路径(此处是猜测,具体验证可以通过修改working directory内容来验证)
2. 使用java命令执行时,由于没有设置程序运行时的根路径,此时就会将当前main方法所在的类所处的目录设置为跟路径,代码中再使用相对路径时,就是根据main方法所在的类所在的目录生成的路径
根据以上猜测和分析,解决此问题的根本就是找到如何设置程序运行时的根目录
----- 分隔线 ----
分析java源码:
File类:
//获取文件绝对路径方法
public String getAbsolutePath() { return fs.resolve(this);//FileSystem.resolve()方法 }
根据操作系统不同,使用的FileSystem实现类不一样,我的是mac系统,使用的是UnixFileSystem类:
1 public String resolve(File f) { 2 if (isAbsolute(f)) return f.getPath(); 3 return resolve(System.getProperty("user.dir"), f.getPath()); 4 }
可以发现java源码中使用的是System.getProperty("user.dir")来设置程序运行的跟目录的,那么就可以通过此设置解决这个问题:
1 System.setProperty("user.dir", "/workspace/code/git/jetty.project");
总结:通过修改系统属性user.dir,使用java命令也可以通过jetty源码正常启动了,此时可以猜测idea是否也是通过将working directory设置到user.dir属性来实现的呢。
---- 少百度,多看源码