FELIX-1914: Add a command to enable debug logging for the OSGi framework
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@887538 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/FrameworkDebug.java b/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/FrameworkDebug.java
new file mode 100644
index 0000000..7413c91
--- /dev/null
+++ b/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/FrameworkDebug.java
@@ -0,0 +1,71 @@
+/*
+ * 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.apache.felix.karaf.shell.dev;
+
+import java.io.File;
+
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+import org.apache.felix.karaf.shell.console.OsgiCommandSupport;
+import org.apache.felix.karaf.shell.dev.framework.Equinox;
+import org.apache.felix.karaf.shell.dev.framework.Felix;
+import org.apache.felix.karaf.shell.dev.framework.Framework;
+
+/**
+ * Command for enabling/disabling debug logging on the OSGi framework
+ */
+@Command(scope = "dev", name = "framework",
+ description = "Enable/disable debugging for the OSGi Framework")
+public class FrameworkDebug extends OsgiCommandSupport {
+
+ private static final String KARAF_BASE = System.getProperty("karaf.base");
+
+ @Option(name = "-debug", aliases={"--enable-debug"}, description="Enable debug for the OSGi framework", required = false, multiValued = false)
+ boolean debug;
+
+ @Option(name = "-nodebug", aliases={"--disable-debug"}, description="Disable debug for the OSGi framework", required = false, multiValued = false)
+ boolean nodebug;
+
+ @Override
+ protected Object doExecute() throws Exception {
+ Framework framework = getFramework();
+
+ if (!debug^nodebug) {
+ System.err.printf("Required option missing: use -debug or -nodebug%n");
+ return null;
+ }
+ if (debug) {
+ System.out.printf("Enabling debug for OSGi framework (%s)%n", framework.getName());
+ framework.enableDebug(new File(KARAF_BASE));
+ }
+ if (nodebug) {
+ System.out.printf("Disabling debug for OSGi framework (%s)%n", framework.getName());
+ framework.disableDebug(new File(KARAF_BASE));
+ }
+
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+
+ public Framework getFramework() {
+ if (bundleContext.getBundle(0).getSymbolicName().contains("felix")) {
+ return new Felix(new File(KARAF_BASE));
+ } else {
+ return new Equinox(new File(KARAF_BASE));
+ }
+ }
+}
diff --git a/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/framework/Equinox.java b/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/framework/Equinox.java
new file mode 100644
index 0000000..288697b
--- /dev/null
+++ b/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/framework/Equinox.java
@@ -0,0 +1,69 @@
+/*
+ * 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.apache.felix.karaf.shell.dev.framework;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.felix.karaf.shell.dev.util.IO;
+
+/**
+ * Represents Eclipse's Equinox as the underlying OSGi framework
+ */
+public class Equinox extends Framework {
+
+ /**
+ * Create a new instance
+ *
+ * @param base
+ */
+ public Equinox(File base) {
+ super(base);
+ }
+
+ public String getName() {
+ return "Equinox";
+ }
+
+ public void enableDebug(File directory) throws IOException {
+ setConfigProperty("osgi.debug", "etc/equinox-debug.properties");
+ saveConfigProperties();
+
+ System.out.printf("- set osgi.debug=etc/equinox-debug.properties in etc/config.properties%n");
+
+ File debug = new File(directory, "etc/equinox-debug.properties");
+ if (!debug.exists()) {
+ IO.copyTextToFile(
+ Equinox.class.getResourceAsStream("equinox-debug.properties"),
+ debug);
+ System.out.printf("- created etc/equinox-debug.properties to configure Equinox debugging options%n");
+ }
+
+ System.out.printf("%nEnable specific debug options in etc/equinox-debug.properties%n");
+ System.out.printf("and restart Karaf now to enable Equinox debug logging%n");
+ }
+
+ @Override
+ public void disableDebug(File directory) throws IOException {
+ removeConfigProperty("osgi.debug");
+ saveConfigProperties();
+
+ System.out.printf("- removed osgi.debug from etc/config.properties%n%n");
+ System.out.printf("Restart Karaf now to disable Equinox debug logging%n");
+
+ }
+}
diff --git a/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/framework/Felix.java b/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/framework/Felix.java
new file mode 100644
index 0000000..ff5c6a9
--- /dev/null
+++ b/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/framework/Felix.java
@@ -0,0 +1,55 @@
+/*
+ * 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.apache.felix.karaf.shell.dev.framework;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Represents Apache Felix as the underlying OSGi platform
+ */
+public class Felix extends Framework {
+
+ /**
+ * Create a instance of Karaf running with Felix in the given base directory
+ *
+ * @param base the base directory
+ */
+ public Felix(File base) {
+ super(base);
+ }
+
+ public String getName() {
+ return "Felix";
+ }
+
+ public void enableDebug(File directory) throws IOException {
+ setConfigProperty("felix.log.level", "4");
+ saveConfigProperties();
+
+ System.out.printf("- set felix.log.level=4 in etc/config.properties%n%n");
+ System.out.printf("Restart Karaf now to enable Felix debug logging%n");
+ }
+
+ public void disableDebug(File directory) throws IOException {
+ removeConfigProperty("felix.log.level");
+ saveConfigProperties();
+
+ System.out.printf("- removed felix.log.level from etc/config.properties%n%n");
+ System.out.printf("Restart Karaf now to disable Felix debug logging%n");
+ }
+}
diff --git a/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/framework/Framework.java b/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/framework/Framework.java
new file mode 100644
index 0000000..e930549
--- /dev/null
+++ b/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/framework/Framework.java
@@ -0,0 +1,154 @@
+/*
+ * 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.apache.felix.karaf.shell.dev.framework;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Class to represent the underlying OSGi framework
+ */
+public abstract class Framework {
+
+ /*
+ * The Karaf base directory
+ */
+ private File base;
+
+ /*
+ * The contents of the etc/config.properties file
+ */
+ private List<String> config;
+
+ /**
+ * Create a instance of this framework in the given base directory
+ *
+ * @param base the base directory
+ */
+ public Framework(File base) {
+ super();
+ this.base = base;
+ }
+
+ /**
+ * Get the underlying OSGi framework name
+ */
+ public abstract String getName();
+
+ /**
+ * Enable the OSGi framework's debug logging
+ *
+ * @param directory the directory containing the Karaf installation
+ * @throws IOException when a problem occurs configuring debug settings
+ */
+ public abstract void enableDebug(File directory) throws IOException;
+
+ /**
+ * Disable the OSGI framework's debug logging
+ *
+ * @param directory the Karaf base installation directory
+ * @throws IOException when a problem occurs removing debug configuration settings
+ */
+ public abstract void disableDebug(File directory) throws IOException;
+
+ /*
+ * Save the etc/config.properties file
+ */
+ protected void saveConfigProperties() throws IOException {
+ PrintWriter writer = null;
+ try {
+ writer = new PrintWriter(new File(base, "etc/config.properties"));
+ for (String line : getConfig()) {
+ writer.printf("%s%n", line);
+ }
+ writer.flush();
+ writer.close();
+ } finally {
+ if (writer != null) {
+ writer.close();
+ }
+ }
+ }
+
+ protected List<String> readPropertyFile(File config) throws IOException {
+ List<String> result = new LinkedList<String>();
+ BufferedReader reader = new BufferedReader(new FileReader(config));
+ String line = reader.readLine();
+ while (line != null) {
+ result.add(line);
+ line = reader.readLine();
+ }
+ return result;
+ }
+
+ /**
+ * Set a new key and value in the etc/config.properties - if the given key
+ * already exists, the existing value will be overwritten
+ *
+ * @param key property key
+ * @param value property value
+ * @throws IOException if the etc/config.properties file can not be read
+ */
+ protected void setConfigProperty(String key, String value) throws IOException {
+ boolean done = false;
+
+ for (int i = 0 ; i < getConfig().size() ; i++) {
+ if (getConfig().get(i).startsWith(key)) {
+ getConfig().set(i, java.lang.String.format("%s=%s", key, value));
+ done = true;
+ }
+ }
+
+ if (!done) {
+ getConfig().add("");
+ getConfig().add(java.lang.String.format("%s=%s", key, value, new Date()));
+ }
+ }
+
+ /**
+ * Remove an existing key from the etc/config.properties file
+ *
+ * @param key the key
+ * @throws IOException if the etc/config.properties file can not be read
+ */
+ protected void removeConfigProperty(String key) throws IOException {
+ for (int i = 0 ; i < getConfig().size() ; i++) {
+ if (getConfig().get(i).startsWith(key)) {
+ getConfig().remove(i);
+ }
+ }
+ }
+
+ /**
+ * Access the contents of the etc/config.properties file
+ *
+ * @return the contents of the file
+ * @throws IOException if the etc/config.properties file can not be read
+ */
+ public List<String> getConfig() throws IOException {
+ if (config == null) {
+ config = readPropertyFile(new File(base, "etc/config.properties"));
+ }
+ return config;
+ }
+}
diff --git a/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/util/IO.java b/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/util/IO.java
new file mode 100644
index 0000000..15f5f45
--- /dev/null
+++ b/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/util/IO.java
@@ -0,0 +1,58 @@
+/*
+ * 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.apache.felix.karaf.shell.dev.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.Scanner;
+
+/**
+ * Helper class for I/O operations
+ */
+public class IO {
+
+ /**
+ * Write text from an InputStream to a file
+ */
+ public static void copyTextToFile(InputStream stream, File file) throws IOException {
+ PrintWriter writer = null;
+ Scanner scanner = null;
+
+ try {
+ scanner = new Scanner(stream);
+ writer = new PrintWriter(file);
+
+ while (scanner.hasNextLine()) {
+ writer.printf("%s%n", scanner.nextLine());
+ }
+
+ writer.flush();
+ } finally {
+ if (scanner != null) {
+ scanner.close();
+ }
+ if (writer != null) {
+ writer.close();
+ }
+ }
+ }
+}
diff --git a/karaf/shell/dev/src/main/resources/OSGI-INF/blueprint/shell-dev.xml b/karaf/shell/dev/src/main/resources/OSGI-INF/blueprint/shell-dev.xml
index a695b7a..2dd7d28 100644
--- a/karaf/shell/dev/src/main/resources/OSGI-INF/blueprint/shell-dev.xml
+++ b/karaf/shell/dev/src/main/resources/OSGI-INF/blueprint/shell-dev.xml
@@ -23,6 +23,9 @@
<command name="dev/show-tree">
<action class="org.apache.felix.karaf.shell.dev.ShowBundleTree"/>
</command>
+ <command name="dev/framework">
+ <action class="org.apache.felix.karaf.shell.dev.FrameworkDebug" />
+ </command>
</command-bundle>
</blueprint>
diff --git a/karaf/shell/dev/src/main/resources/org/apache/felix/karaf/shell/dev/framework/equinox-debug.properties b/karaf/shell/dev/src/main/resources/org/apache/felix/karaf/shell/dev/framework/equinox-debug.properties
new file mode 100644
index 0000000..b842875
--- /dev/null
+++ b/karaf/shell/dev/src/main/resources/org/apache/felix/karaf/shell/dev/framework/equinox-debug.properties
@@ -0,0 +1,111 @@
+# 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.
+
+
+#### Debugging options for org.eclipse.osgi
+
+# Turn on general debugging for org.eclipse.osgi
+org.eclipse.osgi/debug=false
+# Prints out class loading debug information
+org.eclipse.osgi/debug/loader=false
+# Prints out event (FrameworkEvent/BundleEvent/ServiceEvent) and listener debug information
+org.eclipse.osgi/debug/events=false
+# Prints out OSGi service debug information (registration/getting/ungetting etc.)
+org.eclipse.osgi/debug/services=false
+# Prints out bundle manifest parsing debug information
+org.eclipse.osgi/debug/manifest=false
+# Prints out LDAP filter debug information
+org.eclipse.osgi/debug/filter=false
+# Prints out security (PermissionAdmin service) debug information
+org.eclipse.osgi/debug/security=false
+# Prints out start level service debug information
+org.eclipse.osgi/debug/startlevel=false
+# Prints out package admin service debug information
+org.eclipse.osgi/debug/packageadmin=false
+# Prints out timing information for bundle activation
+org.eclipse.osgi/debug/bundleTime=false
+# Debug the loading of message bundles
+org.eclipse.osgi/debug/messageBundles=false
+
+# Eclipse adaptor options
+org.eclipse.osgi/eclipseadaptor/debug = false
+org.eclipse.osgi/eclipseadaptor/debug/location = false
+org.eclipse.osgi/eclipseadaptor/debug/platformadmin=false
+org.eclipse.osgi/eclipseadaptor/debug/platformadmin/resolver=false
+org.eclipse.osgi/eclipseadaptor/converter/debug = false
+
+### OSGi resolver options
+# Turns on debugging for the resolver
+org.eclipse.osgi/resolver/debug = false
+# Prints out wiring information after the resolver has completed the resolve process
+org.eclipse.osgi/resolver/wiring = false
+# Prints out Import-Package information
+org.eclipse.osgi/resolver/imports = false
+# Prints out Require-Bundle information
+org.eclipse.osgi/resolver/requires = false
+# Prints out package grouping information form the "uses" clause
+org.eclipse.osgi/resolver/grouping = false
+# Prints out cycle information
+org.eclipse.osgi/resolver/cycles = false
+# Prints out Eclipse-GenericRequire information
+org.eclipse.osgi/resolver/generics = false
+
+#### Profile settings
+org.eclipse.osgi/profile/startup = false
+org.eclipse.osgi/profile/benchmark = false
+org.eclipse.osgi/profile/debug = false
+
+# Override the default implemenation
+org.eclipse.osgi/profile/impl = org.eclipse.osgi.internal.profile.DefaultProfileLogger
+
+# Append all profile messages to the filename specified
+org.eclipse.osgi/defaultprofile/logfilename =
+
+# Output all profile log messages synchronously to the jvm console.
+# By default, all log messages are cached until the log buffer is
+# requested.
+org.eclipse.osgi/defaultprofile/logsynchronously = false
+
+# Specify the size of the default profile implementation log buffer.
+org.eclipse.osgi/defaultprofile/buffersize = 256
+
+#### Monitoring settings
+# monitor class loading
+org.eclipse.osgi/monitor/classes=false
+
+# monitor bundle activation
+org.eclipse.osgi/monitor/activation=false
+
+# monitor resource bundle (*.properties) loading
+org.eclipse.osgi/monitor/resources=false
+
+
+#### Trace settings
+# trace class loading - snapshot the execution stack when a class is loaded
+org.eclipse.osgi/trace/classLoading=false
+
+# trace location - file in which execution traces are written
+org.eclipse.osgi/trace/filename=runtime.traces
+
+# trace filters - Java properties file defining which classes should
+# be traced (if trace/classLoading is true)
+# File format:
+# plugins=<comma separated list of plugins whose classes to trace>
+# packages=<comma separated list of package prefixes of classes to trace>
+# Note that there may be many 'plugins' and 'packages' lines in one file.
+org.eclipse.osgi/trace/filters=trace.properties
+
+# trace bundle activation - snapshot the execution stack when a bundle is activated
+org.eclipse.osgi/trace/activation=false
diff --git a/karaf/shell/dev/src/test/java/org/apache/felix/karaf/shell/dev/framework/EquinoxTest.java b/karaf/shell/dev/src/test/java/org/apache/felix/karaf/shell/dev/framework/EquinoxTest.java
new file mode 100644
index 0000000..85ea42c
--- /dev/null
+++ b/karaf/shell/dev/src/test/java/org/apache/felix/karaf/shell/dev/framework/EquinoxTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.apache.felix.karaf.shell.dev.framework;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.felix.karaf.shell.dev.util.IO;
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link org.apache.felix.karaf.shell.dev.framework.Equinox}
+ */
+public class EquinoxTest {
+
+ private File base;
+ private File etc;
+
+ private Equinox equinox;
+
+ @Before
+ public void setUp() {
+ // creating a dummy karaf instance folder
+ base = new File("target/instances/" + System.currentTimeMillis());
+ base.mkdirs();
+
+ // make sure the etc directory exists
+ etc = new File(base, "etc");
+ etc.mkdirs();
+
+ equinox = new Equinox(base);
+ }
+
+ @Test
+ public void enableDebug() throws IOException {
+ IO.copyTextToFile(
+ EquinoxTest.class.getResourceAsStream("config.properties"),
+ new File(etc, "config.properties"));
+
+ equinox.enableDebug(base);
+
+ Properties properties = new Properties();
+ properties.load(new FileInputStream(new File(base, "etc/config.properties")));
+ assertNotNull(properties.get("osgi.debug"));
+ assertEquals("etc/equinox-debug.properties", properties.get("osgi.debug"));
+
+ assertTrue("Should have created the default Equinox debug config file",
+ new File(etc, "equinox-debug.properties").exists());
+ }
+
+ @Test
+ public void testDisableDebug() throws IOException {
+ IO.copyTextToFile(
+ EquinoxTest.class.getResourceAsStream("enabled-config.properties"),
+ new File(etc, "config.properties"));
+
+ equinox.disableDebug(base);
+
+ Properties properties = new Properties();
+ properties.load(new FileInputStream(new File(etc, "config.properties")));
+ assertFalse("osgi.debug property should have been removed from the file",
+ properties.containsKey("osgi.debug"));
+ }
+}
diff --git a/karaf/shell/dev/src/test/java/org/apache/felix/karaf/shell/dev/framework/FelixTest.java b/karaf/shell/dev/src/test/java/org/apache/felix/karaf/shell/dev/framework/FelixTest.java
new file mode 100644
index 0000000..399777b
--- /dev/null
+++ b/karaf/shell/dev/src/test/java/org/apache/felix/karaf/shell/dev/framework/FelixTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.apache.felix.karaf.shell.dev.framework;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.felix.karaf.shell.dev.util.IO;
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link org.apache.felix.karaf.shell.dev.framework.Felix}
+ */
+public class FelixTest {
+
+ private File base;
+ private File etc;
+
+ private Felix felix;
+
+ @Before
+ public void setUp() {
+ // creating a dummy karaf instance folder
+ base = new File("target/instances/" + System.currentTimeMillis());
+ base.mkdirs();
+
+ // make sure the etc directory exists
+ etc = new File(base, "etc");
+ etc.mkdirs();
+
+ felix = new Felix(base);
+ }
+
+ @Test
+ public void enableDebug() throws IOException {
+ IO.copyTextToFile(
+ FelixTest.class.getResourceAsStream("config.properties"),
+ new File(etc, "config.properties"));
+
+ felix.enableDebug(base);
+
+ Properties properties = new Properties();
+ properties.load(new FileInputStream(new File(etc, "config.properties")));
+ assertNotNull(properties.get("felix.log.level"));
+ assertEquals("4", properties.get("felix.log.level"));
+ }
+
+ @Test
+ public void testDisableDebug() throws IOException {
+ IO.copyTextToFile(
+ FelixTest.class.getResourceAsStream("enabled-config.properties"),
+ new File(etc, "config.properties"));
+
+ felix.disableDebug(base);
+
+ Properties properties = new Properties();
+ properties.load(new FileInputStream(new File(etc, "config.properties")));
+ assertFalse(properties.containsKey("felix.log.level"));
+ }
+}
diff --git a/karaf/shell/dev/src/test/resources/org/apache/felix/karaf/shell/dev/framework/config.properties b/karaf/shell/dev/src/test/resources/org/apache/felix/karaf/shell/dev/framework/config.properties
new file mode 100644
index 0000000..5cc8009
--- /dev/null
+++ b/karaf/shell/dev/src/test/resources/org/apache/felix/karaf/shell/dev/framework/config.properties
@@ -0,0 +1,351 @@
+################################################################################
+#
+# 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.
+#
+################################################################################
+
+#
+# Framework selection properties
+#
+karaf.framework=felix
+
+karaf.framework.equinox=${karaf.default.repository}/org/eclipse/osgi/${equinox.version}/osgi-${equinox.version}.jar
+karaf.framework.felix=${karaf.default.repository}/org/apache/felix/org.apache.felix.framework/${felix.framework.version}/org.apache.felix.framework-${felix.framework.version}.jar
+
+#
+# Framework config properties.
+#
+org.osgi.framework.system.packages=org.osgi.framework; version=1.5.0, \
+ org.osgi.framework.launch; version=1.0.0, \
+ org.osgi.framework.hooks.service; version=1.0.0, \
+ org.osgi.service.packageadmin; version=1.2.0, \
+ org.osgi.service.startlevel; version=1.1.0, \
+ org.osgi.service.url; version=1.0.0, \
+ org.osgi.util.tracker; version=1.4.0 \
+ ${jre-${java.specification.version}}
+
+org.osgi.framework.system.packages.extra=\
+ org.apache.felix.karaf.jaas.boot; version=${karaf.osgi.version}, \
+ org.apache.felix.karaf.version; version=${karaf.osgi.version}
+
+# javax.transaction is needed to avoid class loader constraint violation when using javax.sql
+org.osgi.framework.bootdelegation=sun.*,com.sun.*,javax.transaction,javax.transaction.*
+
+# To enable the use of the startup.properties file to control the start level:
+karaf.auto.start=startup.properties
+#felix.auto.start=all
+
+org.osgi.framework.startlevel.beginning=100
+karaf.startlevel.bundle=60
+
+#
+# FileMonitor properties
+#
+felix.fileinstall.dir = ${karaf.base}/etc
+felix.fileinstall.filter = .*\\.cfg
+felix.fileinstall.poll = 1000
+felix.fileinstall.noInitialDelay = true
+
+#
+# Java platform package export properties.
+#
+
+# Standard package set. Note that:
+# - javax.transaction* is exported with a mandatory attribute
+jre-1.5=, \
+ javax.accessibility, \
+ javax.activity, \
+ javax.crypto, \
+ javax.crypto.interfaces, \
+ javax.crypto.spec, \
+ javax.imageio, \
+ javax.imageio.event, \
+ javax.imageio.metadata, \
+ javax.imageio.plugins.bmp, \
+ javax.imageio.plugins.jpeg, \
+ javax.imageio.spi, \
+ javax.imageio.stream, \
+ javax.management, \
+ javax.management.loading, \
+ javax.management.modelmbean, \
+ javax.management.monitor, \
+ javax.management.openmbean, \
+ javax.management.relation, \
+ javax.management.remote, \
+ javax.management.remote.rmi, \
+ javax.management.timer, \
+ javax.naming, \
+ javax.naming.directory, \
+ javax.naming.event, \
+ javax.naming.ldap, \
+ javax.naming.spi, \
+ javax.net, \
+ javax.net.ssl, \
+ javax.print, \
+ javax.print.attribute, \
+ javax.print.attribute.standard, \
+ javax.print.event, \
+ javax.rmi, \
+ javax.rmi.CORBA, \
+ javax.rmi.ssl, \
+ javax.security.auth, \
+ javax.security.auth.callback, \
+ javax.security.auth.kerberos, \
+ javax.security.auth.login, \
+ javax.security.auth.spi, \
+ javax.security.auth.x500, \
+ javax.security.cert, \
+ javax.security.sasl, \
+ javax.sound.midi, \
+ javax.sound.midi.spi, \
+ javax.sound.sampled, \
+ javax.sound.sampled.spi, \
+ javax.sql, \
+ javax.sql.rowset, \
+ javax.sql.rowset.serial, \
+ javax.sql.rowset.spi, \
+ javax.swing, \
+ javax.swing.border, \
+ javax.swing.colorchooser, \
+ javax.swing.event, \
+ javax.swing.filechooser, \
+ javax.swing.plaf, \
+ javax.swing.plaf.basic, \
+ javax.swing.plaf.metal, \
+ javax.swing.plaf.multi, \
+ javax.swing.plaf.synth, \
+ javax.swing.table, \
+ javax.swing.text, \
+ javax.swing.text.html, \
+ javax.swing.text.html.parser, \
+ javax.swing.text.rtf, \
+ javax.swing.tree, \
+ javax.swing.undo, \
+ javax.transaction; javax.transaction.xa; partial=true; mandatory:=partial, \
+ javax.xml, \
+ javax.xml.datatype, \
+ javax.xml.namespace, \
+ javax.xml.parsers, \
+ javax.xml.transform, \
+ javax.xml.transform.dom, \
+ javax.xml.transform.sax, \
+ javax.xml.transform.stream, \
+ javax.xml.validation, \
+ javax.xml.xpath, \
+ org.ietf.jgss, \
+ org.omg.CORBA, \
+ org.omg.CORBA_2_3, \
+ org.omg.CORBA_2_3.portable, \
+ org.omg.CORBA.DynAnyPackage, \
+ org.omg.CORBA.ORBPackage, \
+ org.omg.CORBA.portable, \
+ org.omg.CORBA.TypeCodePackage, \
+ org.omg.CosNaming, \
+ org.omg.CosNaming.NamingContextExtPackage, \
+ org.omg.CosNaming.NamingContextPackage, \
+ org.omg.Dynamic, \
+ org.omg.DynamicAny, \
+ org.omg.DynamicAny.DynAnyFactoryPackage, \
+ org.omg.DynamicAny.DynAnyPackage, \
+ org.omg.IOP, \
+ org.omg.IOP.CodecFactoryPackage, \
+ org.omg.IOP.CodecPackage, \
+ org.omg.Messaging, \
+ org.omg.PortableInterceptor, \
+ org.omg.PortableInterceptor.ORBInitInfoPackage, \
+ org.omg.PortableServer, \
+ org.omg.PortableServer.CurrentPackage, \
+ org.omg.PortableServer.POAManagerPackage, \
+ org.omg.PortableServer.POAPackage, \
+ org.omg.PortableServer.portable, \
+ org.omg.PortableServer.ServantLocatorPackage, \
+ org.omg.SendingContext, \
+ org.omg.stub.java.rmi, \
+ org.omg.stub.javax.management.remote.rmi, \
+ org.w3c.dom, \
+ org.w3c.dom.bootstrap, \
+ org.w3c.dom.css, \
+ org.w3c.dom.events, \
+ org.w3c.dom.html, \
+ org.w3c.dom.ls, \
+ org.w3c.dom.ranges, \
+ org.w3c.dom.stylesheets, \
+ org.w3c.dom.traversal, \
+ org.w3c.dom.views, \
+ org.xml.sax, \
+ org.xml.sax.ext, \
+ org.xml.sax.helpers
+
+# Standard package set. Note that:
+# - javax.transaction* is exported with a mandatory attribute
+jre-1.6=, \
+ javax.accessibility, \
+ javax.activation, \
+ javax.activity, \
+ javax.annotation, \
+ javax.annotation.processing, \
+ javax.crypto, \
+ javax.crypto.interfaces, \
+ javax.crypto.spec, \
+ javax.imageio, \
+ javax.imageio.event, \
+ javax.imageio.metadata, \
+ javax.imageio.plugins.bmp, \
+ javax.imageio.plugins.jpeg, \
+ javax.imageio.spi, \
+ javax.imageio.stream, \
+ javax.jws, \
+ javax.jws.soap, \
+ javax.lang.model, \
+ javax.lang.model.element, \
+ javax.lang.model.type, \
+ javax.lang.model.util, \
+ javax.management, \
+ javax.management.loading, \
+ javax.management.modelmbean, \
+ javax.management.monitor, \
+ javax.management.openmbean, \
+ javax.management.relation, \
+ javax.management.remote, \
+ javax.management.remote.rmi, \
+ javax.management.timer, \
+ javax.naming, \
+ javax.naming.directory, \
+ javax.naming.event, \
+ javax.naming.ldap, \
+ javax.naming.spi, \
+ javax.net, \
+ javax.net.ssl, \
+ javax.print, \
+ javax.print.attribute, \
+ javax.print.attribute.standard, \
+ javax.print.event, \
+ javax.rmi, \
+ javax.rmi.CORBA, \
+ javax.rmi.ssl, \
+ javax.script, \
+ javax.security.auth, \
+ javax.security.auth.callback, \
+ javax.security.auth.kerberos, \
+ javax.security.auth.login, \
+ javax.security.auth.spi, \
+ javax.security.auth.x500, \
+ javax.security.cert, \
+ javax.security.sasl, \
+ javax.sound.midi, \
+ javax.sound.midi.spi, \
+ javax.sound.sampled, \
+ javax.sound.sampled.spi, \
+ javax.sql, \
+ javax.sql.rowset, \
+ javax.sql.rowset.serial, \
+ javax.sql.rowset.spi, \
+ javax.swing, \
+ javax.swing.border, \
+ javax.swing.colorchooser, \
+ javax.swing.event, \
+ javax.swing.filechooser, \
+ javax.swing.plaf, \
+ javax.swing.plaf.basic, \
+ javax.swing.plaf.metal, \
+ javax.swing.plaf.multi, \
+ javax.swing.plaf.synth, \
+ javax.swing.table, \
+ javax.swing.text, \
+ javax.swing.text.html, \
+ javax.swing.text.html.parser, \
+ javax.swing.text.rtf, \
+ javax.swing.tree, \
+ javax.swing.undo, \
+ javax.tools, \
+ javax.transaction; javax.transaction.xa; partial=true; mandatory:=partial, \
+ javax.xml, \
+ javax.xml.bind, \
+ javax.xml.bind.annotation, \
+ javax.xml.bind.annotation.adapters, \
+ javax.xml.bind.attachment, \
+ javax.xml.bind.helpers, \
+ javax.xml.bind.util, \
+ javax.xml.crypto, \
+ javax.xml.crypto.dom, \
+ javax.xml.crypto.dsig, \
+ javax.xml.crypto.dsig.dom, \
+ javax.xml.crypto.dsig.keyinfo, \
+ javax.xml.crypto.dsig.spec, \
+ javax.xml.datatype, \
+ javax.xml.namespace, \
+ javax.xml.parsers, \
+ javax.xml.soap, \
+ javax.xml.stream, \
+ javax.xml.stream.events, \
+ javax.xml.stream.util, \
+ javax.xml.transform, \
+ javax.xml.transform.dom, \
+ javax.xml.transform.sax, \
+ javax.xml.transform.stax, \
+ javax.xml.transform.stream, \
+ javax.xml.validation, \
+ javax.xml.ws, \
+ javax.xml.ws.handler, \
+ javax.xml.ws.handler.soap, \
+ javax.xml.ws.http, \
+ javax.xml.ws.soap, \
+ javax.xml.ws.spi, \
+ javax.xml.xpath, \
+ org.ietf.jgss, \
+ org.omg.CORBA, \
+ org.omg.CORBA_2_3, \
+ org.omg.CORBA_2_3.portable, \
+ org.omg.CORBA.DynAnyPackage, \
+ org.omg.CORBA.ORBPackage, \
+ org.omg.CORBA.portable, \
+ org.omg.CORBA.TypeCodePackage, \
+ org.omg.CosNaming, \
+ org.omg.CosNaming.NamingContextExtPackage, \
+ org.omg.CosNaming.NamingContextPackage, \
+ org.omg.Dynamic, \
+ org.omg.DynamicAny, \
+ org.omg.DynamicAny.DynAnyFactoryPackage, \
+ org.omg.DynamicAny.DynAnyPackage, \
+ org.omg.IOP, \
+ org.omg.IOP.CodecFactoryPackage, \
+ org.omg.IOP.CodecPackage, \
+ org.omg.Messaging, \
+ org.omg.PortableInterceptor, \
+ org.omg.PortableInterceptor.ORBInitInfoPackage, \
+ org.omg.PortableServer, \
+ org.omg.PortableServer.CurrentPackage, \
+ org.omg.PortableServer.POAManagerPackage, \
+ org.omg.PortableServer.POAPackage, \
+ org.omg.PortableServer.portable, \
+ org.omg.PortableServer.ServantLocatorPackage, \
+ org.omg.SendingContext, \
+ org.omg.stub.java.rmi, \
+ org.omg.stub.javax.management.remote.rmi, \
+ org.w3c.dom, \
+ org.w3c.dom.bootstrap, \
+ org.w3c.dom.css, \
+ org.w3c.dom.events, \
+ org.w3c.dom.html, \
+ org.w3c.dom.ls, \
+ org.w3c.dom.ranges, \
+ org.w3c.dom.stylesheets, \
+ org.w3c.dom.traversal, \
+ org.w3c.dom.views, \
+ org.w3c.dom.xpath, \
+ org.xml.sax, \
+ org.xml.sax.ext, \
+ org.xml.sax.helpers
diff --git a/karaf/shell/dev/src/test/resources/org/apache/felix/karaf/shell/dev/framework/enabled-config.properties b/karaf/shell/dev/src/test/resources/org/apache/felix/karaf/shell/dev/framework/enabled-config.properties
new file mode 100644
index 0000000..53c4eca
--- /dev/null
+++ b/karaf/shell/dev/src/test/resources/org/apache/felix/karaf/shell/dev/framework/enabled-config.properties
@@ -0,0 +1,355 @@
+################################################################################
+#
+# 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.
+#
+################################################################################
+
+#
+# Framework selection properties
+#
+karaf.framework=felix
+
+karaf.framework.equinox=${karaf.default.repository}/org/eclipse/osgi/${equinox.version}/osgi-${equinox.version}.jar
+karaf.framework.felix=${karaf.default.repository}/org/apache/felix/org.apache.felix.framework/${felix.framework.version}/org.apache.felix.framework-${felix.framework.version}.jar
+
+# Here are the properties to enable debugging
+felix.log.level=4
+osgi.debug=etc/equinox-debug.properties
+
+#
+# Framework config properties.
+#
+org.osgi.framework.system.packages=org.osgi.framework; version=1.5.0, \
+ org.osgi.framework.launch; version=1.0.0, \
+ org.osgi.framework.hooks.service; version=1.0.0, \
+ org.osgi.service.packageadmin; version=1.2.0, \
+ org.osgi.service.startlevel; version=1.1.0, \
+ org.osgi.service.url; version=1.0.0, \
+ org.osgi.util.tracker; version=1.4.0 \
+ ${jre-${java.specification.version}}
+
+org.osgi.framework.system.packages.extra=\
+ org.apache.felix.karaf.jaas.boot; version=${karaf.osgi.version}, \
+ org.apache.felix.karaf.version; version=${karaf.osgi.version}
+
+# javax.transaction is needed to avoid class loader constraint violation when using javax.sql
+org.osgi.framework.bootdelegation=sun.*,com.sun.*,javax.transaction,javax.transaction.*
+
+# To enable the use of the startup.properties file to control the start level:
+karaf.auto.start=startup.properties
+#felix.auto.start=all
+
+org.osgi.framework.startlevel.beginning=100
+karaf.startlevel.bundle=60
+
+#
+# FileMonitor properties
+#
+felix.fileinstall.dir = ${karaf.base}/etc
+felix.fileinstall.filter = .*\\.cfg
+felix.fileinstall.poll = 1000
+felix.fileinstall.noInitialDelay = true
+
+#
+# Java platform package export properties.
+#
+
+# Standard package set. Note that:
+# - javax.transaction* is exported with a mandatory attribute
+jre-1.5=, \
+ javax.accessibility, \
+ javax.activity, \
+ javax.crypto, \
+ javax.crypto.interfaces, \
+ javax.crypto.spec, \
+ javax.imageio, \
+ javax.imageio.event, \
+ javax.imageio.metadata, \
+ javax.imageio.plugins.bmp, \
+ javax.imageio.plugins.jpeg, \
+ javax.imageio.spi, \
+ javax.imageio.stream, \
+ javax.management, \
+ javax.management.loading, \
+ javax.management.modelmbean, \
+ javax.management.monitor, \
+ javax.management.openmbean, \
+ javax.management.relation, \
+ javax.management.remote, \
+ javax.management.remote.rmi, \
+ javax.management.timer, \
+ javax.naming, \
+ javax.naming.directory, \
+ javax.naming.event, \
+ javax.naming.ldap, \
+ javax.naming.spi, \
+ javax.net, \
+ javax.net.ssl, \
+ javax.print, \
+ javax.print.attribute, \
+ javax.print.attribute.standard, \
+ javax.print.event, \
+ javax.rmi, \
+ javax.rmi.CORBA, \
+ javax.rmi.ssl, \
+ javax.security.auth, \
+ javax.security.auth.callback, \
+ javax.security.auth.kerberos, \
+ javax.security.auth.login, \
+ javax.security.auth.spi, \
+ javax.security.auth.x500, \
+ javax.security.cert, \
+ javax.security.sasl, \
+ javax.sound.midi, \
+ javax.sound.midi.spi, \
+ javax.sound.sampled, \
+ javax.sound.sampled.spi, \
+ javax.sql, \
+ javax.sql.rowset, \
+ javax.sql.rowset.serial, \
+ javax.sql.rowset.spi, \
+ javax.swing, \
+ javax.swing.border, \
+ javax.swing.colorchooser, \
+ javax.swing.event, \
+ javax.swing.filechooser, \
+ javax.swing.plaf, \
+ javax.swing.plaf.basic, \
+ javax.swing.plaf.metal, \
+ javax.swing.plaf.multi, \
+ javax.swing.plaf.synth, \
+ javax.swing.table, \
+ javax.swing.text, \
+ javax.swing.text.html, \
+ javax.swing.text.html.parser, \
+ javax.swing.text.rtf, \
+ javax.swing.tree, \
+ javax.swing.undo, \
+ javax.transaction; javax.transaction.xa; partial=true; mandatory:=partial, \
+ javax.xml, \
+ javax.xml.datatype, \
+ javax.xml.namespace, \
+ javax.xml.parsers, \
+ javax.xml.transform, \
+ javax.xml.transform.dom, \
+ javax.xml.transform.sax, \
+ javax.xml.transform.stream, \
+ javax.xml.validation, \
+ javax.xml.xpath, \
+ org.ietf.jgss, \
+ org.omg.CORBA, \
+ org.omg.CORBA_2_3, \
+ org.omg.CORBA_2_3.portable, \
+ org.omg.CORBA.DynAnyPackage, \
+ org.omg.CORBA.ORBPackage, \
+ org.omg.CORBA.portable, \
+ org.omg.CORBA.TypeCodePackage, \
+ org.omg.CosNaming, \
+ org.omg.CosNaming.NamingContextExtPackage, \
+ org.omg.CosNaming.NamingContextPackage, \
+ org.omg.Dynamic, \
+ org.omg.DynamicAny, \
+ org.omg.DynamicAny.DynAnyFactoryPackage, \
+ org.omg.DynamicAny.DynAnyPackage, \
+ org.omg.IOP, \
+ org.omg.IOP.CodecFactoryPackage, \
+ org.omg.IOP.CodecPackage, \
+ org.omg.Messaging, \
+ org.omg.PortableInterceptor, \
+ org.omg.PortableInterceptor.ORBInitInfoPackage, \
+ org.omg.PortableServer, \
+ org.omg.PortableServer.CurrentPackage, \
+ org.omg.PortableServer.POAManagerPackage, \
+ org.omg.PortableServer.POAPackage, \
+ org.omg.PortableServer.portable, \
+ org.omg.PortableServer.ServantLocatorPackage, \
+ org.omg.SendingContext, \
+ org.omg.stub.java.rmi, \
+ org.omg.stub.javax.management.remote.rmi, \
+ org.w3c.dom, \
+ org.w3c.dom.bootstrap, \
+ org.w3c.dom.css, \
+ org.w3c.dom.events, \
+ org.w3c.dom.html, \
+ org.w3c.dom.ls, \
+ org.w3c.dom.ranges, \
+ org.w3c.dom.stylesheets, \
+ org.w3c.dom.traversal, \
+ org.w3c.dom.views, \
+ org.xml.sax, \
+ org.xml.sax.ext, \
+ org.xml.sax.helpers
+
+# Standard package set. Note that:
+# - javax.transaction* is exported with a mandatory attribute
+jre-1.6=, \
+ javax.accessibility, \
+ javax.activation, \
+ javax.activity, \
+ javax.annotation, \
+ javax.annotation.processing, \
+ javax.crypto, \
+ javax.crypto.interfaces, \
+ javax.crypto.spec, \
+ javax.imageio, \
+ javax.imageio.event, \
+ javax.imageio.metadata, \
+ javax.imageio.plugins.bmp, \
+ javax.imageio.plugins.jpeg, \
+ javax.imageio.spi, \
+ javax.imageio.stream, \
+ javax.jws, \
+ javax.jws.soap, \
+ javax.lang.model, \
+ javax.lang.model.element, \
+ javax.lang.model.type, \
+ javax.lang.model.util, \
+ javax.management, \
+ javax.management.loading, \
+ javax.management.modelmbean, \
+ javax.management.monitor, \
+ javax.management.openmbean, \
+ javax.management.relation, \
+ javax.management.remote, \
+ javax.management.remote.rmi, \
+ javax.management.timer, \
+ javax.naming, \
+ javax.naming.directory, \
+ javax.naming.event, \
+ javax.naming.ldap, \
+ javax.naming.spi, \
+ javax.net, \
+ javax.net.ssl, \
+ javax.print, \
+ javax.print.attribute, \
+ javax.print.attribute.standard, \
+ javax.print.event, \
+ javax.rmi, \
+ javax.rmi.CORBA, \
+ javax.rmi.ssl, \
+ javax.script, \
+ javax.security.auth, \
+ javax.security.auth.callback, \
+ javax.security.auth.kerberos, \
+ javax.security.auth.login, \
+ javax.security.auth.spi, \
+ javax.security.auth.x500, \
+ javax.security.cert, \
+ javax.security.sasl, \
+ javax.sound.midi, \
+ javax.sound.midi.spi, \
+ javax.sound.sampled, \
+ javax.sound.sampled.spi, \
+ javax.sql, \
+ javax.sql.rowset, \
+ javax.sql.rowset.serial, \
+ javax.sql.rowset.spi, \
+ javax.swing, \
+ javax.swing.border, \
+ javax.swing.colorchooser, \
+ javax.swing.event, \
+ javax.swing.filechooser, \
+ javax.swing.plaf, \
+ javax.swing.plaf.basic, \
+ javax.swing.plaf.metal, \
+ javax.swing.plaf.multi, \
+ javax.swing.plaf.synth, \
+ javax.swing.table, \
+ javax.swing.text, \
+ javax.swing.text.html, \
+ javax.swing.text.html.parser, \
+ javax.swing.text.rtf, \
+ javax.swing.tree, \
+ javax.swing.undo, \
+ javax.tools, \
+ javax.transaction; javax.transaction.xa; partial=true; mandatory:=partial, \
+ javax.xml, \
+ javax.xml.bind, \
+ javax.xml.bind.annotation, \
+ javax.xml.bind.annotation.adapters, \
+ javax.xml.bind.attachment, \
+ javax.xml.bind.helpers, \
+ javax.xml.bind.util, \
+ javax.xml.crypto, \
+ javax.xml.crypto.dom, \
+ javax.xml.crypto.dsig, \
+ javax.xml.crypto.dsig.dom, \
+ javax.xml.crypto.dsig.keyinfo, \
+ javax.xml.crypto.dsig.spec, \
+ javax.xml.datatype, \
+ javax.xml.namespace, \
+ javax.xml.parsers, \
+ javax.xml.soap, \
+ javax.xml.stream, \
+ javax.xml.stream.events, \
+ javax.xml.stream.util, \
+ javax.xml.transform, \
+ javax.xml.transform.dom, \
+ javax.xml.transform.sax, \
+ javax.xml.transform.stax, \
+ javax.xml.transform.stream, \
+ javax.xml.validation, \
+ javax.xml.ws, \
+ javax.xml.ws.handler, \
+ javax.xml.ws.handler.soap, \
+ javax.xml.ws.http, \
+ javax.xml.ws.soap, \
+ javax.xml.ws.spi, \
+ javax.xml.xpath, \
+ org.ietf.jgss, \
+ org.omg.CORBA, \
+ org.omg.CORBA_2_3, \
+ org.omg.CORBA_2_3.portable, \
+ org.omg.CORBA.DynAnyPackage, \
+ org.omg.CORBA.ORBPackage, \
+ org.omg.CORBA.portable, \
+ org.omg.CORBA.TypeCodePackage, \
+ org.omg.CosNaming, \
+ org.omg.CosNaming.NamingContextExtPackage, \
+ org.omg.CosNaming.NamingContextPackage, \
+ org.omg.Dynamic, \
+ org.omg.DynamicAny, \
+ org.omg.DynamicAny.DynAnyFactoryPackage, \
+ org.omg.DynamicAny.DynAnyPackage, \
+ org.omg.IOP, \
+ org.omg.IOP.CodecFactoryPackage, \
+ org.omg.IOP.CodecPackage, \
+ org.omg.Messaging, \
+ org.omg.PortableInterceptor, \
+ org.omg.PortableInterceptor.ORBInitInfoPackage, \
+ org.omg.PortableServer, \
+ org.omg.PortableServer.CurrentPackage, \
+ org.omg.PortableServer.POAManagerPackage, \
+ org.omg.PortableServer.POAPackage, \
+ org.omg.PortableServer.portable, \
+ org.omg.PortableServer.ServantLocatorPackage, \
+ org.omg.SendingContext, \
+ org.omg.stub.java.rmi, \
+ org.omg.stub.javax.management.remote.rmi, \
+ org.w3c.dom, \
+ org.w3c.dom.bootstrap, \
+ org.w3c.dom.css, \
+ org.w3c.dom.events, \
+ org.w3c.dom.html, \
+ org.w3c.dom.ls, \
+ org.w3c.dom.ranges, \
+ org.w3c.dom.stylesheets, \
+ org.w3c.dom.traversal, \
+ org.w3c.dom.views, \
+ org.w3c.dom.xpath, \
+ org.xml.sax, \
+ org.xml.sax.ext, \
+ org.xml.sax.helpers