当我将webapp部署到Tomcat时,我遇到了一个奇怪的错误,我相信类加载器问题。当我使用Jetty在本地运行我的webapp时,不会出现该错误。似乎我的.yml资源文件的输入流由于某些原因而被关闭。当我尝试将单个模块项目转换为多模块项目时,首先出现此错误。在此之前,它使用完全相同的代码在Tomcat上正常工作:
Caused by: org.yaml.snakeyaml.error.YAMLException: java.io.IOException: Stream closed
at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:200)
at org.yaml.snakeyaml.reader.StreamReader.<init>(StreamReader.java:60)
at org.yaml.snakeyaml.Yaml.load(Yaml.java:412)
at com.config.ConfigProvider.<init>(ConfigProvider.java:20)
... 49 more
Caused by: java.io.IOException: Stream closed
at java.io.PushbackInputStream.ensureOpen(PushbackInputStream.java:57)
at java.io.PushbackInputStream.read(PushbackInputStream.java:149)
at org.yaml.snakeyaml.reader.UnicodeReader.init(UnicodeReader.java:90)
at org.yaml.snakeyaml.reader.UnicodeReader.read(UnicodeReader.java:122)
at java.io.Reader.read(Reader.java:123)
at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:184)
... 55 more
以下是导致错误的行:
String s = ConfigProvider.getConfig().getString("test");
这是ConfigProvider
课程。它基本上扫描正则表达式^.*\\.config\\.yml$
的所有资源文件,将其转换为Map<String, Object>
,并将获得的所有Map<String, Object>
合并为一个Map<String, Object>
:
1 public class ConfigProvider {
2 protected static final String CONFIG_PACKAGE = ConfigProvider.class.getPackage().getName();
3 protected static final Pattern CONFIG_PATH_REGEX = Pattern.compile("^.*\\.config\\.yml$");
4
5 private static final ConfigProvider INSTANCE = new ConfigProvider();
6 private Map<String, Object> configMap;
7
8 protected ConfigProvider() {
9 configMap = new HashMap<String, Object>();
10
11 Set<String> configPaths = new Reflections(CONFIG_PACKAGE,
12 new ResourcesScanner()).getResources(CONFIG_PATH_REGEX);
13
14 if (configPaths.isEmpty()) {
15 throw new RuntimeException("no config paths found");
16 }
17
18 for (String path : configPaths) {
19 InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
20 Map<String, Object> fullConfig = new Map<String, Object>((Map) new Yaml().load(inputStream));
21
22 try {
23 inputStream.close();
24 } catch (IOException e) {
25 throw new RuntimeException("error closing stream");
26 }
27
28 MapUtils.merge(configMap, fullConfig);
29 }
30 }
31
32 public static ConfigMap getConfig() {
33 return INSTANCE.configMap;
34 }
35 }
这是我的项目结构,标题为Foo:
- Foo (this is a module)
- .idea
- application (this is a module)
- src
- main
- java
- resources
- application.config.yml
- webapp
- test
- pom.xml
- client (this is a module)
- src
- main
- java
- resources
- client.config.yml
- webapp
- test
- pom.xml
- pom.xml
ConfigProvider
是我从父pom文件(Foo/pom.xml
)获得的一个类。我打包WAR
模块(application
)中的Foo/application/target/application.war
文件,并使用Tomcat进行部署。以前,我的项目是单个模块项目,只有Foo
模块与application
模块相同。然后我添加了一个client
模块并将项目转换为多模块项目,问题就出现了。我认为这是因为我的类加载器由于多个模块而变得混乱。我花了很多时间尝试调试它,但仍然没有得到任何结果。任何人都知道可能是什么原因,或者可以考虑可能尝试的事情?
如果您需要更多信息,请与我们联系。
答案 0 :(得分:5)
根据this post,该异常可能意味着找不到.yml
文件。由于您更改了项目结构,因此可能需要为新结构修改用于构建configPaths
的逻辑。您是否尝试记录configPaths
的内容以查看新结构的路径是否正确?
还要确保.yml
文件中包含.war
个文件。一些构建系统处理资源的方式与java类文件不同。
答案 1 :(得分:0)
Bean类成员变量应与.yml文件密钥匹配,第二个选项是可能会给您错误的文件路径。