读好书,交益友
分类: Java
2014-03-12 15:55:09
最近发布基于spring的应用程序,发布的时候遇到了一个问题。
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See for more info.
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'myService' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:277)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1098)
这个问题以前没有遇到过,开始认为是代码或者配置的问题,后来发现是因为
annotation不会扫描jar,而是扫描directory entries(DE)。所以使用
……Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: ……nested exception isorg.springframework.beans.factory.NoSuchBeanDefinitionException:……expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: )}……
查看spring的加载日志时,也看不到@Service、@Component等修饰的bean。
如果使用eplise打包,勾选上 Add directory entries(adds an entry for each directory to the JAR file, even if the directory does only contain subdirectories.)
以前经常使用spring,为什么没遇到问题呢。
以前做jar基本都是jar命令,也使用ant,基本不用eclipse,甚至idea的artifacts都不用(因为这个功能变来变去,不稳定)。
ant打包,filesonly=false,不过该属性默认为false。
其中的根源在于class的getResources方法
使用eclipse新建一个工程,添加文件
package test;
public class Main {
public static void println(Class clazz) {
System.out.println("=====" + clazz.getName() + "=====");
try {
System.out.println("1 " + clazz.getResource(""));
} catch (Exception e) {
System.out.println("1 error " + e.getMessage());
}
try {
System.out.println("2 " + clazz.getResource("/"));
} catch (Exception e) {
System.out.println("2 error " + e.getMessage());
}
try {
System.out.println("3 " + clazz.getClassLoader().getResource(""));
} catch (Exception e) {
System.out.println("3 error " + e.getMessage());
}
System.out.println("4 " + clazz.getResource("test.txt"));
}
public static void main(String[] args) {
println(Main.class);
}
并在test目录下添加一个空的test.txt文件,然后到处test.jar.
运行 D:\idea\package>java -jar test.jar
结果如下
=====test.Main=====
1 null
2 null
3 null
4 jar:file:/D:/idea/package/test.jar!/test/test.txt
查看test.jar的文件信息
D:\idea\package>D:\Java\jdk1.6.0_34\bin\jar tvf test.jar
48 Wed Mar 12 13:21:48 CST 2014 META-INF/MANIFEST.MF
2057 Wed Mar 12 13:20:12 CST 2014 test/Main.class
0 Wed Mar 12 13:18:52 CST 2014 test/test.txt
自己手工做jar,D:\Java\jdk1.6.0_34\bin\jar cvf test.jar .
运行 D:\idea\package\bin>java -cp test.jar test.Main
结果如下
=====test.Main=====
1 jar:file:/D:/idea/package/bin/test.jar!/test/
2 null
3 null
4 jar:file:/D:/idea/package/bin/test.jar!/test/test.txt
查看test.jar的文件信息
D:\idea\package\bin>D:\Java\jdk1.6.0_34\bin\jar tvf test.jar
0 Wed Mar 12 14:21:28 CST 2014 META-INF/
71 Wed Mar 12 14:21:28 CST 2014 META-INF/MANIFEST.MF
0 Wed Mar 12 14:21:04 CST 2014 test/
1573 Wed Mar 12 14:21:04 CST 2014 test/Main.class
0 Wed Mar 12 13:18:52 CST 2014 test/test.txt
如果不在jar中运行
D:\idea\package\bin>java -cp . test.Main
=====test.Main=====
1 file:/D:/idea/package/bin/test/
2 file:/D:/idea/package/bin/
3 file:/D:/idea/package/bin/
4 file:/D:/idea/package/bin/test/test.txt
其中jar中getResource("/")得不到当前的classpath的绝对URI路径,getClassLoader().getResource(""),得不到ClassPath的绝对URI路径,.ClassLoader.getSystemResource("")
得不到的也是当前ClassPath的绝对URI路径。