ClassLoader.getSystemResourceAsStream("a.txt")获取不到资源文件
一、解决方案
换成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
ClassLoader.getSystemResourceAsStream("a.txt")获取不到资源文件的更多相关文章
- Assembly.GetManifestResourceNames()获取不到资源文件
Assembly.GetManifestResourceNames()获取到的是嵌入的资源文件 右键资源文件属性 将生成操作改为嵌入的资源就OK咯
- Linux 获取设备树源文件(DTS)里描述的资源
Linux 获取设备树源文件(DTS)里的资源 韩大卫@吉林师范大学 在linux使用platform_driver_register() 注册 platform_driver 时, 需要在 plat ...
- ClassLoader.getSystemResourceAsStream()
一: 要加载的文件和.class文件在同一目录下,例如:com.x.y 下有类Test.class ,同时有资源文件config.properties 那么,应该有如下代码: //前面没有" ...
- Xamarin.iOS模拟器调试找不到资源文件
Xamarin.iOS模拟器调试找不到资源文件 在Visual Studio 2015中,运行Xamarin.iOS项目,出现找不到资源文件的错误.错误信息:System.IO.FileNotFoun ...
- Android 4.1源码编译找不到资源文件解决办法
我们在Android framework中修改资源文件时,在Android 4.0之前,都是直接在sourcecode/frameworks/base/core/res/res下面添加对应的资源文件, ...
- className.class.getResourceAsStream与ClassLoader.getSystemResourceAsStream区别
className.class.getResourceAsStream : 一: 要加载的文件和.class文件在同一目录下,例如:com.x.y 下有类Test.class ,同时有资源文件conf ...
- java 路径、className.class.getResourceAsStream()、ClassLoader.getSystemResourceAsStream() 、FileInputStream
className.class.getResourceAsStream 用法: 第一: 要加载的文件和.class文件在同一目录下,例如:com.x.y 下有类Test.class ,同时有资源文件c ...
- Linux 获取设备树源文件(DTS)里的资源【转】
本文转载自:http://blog.csdn.net/keleming1/article/details/51036000 http://www.cnblogs.com/dyllove98/archi ...
- web页面找不到资源文件,报404,但是资源文件存在且路径没错
如题 , 今天遇到这个问题,maven项目导入本地myeclipse,正常跑起来之后,在web端存在部分页面资源加载不进来. 但是项目资源确实存在,一开始以为是myeclipse开发环境搭建错误导致, ...
随机推荐
- SVO 特征对齐代码分析
SVO稀疏图像对齐之后使用特征对齐,即通过地图向当前帧投影,并使用逆向组合光流以稀疏图像对齐的结果为初始值,得到更精确的特征位置. 主要涉及文件: reprojector.cpp matcher.cp ...
- Paper | LISTEN, ATTEND AND SPELL: A NEURAL NETWORK FOR LARGE VOCABULARY CONVERSATIONAL SPEECH RECOGNITION
目录 1. 相关工作 2. 方法细节 2.1 收听器 2.2 注意力和拼写 本文提出了一个基于神经网络的语音识别系统List, Attend and Spell(LAS),能够将语音直接转录为文字. ...
- java(一)基础知识
常见DOS命令: dir:列出当前目录下的文件以及文件夹 md:创建目录 rd: 删除目录 cd:进入指定目录 cd .. :返回上一级目录 cd \:返回根目录 del:删除文件 exit:退出do ...
- Mac 应用程序不能打开解决方法
Mac 应用程序不能打开解决方法 关键是 文件原本是可执行文件,由于权限丢失,才变成了类型不明的文件,导致软件无法打开. 参考: https://www.macbl.com/article/tips/ ...
- 转caffe scale layer
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/u011681952/article/det ...
- oracle学习笔记(十八) PL/SQL 游标
游标 说明 查询结果的光标,相当于java中的一个迭代器,方便遍历操作 可使用的属性 %FOUND SQL语句查询或影响了一行或多行时为 TRUE.如:mycursor%FOUND %NOTFOUND ...
- SpringBoot(一):构建第一个SpringBoot工程
1.项目格式如下: 1.启动类: package com.monkey01.springbootstart; import org.springframework.boot.SpringApplica ...
- 区块链社交APP协议分析:BeeChat
- BeeChat是什么 - BeeChat报文情况 BeeChat使用过程中产生的报文如下: 可以看到,其使用443端口,但内容并非SSL承载,格式不符合SSL,内容中含MsgNtf等明文串,但大部 ...
- linux cpu信息
/* who参数 RUSAGE_SELF:只返回当前程序的CPU时间占用信息 RUSAGE_CHILDREN:还包括子进程的CPU时间占用信息 */ int getrusage(int who, st ...
- Qt开源编辑器qsciscintilla的一些用法
首先放一张自己做的软件中的编辑器的效果图 中间红色的框就是放在Qt的tabwidget控件中的qsciscintilla编辑器 先从官网下载qsciscintilla源码,在qtcreater中编译, ...