一.问题描述
在用spring-dm对某bundle进行测试时,报了如下错误。于是便对spring-osgi-test.jar中的几个测试类做了下研究。
java.io.FileNotFoundException: C:\Users\boy\.m2\repository\org\aopalliance\com.springsource.org.aopalliance\1.0.0\com.springsource.org.aopalliance-1.0.0.jar (系统找不到指定的路径。)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:106)
at org.springframework.core.io.FileSystemResource.getInputStream(FileSystemResource.java:110)
at org.springframework.osgi.test.AbstractOsgiTests.installBundle(AbstractOsgiTests.java:323)
at org.springframework.osgi.test.AbstractOsgiTests.startup(AbstractOsgiTests.java:253)
at org.springframework.osgi.test.AbstractOsgiTests.prepareTestExecution(AbstractOsgiTests.java:374)
at org.springframework.osgi.test.AbstractOsgiTests.runBare(AbstractOsgiTests.java:203)
at org.springframework.osgi.test.AbstractOsgiTests$1.protect(AbstractOsgiTests.java:184)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at org.springframework.osgi.test.AbstractOsgiTests.run(AbstractOsgiTests.java:181)
二.spring dm对bundle的集成测试
在使用spring dm框架时,其中的spring-osgi-test.jar这个bundle对集成测试提供了很好的支持。其中最重要的几个类如下
(1)AbstractOsgiTests.java
(2)AbstractConfigurableOsgiTests.java
(3)AbstractDependencyManagerTests
(4)AbstractConfigurableBundleCreatorTests
1.AbstractOsgiTests类
下面说下该类中比较重要的一个方法,在这个方法中定义了bundle的加载过程。
private Resource[] locateBundles() {
//获取测试框架所需的bundle
Resource[] testFrameworkBundles = getTestFrameworkBundles();
//获取要测试的bundle.
Resource[] testBundles = getTestBundles();
if (testFrameworkBundles == null)
testFrameworkBundles = new Resource[0];
if (testBundles == null)
testBundles = new Resource[0];
Resource[] allBundles = new Resource[testFrameworkBundles.length + testBundles.length];
System.arraycopy(testFrameworkBundles, 0, allBundles, 0, testFrameworkBundles.length);
System.arraycopy(testBundles, 0, allBundles, testFrameworkBundles.length, testBundles.length);
return allBundles;
}
其中的getTestFrameworkBundles()方法和getTestBundles()方法都由子类进行实现。对于getTestFrameworkBundles()方法,需要获取到测试框架所需的bundle。而对于getTestBundles()方法需要获取到要被测试的bundle.
2.AbstractDependencyManagerTests类
AbstractDependencyManagerTests是AbstractOsgiTests的子类,在其中提供了对getTestFrameworkBundles()方法的实现。
protected Resource[] getTestFrameworkBundles() {
return locateBundles(getTestFrameworkBundlesNames());
}
在这个getTestFrameworkBundlesNames()方法中,会获取测试框架所需的bundle名称.默认情况下,会加载spring-osgi-test.jar中的boot-bundles.properties文件中指定的bundle.如果子类要更换测试框架所需的bundle,可重载AbstractDependencyManagerTests中的getTestingFrameworkBundlesConfiguration()方法。
protected Resource[] locateBundles(String[] bundles) {
if (bundles == null)
bundles = new String[0];
Resource[] res = new Resource[bundles.length];
for (int i = 0; i < bundles.length; i++) {
res[i] = locateBundle(bundles[i]);
}
return res;
}
protected Resource locateBundle(String bundleId) {
Assert.hasText(bundleId, "bundleId should not be empty");
// parse the String
String[] artifactId = StringUtils.commaDelimitedListToStringArray(bundleId);
Assert.isTrue(artifactId.length >= 3, "the CSV string " + bundleId + " contains too few values");
// TODO: add a smarter mechanism which can handle 1 or 2 values CSVs
for (int i = 0; i < artifactId.length; i++) {
artifactId[i] = StringUtils.trimWhitespace(artifactId[i]);
}
//获取本地的maven仓储。
ArtifactLocator aLocator = getLocator();
return (artifactId.length == 3 ? aLocator.locateArtifact(artifactId[0], artifactId[1], artifactId[2])
: aLocator.locateArtifact(artifactId[0], artifactId[1], artifactId[2], artifactId[3]));
}
在上面的方法中,测试框架会默认到本地的maven仓储中加载所需的bundle. 对于默认的maven仓储,如果用户没有修改过maven的setting.xml中的这项值<localRepository>/path/to/local/repo</localRepository> ,则默认路径是:
${user.home}\.m2\repository这个目录下,对于我的机器则是C:\Users\boy\.m2\repository下。由于我修改了setting.xml中localRepository为 <localRepository>c:\repository</localRepository>,系统在加载bundle时还是会去C:\Users\boy\.m2\repository中寻找,我本地的maven仓储已经不是这个目录了,当然就会出现开头说的错误信息。
三.问题解决
对于上面的错误,我们已经知道了原因,最简单的一种修改方法是将maven中的setting.xml中的localRepository配置改回默认配置。但对于我而言,个人比较喜欢比较简短的文件路径,不想修改回默认的配置,哪就只好想别的办法。
在AbstractDependencyManagerTests类中,
protected ArtifactLocator getLocator() {
return locator;
}
该方法是允许子类扩展的。Spring dm对ArtifactLocator提供的默认实现类是LocalFileSystemMavenRepository类。
该类不允许对maven中的repositoryHome进行设置。如果能有另一个实现ArtifactLocator接口的类且允许自已指定repositoryHome路径也可以灵活的解决上面的问题。下面是自定义的maven仓储定位器的实现:
public class ConfigLocalFileSystemMavenRepository implements ArtifactLocator {
/** discovered local m2 repository home */
private String repositoryHome;
public ConfigLocalFileSystemMavenRepository(String repositroyHome) {
this.repositoryHome = repositroyHome;
}
//其它方法省略,省略的方法参见 LocalFileSystemMavenRepository中的实现。
}
四.完整的测试代码如下:
public class SpringDmSampleTest extends AbstractConfigurableBundleCreatorTests {
@Override
protected String[] getTestBundlesNames() {
return new String[] { "com.mango.cache, cache.core, 1.0.0" };
}
@Override
protected Resource getTestingFrameworkBundlesConfiguration() {
return new InputStreamResource(SpringDmSampleTest.class
.getResourceAsStream("boot-bundles.properties"));
}
@Override
protected ArtifactLocator getLocator() {
ArtifactLocator locator = new ConfigLocalFileSystemMavenRepository(
"c:/repository");
return locator;
}
}
对于要测试的bundle,一定要注意将它install到本地maven仓储中。
分享到:
相关推荐
Spring Dynamic Modules is a flexible OSGi-based framework that makes component building a snap. With Spring DM, you can easily create highly modular applications and you can dynamically add, remove, ...
Spring 动态模型(Spring Dynamic Modules)参考指南
Spring Dynamic Modules Reference Guide中文版
博文链接:https://caichaowei.iteye.com/blog/198017
讲解OSGI在Java企业应用中的角色及Spring DM是如何充当这个角色的。
此文档是Spring Dynamic Modules的参考文档,它定义了Spring Dynamic Modules的概念和语义,OSGi 服务平台(OSGi Service Platform)的语法基于命名空间,Dynamic Module定义了 Dynamic Module扩展Bundle和OSGi ...
。对企业级应用,Spring Dynamic Modules和OSGi平台的整合提供如下特性:
Spring Dynamic Modules Reference Guide翻译已经接近完成,但最近项目较紧,故暂停,现将预览版发布,正好供大家边看边审查。 此预览版除了最后的测试和附录仅翻译了部分之外,其余均已完整翻译,供大家一般...
Spring Dynamic Modules 实战文档,国外不错的资料文档,看了就知道
spring boot 全套示例框架源码(完整包含前端后分离框架、shiro、vue、redis、OAuth2、fastdfs、jwt、mybatis、等等技术点),多年工作经验沉淀总结
Spring源代码分析(三):Spring JDBC Spring源代码解析(四):Spring MVC Spring源代码解析(五):Spring AOP获取Proxy Spring源代码解析(六):Spring声明式事务处理 Spring源代码解析(七):Spring AOP中对拦截器...
Pro Spring Dynamic Modules for OSGi Service Platforms.pdf
This book is about OSGi’s role in enterprise Java and how the Spring Dynamic Modules for OSGi (Spring-DM) fulfills this role. I first learned about OSGi when the Eclipse IDE started using it in its ...
This book is about OSGi’s role in enterprise Java and how the Spring Dynamic Modules for OSGi (Spring-DM) fulfills this role.
Spring源码分析.pdf
Java流行框架源码分析:Spring源码、SpringBoot源码、SpringAOP源码、SpringSecurity源码、SpringSecurity OAuth2源码、JDK源码、Netty源码
springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC...
spring mvc源码框架,绝对可以运行。
spring-osgi-core-1.2.1.jar spring-osgi-core-1.2.1-sources.jar spring-osgi-extender-1.2.1.jar spring-osgi-extender-1.2.1-sources.jar spring-osgi-io-1.2.1.jar spring-osgi-io-1.2.1-sources.jar spring-...