idea获取java类的相对路径,然后打包后运行出错的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了idea获取java类的相对路径,然后打包后运行出错的问题相关的知识,希望对你有一定的参考价值。

src目录下的dao包里有类文件和txt文件,本来访问txt用的是src/com../dao,调试正常,打包之后访问不到,后来改成this.getClass().getClassLoader().getResource("").getPath()方法,发现获取的路径前面多了个斜杠,但是调试正常,打jar包运行之后报空指针错,哪位大神解答一下,搞了一个下午了,不胜感激

参考技术A 在project所在的标题栏右键鼠标,在弹出的菜单中将showmembers打钩即可。此时就会看到java类的相关成员信息追问

你确定吗

怎么觉得和提问无关

java 获取当前类的路径

最近在做项目的时候,自己写了一些配置参数的读取,将配置文件放到具体的位置,然后让程序根据当前类的路径寻找配置文件的路径,但是,发现eclipse的开发坏境下是可以顺利读取到指定路径下的配置文件中的配置参数的,

但是当将项目放到Tomcat下  或者 将项目打包成可执行jar包之后,编译后的class文件却读取不到了开发环境下寻找的配置文件了。

如果在 .java 文件中直接写// public static  String Config = "config.properties";  则该路径指向的就是项目的 src 的同级目录(直接将配置文件放到项目的根目录下)

经过查找资料和进行验证,现将读取class文件相对路径下配置文件的方法汇总如下:

方法一:使用System获取路径

方法二:使用当前类的ProtectionDomain或者ClassLoader获取路径

方法三:使用Thread获取路径

方法一:

示例:

 public static  final String URLConfig = System.getProperty("user.dir").replace("bin", "webapps")+"/URLConfig.properties";//这种是将配置文件放到Tomcat的webapps的目录下

其中的 System.getProperty("user.dir")  为获取用户当前工作目录

java的System.getProperty()方法可以获取的值

获取的代码示例:

