Index: assembly/src/main/distribution/text/etc/org.ops4j.pax.url.mvn.cfg
===================================================================
--- assembly/src/main/distribution/text/etc/org.ops4j.pax.url.mvn.cfg (revision 999885)
+++ assembly/src/main/distribution/text/etc/org.ops4j.pax.url.mvn.cfg (working copy)
@@ -55,7 +55,8 @@
#
# The following property value will add the system folder as a repo.
#
-org.ops4j.pax.url.mvn.defaultRepositories=file:${karaf.home}/${karaf.default.repository}@snapshots
+org.ops4j.pax.url.mvn.defaultRepositories=file:${karaf.home}/${karaf.default.repository}@snapshots, \
+ file:${karaf.home}/local-repo@snapshots
#
# Comma separated list of repositories scanned when resolving an artifact.
Index: assembly/src/main/descriptors/windows-bin.xml
===================================================================
--- assembly/src/main/descriptors/windows-bin.xml (revision 999885)
+++ assembly/src/main/descriptors/windows-bin.xml (working copy)
@@ -199,6 +199,7 @@
org.apache.karaf.deployer:org.apache.karaf.deployer.spring
org.apache.karaf.deployer:org.apache.karaf.deployer.blueprint
org.apache.karaf.deployer:org.apache.karaf.deployer.features
+ org.apache.karaf.deployer:org.apache.karaf.deployer.kar
Index: assembly/src/main/descriptors/unix-bin.xml
===================================================================
--- assembly/src/main/descriptors/unix-bin.xml (revision 999885)
+++ assembly/src/main/descriptors/unix-bin.xml (working copy)
@@ -212,6 +212,7 @@
org.apache.karaf.deployer:org.apache.karaf.deployer.spring
org.apache.karaf.deployer:org.apache.karaf.deployer.blueprint
org.apache.karaf.deployer:org.apache.karaf.deployer.features
+ org.apache.karaf.deployer:org.apache.karaf.deployer.kar
Index: assembly/src/main/filtered-resources/etc/startup.properties
===================================================================
--- assembly/src/main/filtered-resources/etc/startup.properties (revision 999885)
+++ assembly/src/main/filtered-resources/etc/startup.properties (working copy)
@@ -62,3 +62,4 @@
org/apache/karaf/deployer/org.apache.karaf.deployer.spring/${project.version}/org.apache.karaf.deployer.spring-${project.version}.jar=30
org/apache/karaf/deployer/org.apache.karaf.deployer.blueprint/${project.version}/org.apache.karaf.deployer.blueprint-${project.version}.jar=30
org/apache/karaf/deployer/org.apache.karaf.deployer.features/${project.version}/org.apache.karaf.deployer.features-${project.version}.jar=30
+org/apache/karaf/deployer/org.apache.karaf.deployer.kar/${project.version}/org.apache.karaf.deployer.kar-${project.version}.jar=30
Index: assembly/src/main/filtered-resources/features.xml
===================================================================
--- assembly/src/main/filtered-resources/features.xml (revision 999885)
+++ assembly/src/main/filtered-resources/features.xml (working copy)
@@ -66,6 +66,9 @@
mvn:org.ops4j.pax.url/pax-url-war/${pax.url.version}
mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.war/${project.version}
+
+ mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.kar/${project.version}
+
http
Index: assembly/pom.xml
===================================================================
--- assembly/pom.xml (revision 999885)
+++ assembly/pom.xml (working copy)
@@ -74,6 +74,10 @@
org.apache.karaf.deployer
+ org.apache.karaf.deployer.kar
+
+
+ org.apache.karaf.deployer
org.apache.karaf.deployer.war
Index: deployer/pom.xml
===================================================================
--- deployer/pom.xml (revision 999885)
+++ deployer/pom.xml (working copy)
@@ -37,6 +37,7 @@
blueprint
features
war
+ kar
Index: deployer/kar/NOTICE
===================================================================
--- deployer/kar/NOTICE (revision 0)
+++ deployer/kar/NOTICE (revision 0)
@@ -0,0 +1,21 @@
+Apache Felix Karaf
+Copyright 2010 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+
+II. Used Software
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2010).
+Licensed under the Apache License 2.0.
+
+
+III. License Summary
+- Apache License 2.0
Index: deployer/kar/src/test/java/org/apache/karaf/deployer/kar/KarArtifactInstallerTest.java
===================================================================
--- deployer/kar/src/test/java/org/apache/karaf/deployer/kar/KarArtifactInstallerTest.java (revision 0)
+++ deployer/kar/src/test/java/org/apache/karaf/deployer/kar/KarArtifactInstallerTest.java (revision 0)
@@ -0,0 +1,183 @@
+package org.apache.karaf.deployer.kar;
+
+import static org.easymock.EasyMock.createMock;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.net.URI;
+
+import org.apache.karaf.features.FeaturesService;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class KarArtifactInstallerTest {
+ private KarArtifactInstaller karArtifactInstaller;
+ private FeaturesService featuresService;
+
+ private URI goodKarFile;
+ private URI zipFileWithKarafManifest;
+ private URI zipFileWithoutKarafManifest;
+ private URI badZipFile;
+
+ @Before
+ public void setUp() throws Exception {
+ featuresService = createMock(FeaturesService.class);
+
+ karArtifactInstaller = new KarArtifactInstaller();
+
+ karArtifactInstaller.setFeaturesService(featuresService);
+ karArtifactInstaller.setLocalRepoPath("./target/local-repo");
+
+ karArtifactInstaller.init();
+
+ goodKarFile = getClass().getClassLoader().getResource("goodKarFile.kar").toURI();
+ zipFileWithKarafManifest = getClass().getClassLoader().getResource("karFileAsZip.zip").toURI();
+ zipFileWithoutKarafManifest = getClass().getClassLoader().getResource("karFileAsZipNoManifest.zip").toURI();
+ badZipFile = getClass().getClassLoader().getResource("badZipFile.zip").toURI();
+ }
+
+ @After
+ public void destroy() throws Exception {
+ karArtifactInstaller.destroy();
+ karArtifactInstaller.deleteLocalRepository();
+ }
+
+
+
+ @Test
+ public void shouldHandleKarFile() throws Exception {
+ assertTrue(karArtifactInstaller.canHandle(new File(goodKarFile)));
+ }
+
+ @Test
+ public void shouldHandleZipFileWithKarafManifest() throws Exception {
+ assertTrue(karArtifactInstaller.canHandle(new File(zipFileWithKarafManifest)));
+ }
+
+ @Test
+ public void shouldIgnoreZipFileWithoutKarafManifest() throws Exception {
+ assertFalse(karArtifactInstaller.canHandle(new File(zipFileWithoutKarafManifest)));
+ }
+
+ @Test
+ public void shouldIgnoreBadZipFile() throws Exception {
+ assertFalse(karArtifactInstaller.canHandle(new File(badZipFile)));
+ }
+
+ @Test
+ public void shouldRecognizeGoodFeaturesFile() throws Exception
+ {
+ File goodFeaturesXml = new File(getClass().getClassLoader().getResource("goodKarFile/org/foo/goodFeaturesXml.xml").getFile());
+ Assert.assertTrue(karArtifactInstaller.isFeaturesRepository(goodFeaturesXml));
+ }
+
+ @Test
+ public void shouldRejectNonFeaturesXMLFile() throws Exception
+ {
+ File goodFeaturesXml = new File(getClass().getClassLoader().getResource("badFeaturesXml.xml").toURI());
+ Assert.assertFalse(karArtifactInstaller.isFeaturesRepository(goodFeaturesXml));
+ }
+
+
+ @Test
+ public void shouldRejectMalformedXMLFile() throws Exception
+ {
+ File malformedXml = new File(getClass().getClassLoader().getResource("malformedXml.xml").toURI());
+ Assert.assertFalse(karArtifactInstaller.isFeaturesRepository(malformedXml));
+ }
+
+ @Test
+ public void shouldExtractAndRegisterFeaturesFromKar() throws Exception {
+ // Setup expectations on the features service
+ featuresService.addRepository(EasyMock.anyObject(URI.class));
+ EasyMock.replay(featuresService);
+
+ // Test
+ //
+ File goodKarFile = new File(getClass().getClassLoader().getResource("goodKarFile.kar").getFile());
+ karArtifactInstaller.install(goodKarFile);
+
+ // Verify expectations.
+ //
+ EasyMock.verify(featuresService);
+ }
+
+ @Test
+ public void shouldLogAndNotThrowExceptionIfCannotAddToFeaturesRepository() throws Exception {
+ // Setup expectations on the features service
+ featuresService.addRepository(EasyMock.anyObject(URI.class));
+ EasyMock.expectLastCall().andThrow(new Exception("Unable to add to repository."));
+ EasyMock.replay(featuresService);
+
+ // Test
+ //
+ File goodKarFile = new File(getClass().getClassLoader().getResource("goodKarFile.kar").getFile());
+ karArtifactInstaller.install(goodKarFile);
+
+ // Verify expectations.
+ //
+ EasyMock.verify(featuresService);
+ }
+
+ @Test
+ public void shouldIgnoreUpdateIfFileHasNotChanged() throws Exception {
+ // Setup expectations on the features service: the addRepository
+ // should only be added once, as the update command should be ignored!
+ //
+ featuresService.addRepository(EasyMock.anyObject(URI.class));
+ EasyMock.replay(featuresService);
+
+ // Test
+ //
+ File goodKarFile = new File(getClass().getClassLoader().getResource("goodKarFile.kar").getFile());
+ karArtifactInstaller.install(goodKarFile);
+ karArtifactInstaller.update(goodKarFile);
+
+ // Verify expectations.
+ //
+ EasyMock.verify(featuresService);
+ }
+
+ @Test
+ public void shouldExtractAndRegisterFeaturesFromZip() throws Exception {
+ // Setup expectations on the features service
+ featuresService.addRepository(EasyMock.anyObject(URI.class));
+ EasyMock.replay(featuresService);
+
+ // Test
+ //
+ File karFileAsZip = new File(getClass().getClassLoader().getResource("karFileAsZip.zip").getFile());
+ karArtifactInstaller.install(karFileAsZip);
+
+ // Verify expectations.
+ //
+ EasyMock.verify(featuresService);
+ }
+
+ @Test (expected = java.io.IOException.class)
+ public void shouldThrowExceptionIfFileDoesNotExist() throws Exception
+ {
+ File nonExistantFile = new File("DoesNotExist");
+ karArtifactInstaller.install(nonExistantFile);
+ }
+
+ @Test
+ public void uninstallShouldDoNothing() throws Exception
+ {
+ EasyMock.replay(featuresService);
+
+ // Test
+ //
+ File karFileAsZip = new File(getClass().getClassLoader().getResource("karFileAsZip.zip").getFile());
+ karArtifactInstaller.uninstall(karFileAsZip);
+
+ // Verify expectations.
+ //
+ EasyMock.verify(featuresService);
+ }
+
+}
Index: deployer/kar/src/test/resources/goodKarFile.kar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: deployer/kar/src/test/resources/goodKarFile.kar
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: deployer/kar/src/test/resources/karFileAsZip/META-INF/KARAF.MF
===================================================================
Index: deployer/kar/src/test/resources/karFileAsZip/org/foo/goodFeaturesXml.xml
===================================================================
--- deployer/kar/src/test/resources/karFileAsZip/org/foo/goodFeaturesXml.xml (revision 0)
+++ deployer/kar/src/test/resources/karFileAsZip/org/foo/goodFeaturesXml.xml (revision 0)
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
Index: deployer/kar/src/test/resources/badFeaturesXml.xml
===================================================================
--- deployer/kar/src/test/resources/badFeaturesXml.xml (revision 0)
+++ deployer/kar/src/test/resources/badFeaturesXml.xml (revision 0)
@@ -0,0 +1 @@
+This is not a features file!
\ No newline at end of file
Index: deployer/kar/src/test/resources/karFileAsZip.zip
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: deployer/kar/src/test/resources/karFileAsZip.zip
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: deployer/kar/src/test/resources/goodKarFile/META-INF/KARAF.MF
===================================================================
Index: deployer/kar/src/test/resources/goodKarFile/org/foo/goodFeaturesXml.xml
===================================================================
--- deployer/kar/src/test/resources/goodKarFile/org/foo/goodFeaturesXml.xml (revision 0)
+++ deployer/kar/src/test/resources/goodKarFile/org/foo/goodFeaturesXml.xml (revision 0)
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
Index: deployer/kar/src/test/resources/goodKarFile/org/bar/hello.txt
===================================================================
Index: deployer/kar/src/test/resources/malformedXml.xml
===================================================================
--- deployer/kar/src/test/resources/malformedXml.xml (revision 0)
+++ deployer/kar/src/test/resources/malformedXml.xml (revision 0)
@@ -0,0 +1 @@
+
+
+
+
+
\ No newline at end of file
Index: deployer/kar/src/test/resources/karFileAsZipNoManifest.zip
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: deployer/kar/src/test/resources/karFileAsZipNoManifest.zip
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Index: deployer/kar/src/test/resources/badZipFile.zip
===================================================================
--- deployer/kar/src/test/resources/badZipFile.zip (revision 0)
+++ deployer/kar/src/test/resources/badZipFile.zip (revision 0)
@@ -0,0 +1 @@
+This is *not* a well formed .kar file :(
\ No newline at end of file
Index: deployer/kar/src/test/resources/log4j.properties
===================================================================
--- deployer/kar/src/test/resources/log4j.properties (revision 0)
+++ deployer/kar/src/test/resources/log4j.properties (revision 0)
@@ -0,0 +1,8 @@
+log4j.rootLogger=DEBUG, stdout
+
+#The logging properties used during tests..
+# CONSOLE appender not used by default
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%-5p %-30.30c{1} - %m%n
+log4j.appender.stdout.threshold=DEBUG
Index: deployer/kar/src/main/java/org/apache/karaf/deployer/kar/KarArtifactInstaller.java
===================================================================
--- deployer/kar/src/main/java/org/apache/karaf/deployer/kar/KarArtifactInstaller.java (revision 0)
+++ deployer/kar/src/main/java/org/apache/karaf/deployer/kar/KarArtifactInstaller.java (revision 0)
@@ -0,0 +1,246 @@
+package org.apache.karaf.deployer.kar;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.felix.fileinstall.ArtifactInstaller;
+import org.apache.karaf.features.FeaturesService;
+import org.w3c.dom.Document;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+public class KarArtifactInstaller implements ArtifactInstaller {
+
+ private static Log logger = LogFactory.getLog(KarArtifactInstaller.class);
+
+ private static final String KAR_PREFIX = ".kar";
+ private static final String ZIP_PREFIX = ".zip";
+
+ private String localRepoPath = "./local-repo";
+
+ private String timestampPath;
+
+ private byte[] buffer = new byte[5 * 1024];
+
+ private DocumentBuilderFactory dbf;
+
+ private FeaturesService featuresService;
+
+ public void init() {
+ dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+
+ timestampPath = localRepoPath + File.separator + ".timestamps";
+ if (new File(timestampPath).mkdirs()) {
+ logger.warn("Unable to create directory for Karaf Archive timestamps. Results may vary...");
+ }
+
+ if (logger.isInfoEnabled()) {
+ logger.info("Karaf archives will be extracted to " + localRepoPath);
+ logger.info("Timestamps for Karaf archives will be extracted to " + timestampPath);
+
+ }
+ }
+
+ public void destroy() {
+ logger.info("Karaf archive installer destroyed.");
+ }
+
+
+ public void install(File file) throws Exception {
+ // Check to see if this file has already been extracted. For example, on restart of Karaf,
+ // we don't necessarily want to re-extract all the Karaf Archives!
+ //
+ if (alreadyExtracted(file)) {
+ logger.info("Ignoring '" + file + "'; timestamp indicates it's already been deployed.");
+ return;
+ }
+
+ if (logger.isInfoEnabled())
+ logger.info("Installing " + file);
+
+ ZipFile zipFile = new ZipFile(file);
+
+ Enumeration entries = (Enumeration) zipFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = (ZipEntry) entries.nextElement();
+
+ if (! entry.getName().startsWith("META-INF")) {
+ if (entry.isDirectory()) {
+ java.io.File directory = new File(localRepoPath + File.separator + entry.getName());
+ if (logger.isDebugEnabled())
+ logger.debug("Creating directory '" + directory.getName());
+ directory.mkdirs();
+ } else {
+ File extract = new File(localRepoPath + File.separator + entry.getName());
+ BufferedOutputStream bos = new BufferedOutputStream(
+ new FileOutputStream(extract));
+
+ int count = 0;
+ int totalBytes = 0;
+ InputStream inputStream = zipFile.getInputStream(entry);
+ while ((count = inputStream.read(buffer)) > 0)
+ {
+ bos.write(buffer, 0, count);
+ totalBytes += count;
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("Extracted " + totalBytes + " bytes to " + extract);
+
+ bos.close();
+ inputStream.close();
+
+ if (isFeaturesRepository(extract)) {
+ addToFeaturesRepositories(extract);
+ }
+ }
+ }
+ }
+
+ zipFile.close();
+
+ updateTimestamp(file);
+ }
+
+ public void uninstall(File file) throws Exception {
+ logger.warn("Karaf archive '" + file + "' has been removed; however, it's feature URLs have not been deregistered, and it's bundles are still available in '" + localRepoPath + "'.");
+ }
+
+ public void update(File file) throws Exception {
+ logger.warn("Karaf archive " + file + " has been updated; redeploying.");
+ install(file);
+ }
+
+ protected void updateTimestamp(File karafArchive) throws Exception {
+ File timestamp = getArchiveTimestampFile(karafArchive);
+
+ if (timestamp.exists()) {
+ if (logger.isDebugEnabled())
+ logger.debug("Deleting old timestamp file '" + timestamp + "");
+
+ if (!timestamp.delete()) {
+ throw new Exception("Unable to delete archive timestamp '" + timestamp + "'");
+ }
+ }
+
+ logger.debug("Creating timestamp file '" + timestamp + "'");
+ timestamp.createNewFile();
+ }
+
+ protected boolean alreadyExtracted(File karafArchive) {
+ File timestamp = getArchiveTimestampFile(karafArchive);
+ if (timestamp.exists()) {
+ return timestamp.lastModified() >= karafArchive.lastModified();
+ }
+ return false;
+ }
+
+ protected File getArchiveTimestampFile(File karafArchive) {
+ return new File(localRepoPath + File.separator + ".timestamps" + File.separator + karafArchive.getName());
+ }
+
+ protected boolean isFeaturesRepository(File artifact) {
+ try {
+ if (artifact.isFile() && artifact.getName().endsWith(".xml")) {
+ Document doc = parse(artifact);
+ String name = doc.getDocumentElement().getLocalName();
+ String uri = doc.getDocumentElement().getNamespaceURI();
+ if ("features".equals(name) && (uri == null || "".equals(uri))) {
+ return true;
+ }
+ }
+ } catch (Exception e) {
+ if (logger.isDebugEnabled())
+ logger.debug("File " + artifact.getName() + " is not a features file.", e);
+ }
+ return false;
+ }
+
+ protected Document parse(File artifact) throws Exception {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ db.setErrorHandler(new ErrorHandler() {
+ public void warning(SAXParseException exception) throws SAXException {
+ }
+ public void error(SAXParseException exception) throws SAXException {
+ }
+ public void fatalError(SAXParseException exception) throws SAXException {
+ throw exception;
+ }
+ });
+ return db.parse(artifact);
+ }
+
+ private void addToFeaturesRepositories(File file) {
+ try {
+ featuresService.addRepository(file.toURI());
+ if (logger.isInfoEnabled())
+ logger.info("Added feature repository '" + file.toURI() + "'.");
+ } catch (Exception e) {
+ logger.error("Unable to add repository '" + file.getName() + "'", e);
+ }
+ }
+
+ public boolean canHandle(File file) {
+ // If the file ends with .kar, then we can handle it!
+ //
+ if (file.isFile() && file.getName().endsWith(KAR_PREFIX)) {
+ logger.info("Found a .kar file to deploy.");
+ return true;
+ }
+ // Otherwise, check to see if it's a zip file containing a META-INF/KARAF.MF manifest.
+ //
+ else if (file.isFile() && file.getName().endsWith(ZIP_PREFIX)) {
+ logger.debug("Found a .zip file to deploy; checking contents to see if it's a Karaf archive.");
+ try {
+ if (new ZipFile(file).getEntry("META-INF/KARAF.MF") != null) {
+ logger.info("Found a Karaf archive with .zip prefix; will deploy.");
+ return true;
+ }
+ } catch (Exception e) {
+ logger.warn("Problem extracting zip file '" + file.getName() + "'; ignoring.", e);
+ }
+ }
+
+ return false;
+ }
+
+ public boolean deleteLocalRepository() {
+ return deleteDirectory(new File(localRepoPath));
+ }
+
+ private boolean deleteDirectory(File path) {
+ if (path.exists()) {
+ File[] files = path.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ if (files[i].isDirectory()) {
+ deleteDirectory(files[i]);
+ } else {
+ files[i].delete();
+ }
+ }
+ }
+ return (path.delete());
+ }
+
+ public void setLocalRepoPath(String localRepoPath) {
+ this.localRepoPath = localRepoPath;
+ }
+
+ public void setFeaturesService(FeaturesService featuresService) {
+ this.featuresService = featuresService;
+ }
+
+}
Index: deployer/kar/src/main/resources/OSGI-INF/blueprint/kar-deployer.xml
===================================================================
--- deployer/kar/src/main/resources/OSGI-INF/blueprint/kar-deployer.xml (revision 0)
+++ deployer/kar/src/main/resources/OSGI-INF/blueprint/kar-deployer.xml (revision 0)
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: deployer/kar/pom.xml
===================================================================
--- deployer/kar/pom.xml (revision 0)
+++ deployer/kar/pom.xml (revision 0)
@@ -0,0 +1,102 @@
+
+
+
+
+ 4.0.0
+
+
+ org.apache.karaf.deployer
+ deployer
+ 2.1.99-SNAPSHOT
+
+
+ org.apache.karaf.deployer
+ org.apache.karaf.deployer.kar
+ bundle
+ 2.1.99-SNAPSHOT
+ Apache Karaf :: Karaf Archive (.kar) Deployer
+
+ This deployer can deploy .kar archives on the fly
+
+
+ ${basedir}/../../etc/appended-resources
+
+
+
+
+ org.apache.felix
+ org.osgi.core
+ provided
+
+
+ org.springframework.osgi
+ spring-osgi-core
+
+
+ org.apache.karaf.features
+ org.apache.karaf.features.core
+
+
+ commons-logging
+ commons-logging
+
+
+ org.apache.felix
+ org.apache.felix.fileinstall
+
+
+ org.apache.servicemix.bundles
+ org.apache.servicemix.bundles.junit
+
+
+ org.easymock
+ easymock
+ 3.0
+ jar
+ test
+
+
+ log4j
+ log4j
+ 1.2.16
+ test
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+
+
+
+ ${project.artifactId};blueprint.graceperiod:=false
+ ${project.artifactId}*;version=${project.version}
+ !${project.artifactId}*,*
+ org.apache.karaf.deployer.features
+ <_versionpolicy>${bnd.version.policy}
+
+
+
+
+
+
+
Index: pom.xml
===================================================================
--- pom.xml (revision 999885)
+++ pom.xml (working copy)
@@ -244,6 +244,11 @@
${project.version}
+ org.apache.karaf.deployer
+ org.apache.karaf.deployer.kar
+ ${project.version}
+
+
org.apache.karaf
org.apache.karaf.management
${project.version}
Index: features/command/src/main/resources/OSGI-INF/blueprint/features-command.xml
===================================================================
--- features/command/src/main/resources/OSGI-INF/blueprint/features-command.xml (revision 999885)
+++ features/command/src/main/resources/OSGI-INF/blueprint/features-command.xml (working copy)
@@ -36,12 +36,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
@@ -96,7 +96,7 @@
-
+