文档章节

ClassLoader.getSystemResourceAsStream("a.txt")获取不到资源文件

o
 osc_wws45aot
发布于 2019/08/22 12:08
字数 936
阅读 29
收藏 0

精选30+云产品,助力企业轻松上云!>>>

一、解决方案

换成XXX.class.getClassLoader().getResourceAsStream("a.txt")即可。

二、场景复现

src/main/resource下存在文件a.txt,项目类中static 方法中读取该文件。ClassLoader.getSystemResourceAsStream("a.txt")获取不到资源文件

三、原因剖析

getResourceAsStream会先使用本类的类加载器去加载,本类没有类加载器,才会使用系统类加载器。也就是说getResourceAsStream功能覆盖了getSystemResourceAsStream,所以推荐直接使用getResourceAsStream就完事了都不需要知道具体两者有啥区别。

下面我们来细看有啥区别....

3.1 java类加载器

  • 1.启动类加载器Bootstrap ClassLoader):顶层的类加载器,没有父类加载器。负责加载 /lib 目录下的,或被 -Xbootclasspath 参数所指定路径中的,并被 JVM 识别的(仅按文件名识别,如 rt.jar,名字不符合的类库即使放在 lib 目录也不会被加载)类库加载到虚拟机内存中。所有被 Bootstrap classloader 加载的类,它的 Class.getClassLoader 方法返回的都是 null,所以也称作 NULL ClassLoader。
  • 2.扩展类加载器Extension CLassLoader):由 sun.misc.Launcher$ExtClassLoader 实现,负责加载 <JAVA_HOME>/lib/ext 目录下,或被 java.ext.dirs 系统变量所指定的目录下的所有类库;
  • 3.应用程序类加载器Application/System ClassLoader):由 sun.misc.Launcher$AppClassLoader 实现。它是 ClassLoader.getSystemClassLoader() 方法的默认返回值,所以也称为系统类加载器(System ClassLoader)。它负责加载 classpath 下所指定的类库,如果应用程序没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

3.2 tomcat容器下类加载器

Tomcat官方说明:Class Loader HOW-TO

跟普通的java程序相比,类加载大体顺序相同。

  • 1.Bootstrap 启动类加载器: 加载JVM启动所需的类+系统扩展目录($JAVA_HOME/jre/lib/ext)里 JAR 文件中的类。
  • 2.System 系统类加载器:从 CLASSPATH 系统变量指定的目录中加载类库。该加载器加载的类对 tomcat 本身和 web 应用都可见。但是,标准的 tomcat 启动脚本($CATALINA_HOME/bin/catalina.sh or %CATALINA_HOME%\bin\catalina.bat)都会忽略系统变量 CLASSPATH 的值,而会使用如下的类库来创建 System 类加载器:

          $CATALINA_HOME/bin/bootstrap.jar

        $CATALINA_BASE/bin/tomcat-juli.jar 或 $CATALINA_HOME/bin/tomcat-juli.jar

        $CATALINA_HOME/bin/commons-daemon.jar

  • 3.Common 通用类加载器:通过该类加载器加载的类库可被 Tomcat 和所有应用共享。该类加载器的搜索位置是通过 $CATALINA_BASE/conf/catalina.properties 文件中的 common.loader 属性指定的,默认包括如下位置:

        $CATALINA_BASE/lib 下未打包的类和资源;

        $CATALINA_BASE/lib 下的 jar 包;

        $CATALINA_HOME/lib 下未打包的类和资源;

        $CATALINA_HOME/lib 下的 jar 包。

  • 4.WebappX 应用类加载器:每个 Web 应用创建一个自己的类加载器,加载自己项目下的数据: /WEB-INF/classes 和 /WEB-INF/lib 下的类和资源。并且不使用双亲委派机制,先自己加载,加载不到才使用父类加载器。