public   class  SystemProperty {  
    public   static   void  main(String args[]) {     
    System.out.println("java_vendor:"  + System.getProperty( "java.vendor" ));     
    System.out.println("java_vendor_url:"      
             + System.getProperty("java.vendor.url" ));     
    System.out.println("java_home:"  + System.getProperty( "java.home" ));     
    System.out.println("java_class_version:"      
             + System.getProperty("java.class.version" ));     
    System.out.println("java_class_path:"      
            + System.getProperty("java.class.path" ));     
    System.out.println("os_name:"  + System.getProperty( "os.name" ));     
    System.out.println("os_arch:"  + System.getProperty( "os.arch" ));     
    System.out.println("os_version:"  + System.getProperty( "os.version" ));     
    System.out.println("user_name:"  + System.getProperty( "user.name" ));     
    System.out.println("user_home:"  + System.getProperty( "user.home" ));     
    System.out.println("user_dir:"  + System.getProperty( "user.dir" ));     
    System.out.println("java_vm_specification_version:"      
            + System.getProperty("java.vm.specification.version" ));     
    System.out.println("java_vm_specification_vendor:"      
            + System.getProperty("java.vm.specification.vendor" ));     
    System.out.println("java_vm_specification_name:"      
            + System.getProperty("java.vm.specification.name" ));     
    System.out.println("java_vm_version:"      
            + System.getProperty("java.vm.version" ));     
    System.out.println("java_vm_vendor:"      
            + System.getProperty("java.vm.vendor" ));     
    System.out     
            .println("java_vm_name:"  + System.getProperty( "java.vm.name" ));     
    System.out.println("java_ext_dirs:"      
            + System.getProperty("java.ext.dirs" ));     
    System.out.println("file_separator:"      
            + System.getProperty("file.separator" ));     
    System.out.println("path_separator:"      
            + System.getProperty("path.separator" ));     
    System.out.println("line_separator:"      
            + System.getProperty("line.separator" ));     
}     

 

上面示例引用的博客地址:https://blog.csdn.net/capmiachael/article/details/51895823

 

方法二:

示例1:

public static String getMyDIR(){//获取当前类文件的绝对路径
String jarWholePath = ConfigerPraram.class.getProtectionDomain().getCodeSource().getLocation().getFile(); 
try { 
//保险起见,将路径进行decode转码
jarWholePath = java.net.URLDecoder.decode(jarWholePath, "UTF-8"); 
} catch (UnsupportedEncodingException e) { System.out.println(e.toString()); } 
//获取jar包的上级目录
String jarPath = new File(jarWholePath).getParentFile().getAbsolutePath(); 
return jarPath;
}

示例2:

/**
     * 获取项目所在路径
     * 
     * @return
     */
    public static String getRealPath() {
     //通过类加载器获取jar包的绝对路径 String realPath
= MyPath.class.getClassLoader().getResource("") .getFile(); java.io.File file = new java.io.File(realPath); realPath = file.getParentFile().getAbsolutePath(); //获取jar包的上级目录
try {
       //路径decode转码 realPath
= java.net.URLDecoder.decode(realPath, "utf-8"); } catch (Exception e) { e.printStackTrace(); }  
    return realPath ; 
  }

 

 

方法三:(该方法还未做验证,引用博客:https://blog.csdn.net/z69183787/article/details/22774537)

Thread.currentThread().getContextClassLoader().getResource("")来得到当前的classpath的绝对路径的URI表示法

Application可以通过new FileInputStream("xx.properties");直接在classes一级获取。关键是有时我们需要通过web修改配置文件,我们不 能将路径写死了。经过测试觉得有以下心得:

1.servlet中读写。如果运用Struts 或者Servlet可以直接在初始化参数中配置,调用时根据servlet的getRealPath("/")获取真实路径,再根据String file = this.servlet.getInitParameter("abc");获取相对的WEB-INF的相对路径。
例:
InputStream input =Thread.currentThread().getContextClassLoader().getResourceAsStream("abc.properties"); 
Properties prop = new Properties();
prop.load(input);
input.close();

prop.setProperty("abc", “test");
prop.store(new FileOutputStream(path), “–test–"); 
out.close(); 

2.直接在jsp中操作,通过jsp内置对象获取可操作的绝对地址。
例:
// jsp页面
String path = pageContext.getServletContext().getRealPath("/");
String realPath = path+"/WEB-INF/classes/abc.properties";

//java 程序
InputStream in = getClass().getClassLoader().getResourceAsStream("abc.properties"); // abc.properties放在webroot/WEB-INF/classes/目录下
prop.load(in);
in.close();

OutputStream out = new FileOutputStream(path); // path为通过页面传入的路径
prop.setProperty("abc", “abcccccc");
prop.store(out, “–test–");
out.close();

3.只通过Java程序操作资源文件
InputStream in = new FileInputStream("abc.properties"); // 相对路径,项目下的路径

OutputStream out = new FileOutputStream("abc.properties");

 

下面的参考解释引用于博客:https://www.cnblogs.com/gaoxing/p/4703412.html

 

打个简单的比方,你一个WEB程序,发布到Tomcat里面运行。
首先是执行Tomcat org.apache.catalina.startup.Bootstrap类,这时候的类加载器是ClassLoader.getSystemClassLoader()。
而我们后面的WEB程序,里面的jar、resources都是由Tomcat内部来加载的,所以你在代码中动态加载jar、资源文件的时候,首先应该是使用Thread.currentThread().getContextClassLoader()。如果你使用Test.class.getClassLoader(),可能会导致和当前线程所运行的类加载器不一致(因为Java天生的多线程)。
Test.class.getClassLoader()一般用在getResource,因为你想要获取某个资源文件的时候,这个资源文件的位置是相对固定的。

java的类加载机制(jvm规范)是委托模型,简单的说,如果一个类加载器想要加载一个类,首先它会委托给它的parent去加载,如果它的所有parent都没有成功的加载那么它才会自己亲自来,有点儿像儿子使唤老子的感觉。

 

如果你使用Test.class.getClassLoader(),可能会导致和当前线程所运行的类加载器不一致 :Class.getClassLoader() returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader.

以上是关于idea获取java类的相对路径,然后打包后运行出错的问题的主要内容,如果未能解决你的问题,请参考以下文章

java 获取当前类的路径

项目打包(jar)和依赖(lib)分离

IDEA SpringBoot 项目打包成jar包

idea中写的代码不打包怎么能直接运行

如何解决IDEA 中Java项目运行时找不到或无法加载到主类的问题

idea运行按钮是灰色无法点击