一.问题描述
在用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 Reference Guide中文版》是一份详细阐述Spring Dynamic Modules (Osgi)技术的指南,旨在帮助开发者理解和使用这个框架在OSGi环境下进行开发。Spring Dynamic Modules是Spring框架的一个...
SpringDM(Spring Dynamic Modules)是Spring框架对OSGi的支持,它简化了在OSGi环境中开发和管理应用程序的过程。 这篇笔记可能讨论了以下几个关键知识点: 1. **OSGi基础**:首先,理解OSGi的基本概念是至关重要...
标题“spring-dm junit”指的是在Spring Dynamic Modules (Spring DM)框架中使用JUnit进行单元测试的相关主题。Spring DM是Spring框架的一个扩展,专门用于OSGi(开放服务网关规范)环境,它允许开发者在模块化的...
SpringDM(Spring Dynamic Modules)是Spring框架的一个扩展,专门用于OSGi(Open Service Gateway Initiative)环境中的应用程序开发。OSGi是一种Java模块化系统,它允许开发者将应用程序拆分成独立的、可热插拔的...
标题 "spring dm cxf" 涉及到的是Spring Dynamic Modules (Spring DM) 和 Apache CXF 两个关键组件在IT领域的结合使用。Spring DM是Spring框架的一个扩展,它专门用于在OSGi(开放服务网关协议)环境中管理Spring...
Spring DM,全称为Spring Dynamic Modules,是Spring框架的一个扩展,主要用于在OSGi(Open Service Gateway Initiative)环境下管理服务和应用程序。OSGi是一种模块化系统,它允许Java应用程序以模块化的形式进行...
在SpringDM(Spring Dynamic Modules)框架中,OSGi(Open Service Gateway Initiative)服务注册与引用是核心功能之一,它使得模块化系统中的组件能够互相发现并交互。本篇笔记将探讨如何在OSGi环境中注册服务以及...
标题“Spring DM集成Struts2(一)”指出我们要探讨的主题是关于如何在OSGi(Spring DM,即Spring Dynamic Modules)环境中集成Struts2框架。这是一个关键的Java Web开发中的技术结合,因为它允许开发者利用Spring的...
3. **SpringDM(Spring Dynamic Modules)**:SpringDM是Spring框架与OSGi集成的早期解决方案,它允许Spring应用在OSGi环境中运行。笔记可能详细介绍了SpringDM的工作原理和配置。 4. **Spring与OSGi的集成层次**:...
这通常通过使用Spring-DM(Spring Dynamic Modules)或者Apache Felix的Spring-DM服务实现,它是Spring在OSGi环境下的扩展。 接下来,我们来看计算器例子。这个例子可能包含两个主要部分:计算器服务...
为了在OSGi中运行Spring配置,可以使用Spring Dynamic Modules(SDM)或Spring Boot的OSGi支持。SDM是一个库,它使得Spring可以在OSGi环境中运行。配置好后,Spring容器会在OSGi bundle启动时自动初始化。 最后,...
第6章 将Spring与其他Web框架集成 209 6.1 在一般Web应用中访问Spring 209 6.1.1 问题 209 6.1.2 解决方案 210 6.1.3 工作原理 210 6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2...
8. **OSGi支持**:通过Spring Dynamic Modules,可以在OSGi服务平台上轻松部署和管理模块化应用。 9. **Spring源码dm Server**:一个基于Spring的轻量级应用服务器,优化了Spring应用程序的部署和运行环境。 此外...
第6章 将Spring与其他Web框架集成 209 6.1 在一般Web应用中访问Spring 209 6.1.1 问题 209 6.1.2 解决方案 210 6.1.3 工作原理 210 6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2...
标题 "OSGI+SpringDM+Hessian" 涉及到三个重要的技术概念,它们分别是OSGI(Open Services Gateway Initiative)、SpringDM(Spring Dynamic Modules)和Hessian。这些技术在Java开发领域中都有其独特的应用和价值。...
在OSGi环境中,Spring DM(Dynamic Modules,后来被更名为Blueprint)是Spring框架对OSGi服务的一种扩展,用于在bundle之间提供依赖注入和生命周期管理。 在OSGi中,bundle有其自身的生命周期,包括安装、启动、...