本来顺序是1234,但是WebappX不使用委派机制而是先自己加载,加载不了才使用父类,所以真实的顺序是:

  • Bootstrap classes of your JVM
  • /WEB-INF/classes of your web application
  • /WEB-INF/lib/*.jar of your web application
  • System class loader classes (described above)
  • Common class loader classes (described above)

tomcat8支持委托:配置允许委派:<Loader delegate="true"/>,顺序变为:

  • Bootstrap classes of your JVM
  • System class loader classes (described above)
  • Common class loader classes (described above)
  • /WEB-INF/classes of your web application
  • /WEB-INF/lib/*.jar of your web application

3.3 问题回归

tomcat容器中运行的java程序,使用系统类加载器是不能获取到资源的,必须使用WebappClassLoader。使用getResourceAsStream获取当前类的类加载器,也就是WebappClassLoader,自然可以获取到资源了。


=======参考=========

https://blog.csdn.net/w1196726224/article/details/54428493

 

上一篇: 下拉框多选
下一篇: Matlab 排列组合
o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
Java读取文件

1 public static String getFileStr(String filePath) { 2 InputStream is = null; 3 BufferedInputStream bis = null; 4 ByteArrayOutputStream bos = null; 5 byte[] buffer = new byte[10......

osc_eeik3xla
2018/08/08
0
0
java读取项目下的文件

-------------java读取项目下的文件 参考博客:http://blog.csdn.net/christophe2008/article/details/7078238 我们会经常遇到这样的问题,工程里有一个文件,Java程序要读取这个文件,不采用...

yong230
2014/08/19
2
0
JAVA读取外部资源的方法

在java代码中经常有读取外部资源的要求:如配置文件等等,通常会把配置文件放在classpath下或者在web项目中放在web-inf下. 1.从当前的工作目录中读取: try { BufferedReader in = new Buffere...

丶宾利
2014/08/16
28
0
JAVA读取外部资源的方法

在java代码中经常有读取外部资源的要求:如配置文件等等,通常会把配置文件放在classpath下或者在web项目中放在web-inf下. 1.从当前的工作目录中读取: try { BufferedReader in = new Buffere...

晨曦之光
2012/04/25
1.4K
1
Properties-java获取资源文件值

String fileName = "alittleconfig.txt"; /** * Jfinale获取资源文件 / Prop prop=PropKit.use(fileName); String user =prop.get("user"); System.out.println(user); /* * java内置获取pro......

尾生
2016/08/10
2
0

没有更多内容

加载失败,请刷新页面

加载更多

聊聊rocketmq-client-go的TraceInterceptor

序 本文主要研究一下rocketmq-client-go的TraceInterceptor TraceInterceptor rocketmq-client-go-v2.0.0/producer/interceptor.go // WithTrace support rocketmq trace: https://github.c......

go4it
15分钟前
0
0
如何在Android文本视图周围添加边框? - How do I put a border around an Android textview?

问题: 是否可以在textview周围绘制边框? 解决方案: 参考一: https://stackoom.com/question/EfXR/如何在Android文本视图周围添加边框 参考二: https://oldbug.net/q/EfXR/How-do-I-put...

法国红酒甜
30分钟前
10
0
设计模式(4) 建造者模式

什么是建造者模式 经典建造者模式的优缺点 对建造者模式的扩展 什么是建造者模式 建造者模式将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。创建者模式隐藏了...

zhixin9001
42分钟前
14
0
ArrayList源码分析 —— JDK8

ArrayList的特性 ArrayList内部使用数据作为存储结构,ArrayList可以理解为数组的扩展对象,封装了常用的和非常用的操作数组的方法。以及当数组长度不足以保存数组时,自动扩容数组,通常Arr...

XuePeng77
49分钟前
42
0
__slots__的用法? - Usage of __slots__?

问题: Python中__slots__的目的是什么-尤其是关于何时以及何时不使用它的目的? 解决方案: 参考一: https://stackoom.com/question/1ymu/slots-的用法 参考二: https://oldbug.net/q/1ym...

富含淀粉
今天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部