diff --git a/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/container/internal/DependenciesDeployer.java b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/container/internal/DependenciesDeployer.java
index ffff53d2c..d44f3de8e 100644
--- a/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/container/internal/DependenciesDeployer.java
+++ b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/container/internal/DependenciesDeployer.java
@@ -31,6 +31,7 @@
import org.apache.commons.io.FileUtils;
import org.ops4j.pax.exam.ExamSystem;
import org.ops4j.pax.exam.karaf.options.KarafFeaturesOption;
+import org.ops4j.pax.exam.karaf.options.SystemBundleOption;
import org.ops4j.pax.exam.options.BootClasspathLibraryOption;
import org.ops4j.pax.exam.options.ProvisionOption;
import org.ops4j.pax.exam.options.UrlReference;
@@ -69,7 +70,25 @@ public void copyBootClasspathLibraries() throws IOException {
karafHome + "/lib"), new String[] { "jar" }));
}
}
-
+
+ /**
+ *
+ * Copies SystemBundleOption entries into the Karaf system folder using the Maven repository folder convention.
+ *
+ * @throws IOException if copy fails
+ */
+ public void copySystemLibraries() throws IOException {
+ SystemBundleOption[] systemBundleOptions = subsystem
+ .getOptions(SystemBundleOption.class);
+ for (SystemBundleOption systemBundleOption : systemBundleOptions) {
+ UrlReference libraryUrl = systemBundleOption.getLibraryUrl();
+ String destPath = karafHome + "/system" + systemBundleOption.getRepositoryPath();
+ FileUtils.copyURLToFile(
+ new URL(libraryUrl.getURL()),
+ new File(destPath));
+ }
+ }
+
/**
* Copy dependencies specified as ProvisionOption in system to the deploy folder
*/
diff --git a/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/container/internal/KarafTestContainer.java b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/container/internal/KarafTestContainer.java
index f367aaec1..28af2e12b 100644
--- a/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/container/internal/KarafTestContainer.java
+++ b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/container/internal/KarafTestContainer.java
@@ -156,6 +156,7 @@ public synchronized TestContainer start() {
DependenciesDeployer deployer = new DependenciesDeployer(subsystem, karafBase,
karafHome);
deployer.copyBootClasspathLibraries();
+ deployer.copySystemLibraries();
updateLogProperties(karafHome, subsystem);
setupSystemProperties(karafHome, subsystem);
diff --git a/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/KarafDistributionOption.java b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/KarafDistributionOption.java
index 2ffb4859b..44bd88428 100644
--- a/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/KarafDistributionOption.java
+++ b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/KarafDistributionOption.java
@@ -29,6 +29,8 @@
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
+import org.ops4j.pax.exam.options.CompositeOption;
+import org.ops4j.pax.exam.options.DefaultCompositeOption;
import org.ops4j.pax.exam.options.UrlReference;
import org.ops4j.pax.exam.options.extra.VMOption;
@@ -109,6 +111,34 @@ public static KarafDistributionConfigurationSecurityOption configureSecurity() {
return new KarafDistributionConfigurationSecurityOption(null);
}
+ /**
+ * Returns an option to adding an artifact to the Karaf system directory using the provided file.
+ * A corresponding (maven) entry will also be placed into the startup.properties configuration.
+ *
+ * @return
+ */
+ public static CompositeOption systemBundle(String aGroup, String artifact, String version, File file) {
+ return new DefaultCompositeOption(
+ new SystemBundleOption(aGroup, artifact, version, file),
+ editConfigurationFilePut("etc/startup.properties",
+ "mvn:" + aGroup + "/" + artifact + "/" + version, "5")
+ );
+ }
+
+ /**
+ * Returns an option to adding an artifact to the Karaf system directory using the provided file.
+ * A corresponding (maven) entry will also be placed into the startup.properties configuration.
+ *
+ * @return
+ */
+ public static CompositeOption systemBundle(String aGroup, String artifact, String version) {
+ return new DefaultCompositeOption(
+ new SystemBundleOption(aGroup, artifact, version),
+ editConfigurationFilePut("etc/startup.properties",
+ "mvn:" + aGroup + "/" + artifact + "/" + version, "5")
+ );
+ }
+
/**
* Configures which distribution options to use. Relevant are the frameworkURL, the
* frameworkName and the Karaf version since all of those params are relevant to decide which
diff --git a/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/SystemBundleOption.java b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/SystemBundleOption.java
new file mode 100644
index 000000000..bdbf9da50
--- /dev/null
+++ b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/SystemBundleOption.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.ops4j.pax.exam.karaf.options;
+
+import java.io.File;
+import java.net.MalformedURLException;
+
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.options.MavenArtifactUrlReference;
+import org.ops4j.pax.exam.options.RawUrlReference;
+import org.ops4j.pax.exam.options.UrlReference;
+
+/**
+ * Copies the specified file into the Karaf system folder. (A Karaf folder that follows the m2
+ * directory structure). The artifact will also be added to the startup.properties
+ */
+public class SystemBundleOption implements Option {
+
+ private String group;
+ private String artifact;
+ private String version;
+ private File file;
+
+ /**
+ * Installs the specified artifact into the Karaf system folder and adds an entry to
+ * startup.properties
+ *
+ * @see SystemBundleOption
+ */
+ public SystemBundleOption(String aGroup, String artifact, String version, File file) {
+ addSystemBundle(aGroup, artifact, version, file);
+ }
+
+ /**
+ * Installs the specified artifact into the Karaf system folder and adds an entry to
+ * startup.properties
+ *
+ * @see SystemBundleOption
+ */
+ public SystemBundleOption(String aGroup, String artifact, String version) {
+ addSystemBundle(aGroup, artifact, version);
+ }
+
+ /**
+ * @return The Maven group ID
+ */
+ public String getGroup() {
+ return group;
+ }
+
+ /**
+ * @return The Maven artifact ID
+ */
+ public String getArtifact() {
+ return artifact;
+ }
+
+ /**
+ * @return The Maven version ID
+ */
+ public String getVersion() {
+ return version;
+ }
+
+ private SystemBundleOption addSystemBundle(String aGroup, String artifact, String version) {
+ return addSystemBundle(aGroup, artifact, version, null);
+ }
+
+ private SystemBundleOption addSystemBundle(String aGroup, String artifact, String version,
+ File file) {
+ this.group = aGroup;
+ this.artifact = artifact;
+ this.version = version;
+ this.file = file;
+ return this;
+ }
+
+ /**
+ * @return The URL to fetch the artifact
+ */
+ public UrlReference getLibraryUrl() {
+ if (file != null) {
+ try {
+ return new RawUrlReference(file.toURI().toURL().toString());
+ }
+ catch (MalformedURLException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+ else {
+ return new MavenArtifactUrlReference().groupId(group).artifactId(artifact)
+ .version(version);
+ }
+ }
+
+ /**
+ * @return The maven repository path to the artifact. Must start with /. This
+ * path should not include the /system prefix.
+ */
+ public String getRepositoryPath() {
+ String path = "/" + getGroup().replace(".", "/");
+ path += "/" + getArtifact();
+ path += "/" + getVersion();
+ if (file != null) {
+ path += "/" + file.getName();
+ }
+ else {
+ path += "/" + getArtifact() + "-" + getVersion() + ".jar";
+ }
+ return path;
+ }
+}
diff --git a/containers/pax-exam-container-karaf/src/test/java/org/ops4j/pax/exam/karaf/container/SystemBundleOptionTest.java b/containers/pax-exam-container-karaf/src/test/java/org/ops4j/pax/exam/karaf/container/SystemBundleOptionTest.java
new file mode 100644
index 000000000..5099062e2
--- /dev/null
+++ b/containers/pax-exam-container-karaf/src/test/java/org/ops4j/pax/exam/karaf/container/SystemBundleOptionTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 Harald Wellmann
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.ops4j.pax.exam.karaf.container;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.junit.Assert.assertThat;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.inject.Inject;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerMethod;
+import org.ops4j.pax.swissbox.tracker.ServiceLookup;
+import org.osgi.framework.BundleContext;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerMethod.class)
+public class SystemBundleOptionTest extends KarafTestContainerITest {
+
+ @Inject
+ BundleContext bc;
+
+ @Configuration
+ public Option[] config() {
+ ArrayList