You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by cs...@apache.org on 2012/04/05 17:21:57 UTC

svn commit: r1309898 [2/2] - in /karaf/trunk: ./ assemblies/features/framework/src/main/resources/resources/etc/ assemblies/features/standard/src/main/feature/ dev/ dev/command/ dev/command/src/main/java/org/apache/karaf/dev/ dev/command/src/main/java/...

Added: karaf/trunk/dev/core/src/main/java/org/apache/karaf/dev/core/internal/DevServiceImpl.java
URL: http://svn.apache.org/viewvc/karaf/trunk/dev/core/src/main/java/org/apache/karaf/dev/core/internal/DevServiceImpl.java?rev=1309898&view=auto
==============================================================================
--- karaf/trunk/dev/core/src/main/java/org/apache/karaf/dev/core/internal/DevServiceImpl.java (added)
+++ karaf/trunk/dev/core/src/main/java/org/apache/karaf/dev/core/internal/DevServiceImpl.java Thu Apr  5 15:21:55 2012
@@ -0,0 +1,221 @@
+/*
+ * 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.apache.karaf.dev.core.internal;
+
+import static java.lang.String.format;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.utils.properties.Properties;
+import org.apache.karaf.dev.core.DevService;
+import org.apache.karaf.dev.core.FrameworkType;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleRevisions;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.framework.wiring.FrameworkWiring;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DevServiceImpl implements DevService {
+    private static Logger LOG = LoggerFactory.getLogger(DevServiceImpl.class);
+    /**
+     * The header key where we store the active wires when we enable DynamicImport=*
+     */
+    private static final String ORIGINAL_WIRES = "Original-Wires";
+
+    private BundleContext bundleContext;
+
+    public DevServiceImpl(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    public FrameworkType getFramework() {
+        if (bundleContext.getBundle(0).getSymbolicName().contains("felix")) {
+            return FrameworkType.felix;
+        } else {
+            return FrameworkType.equinox;
+        }
+    }
+
+    private Properties loadProps() throws IOException {
+        return new Properties(new File(System.getProperty("karaf.base"), "etc/config.properties"));
+    }
+
+    public void setFramework(FrameworkType framework) {
+        if (framework == null) {
+            return;
+        }
+        try {
+            Properties properties = loadProps();
+            properties.put("karaf.framework", framework.name());
+            properties.save();
+        } catch (IOException e) {
+            throw new RuntimeException("Error settting framework: " + e.getMessage(), e);
+        }
+    }
+
+    public void setFrameworkDebug(boolean debug) {
+        try {
+            Properties properties = loadProps();
+            if (debug) {
+                properties.put("felix.log.level", "4");
+                properties.put("osgi.debug", "etc/equinox-debug.properties");
+            } else {
+                properties.remove("felix.log.level");
+                properties.remove("osgi.debug");
+            }
+            // TODO populate the equinox-debug.properties file with the one provided in shell/dev module
+            properties.save();
+        } catch (IOException e) {
+            throw new RuntimeException("Error settting framework debugging: " + e.getMessage(), e);
+        }
+    }
+
+    public void restart(boolean clean) {
+        System.setProperty("karaf.restart", "true");
+        System.setProperty("karaf.restart.clean", Boolean.toString(clean));
+        try {
+            bundleContext.getBundle(0).stop();
+        } catch (BundleException e) {
+            throw new RuntimeException("Error stopping framework bundle: " + e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public String setSystemProperty(String key, String value, boolean persist) {
+        if (persist) {
+            try {
+                String base = System.getProperty("karaf.base");
+                Properties props = new Properties(new File(base, "etc/system.properties"));
+                props.put(key, value);
+                props.save();
+            } catch (IOException e) {
+                throw new RuntimeException("Error persisting system property", e);
+            }
+        }
+        return System.setProperty(key, value);
+    }
+    
+    /*
+     * Enable DynamicImport=* on the bundle
+     */
+    public void enableDynamicImports(Bundle bundle) {
+        String location =
+                String.format("wrap:%s$" +
+                        "Bundle-UpdateLocation=%s&" +
+                        "DynamicImport-Package=*&" +
+                        "%s=%s&" +
+                        "overwrite=merge",
+                        bundle.getLocation(),
+                        bundle.getLocation(),
+                        ORIGINAL_WIRES,
+                        explode(getWiredBundles(bundle).keySet()));
+        LOG.debug(format("Updating %s with URL %s", bundle, location));
+
+        try {
+            URL url = new URL(location);
+            bundle.update(url.openStream());
+            bundleContext.getBundle(0).adapt(FrameworkWiring.class).refreshBundles(Collections.singleton(bundle));
+        } catch (Exception e) {
+            throw new RuntimeException("Error enabling dynamic imports on bundle" + bundle.getBundleId(), e);
+        }
+    }
+
+    /*
+     * Disable DynamicImport=* on the bundle
+     *
+     * At this time, we will also calculate the difference in package wiring for the bundle compared to
+     * when we enabled the DynamicImport
+     */
+    public void disableDynamicImports(Bundle bundle) {
+        Set<String> current = getWiredBundles(bundle).keySet();
+        for (String original : bundle.getHeaders().get(ORIGINAL_WIRES).toString().split(",")) {
+            current.remove(original);
+        }
+
+        if (current.isEmpty()) {
+            LOG.debug("No additional packages have been wired since dynamic import was enabled");
+        } else {
+            LOG.debug("Additional packages wired since dynamic import was enabled");
+            for (String pkg : current) {
+                LOG.debug("- " + pkg);
+            }
+        }
+
+        try {
+            bundle.update();
+        } catch (BundleException e) {
+            throw new RuntimeException("Error disabling dynamic imports on bundle" + bundle.getBundleId(), e);
+        }
+    }
+    
+    /*
+     * Explode a set of string values in to a ,-delimited string
+     */
+    private String explode(Set<String> set) {
+        StringBuffer result = new StringBuffer();
+        Iterator<String> it = set.iterator();
+        while (it.hasNext()) {
+            result.append(it.next());
+            if (it.hasNext()) {
+                result.append(",");
+            }
+        }
+        if (result.length() == 0) {
+            return "--none--";
+        }
+        return result.toString();
+    }
+    
+    /*
+     * Get the list of bundles from which the given bundle imports packages
+     */
+    public Map<String, Bundle> getWiredBundles(Bundle bundle) {
+        // the set of bundles from which the bundle imports packages
+        Map<String, Bundle> exporters = new HashMap<String, Bundle>();
+
+        for (BundleRevision revision : bundle.adapt(BundleRevisions.class).getRevisions()) {
+            BundleWiring wiring = revision.getWiring();
+            if (wiring != null) {
+                List<BundleWire> wires = wiring.getRequiredWires(BundleRevision.PACKAGE_NAMESPACE);
+                if (wires != null) {
+                    for (BundleWire wire : wires) {
+                        if (wire.getProviderWiring().getBundle().getBundleId() != 0) {
+                            exporters.put(wire.getCapability().getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).toString(),
+                                          wire.getProviderWiring().getBundle());
+                        }
+                    }
+                }
+            }
+        }
+        return exporters;
+    }
+
+    @Override
+    public boolean isDynamicImport(Bundle bundle) {
+        return bundle.getHeaders().get(ORIGINAL_WIRES) != null;
+    }
+}

Copied: karaf/trunk/dev/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml (from r1309676, karaf/trunk/management/mbeans/dev/src/main/resources/OSGI-INF/blueprint/dev-management.xml)
URL: http://svn.apache.org/viewvc/karaf/trunk/dev/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml?p2=karaf/trunk/dev/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml&p1=karaf/trunk/management/mbeans/dev/src/main/resources/OSGI-INF/blueprint/dev-management.xml&r1=1309676&r2=1309898&rev=1309898&view=diff
==============================================================================
--- karaf/trunk/management/mbeans/dev/src/main/resources/OSGI-INF/blueprint/dev-management.xml (original)
+++ karaf/trunk/dev/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml Thu Apr  5 15:21:55 2012
@@ -12,25 +12,36 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+    xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
+    xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
 
-    <!-- Reference to the MBean server -->
-    <reference id="mbeanServer" interface="javax.management.MBeanServer">
-        <reference-listener ref="mbeanRegistrer" bind-method="registerMBeanServer" unbind-method="unregisterMBeanServer"/>
-    </reference>
-
-    <!-- Dev MBean -->
-    <bean id="devMBean" class="org.apache.karaf.management.mbeans.dev.internal.DevMBeanImpl">
-        <property name="bundleContext" ref="blueprintBundleContext"/>
+    <ext:property-placeholder />
+
+    <reference id="configurationAdmin" interface="org.osgi.service.cm.ConfigurationAdmin"/>
+    <reference id="packageAdmin" interface="org.osgi.service.packageadmin.PackageAdmin"/>
+
+    <bean id="watcher" class="org.apache.karaf.dev.core.internal.BundleWatcherImpl" init-method="start" destroy-method="stop">
+        <argument ref="blueprintBundleContext"/>
+        <argument ref="configurationAdmin"/>
+        <argument ref="packageAdmin"/>
+    </bean>
+    
+    <service ref="watcher" interface="org.apache.karaf.dev.core.BundleWatcher"/>
+
+    <bean id="devService" class="org.apache.karaf.dev.core.internal.DevServiceImpl">
+        <argument ref="blueprintBundleContext"/>
     </bean>
 
-    <!-- Register Dev MBean in the MBean Server -->
-    <bean id="mbeanRegistrer" class="org.apache.karaf.management.MBeanRegistrer">
-        <property name="mbeans">
-            <map>
-                <entry value="org.apache.karaf:type=dev,name=${karaf.name}" key-ref="devMBean"/>
-            </map>
-        </property>
+    <bean id="devMBean" class="org.apache.karaf.dev.core.internal.Dev">
+        <argument ref="devService" />
     </bean>
+    
+    <service ref="devService" interface="org.apache.karaf.dev.core.DevService" />
 
-</blueprint>
\ No newline at end of file
+    <service ref="devMBean" auto-export="interfaces">
+        <service-properties>
+            <entry key="jmx.objectname" value="org.apache.karaf:type=dev,name=${karaf.name}"/>
+        </service-properties>
+    </service>
+</blueprint>

Modified: karaf/trunk/dev/core/src/main/resources/OSGI-INF/bundle.info
URL: http://svn.apache.org/viewvc/karaf/trunk/dev/core/src/main/resources/OSGI-INF/bundle.info?rev=1309898&r1=1309676&r2=1309898&view=diff
==============================================================================
--- karaf/trunk/dev/core/src/main/resources/OSGI-INF/bundle.info (original)
+++ karaf/trunk/dev/core/src/main/resources/OSGI-INF/bundle.info Thu Apr  5 15:21:55 2012
@@ -9,7 +9,7 @@ Maven URL:
 
 h1. Description
 
-The dev mbean management bundle exposes a Dev MBean that can be used with any JMX client (for instance JConsole).
+Core services and mbeans for developers.
 
 The dev MBean allows quite the same actions that can be performed using dev:* commands:
   * framework()

Added: karaf/trunk/dev/pom.xml
URL: http://svn.apache.org/viewvc/karaf/trunk/dev/pom.xml?rev=1309898&view=auto
==============================================================================
--- karaf/trunk/dev/pom.xml (added)
+++ karaf/trunk/dev/pom.xml Thu Apr  5 15:21:55 2012
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.karaf</groupId>
+        <artifactId>karaf</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.apache.karaf.dev</groupId>
+    <artifactId>dev</artifactId>
+    <packaging>pom</packaging>
+    <name>Apache Karaf :: Dev</name>
+
+    <modules>
+        <module>core</module>
+        <module>command</module>
+    </modules>
+
+</project>
\ No newline at end of file

Modified: karaf/trunk/management/mbeans/pom.xml
URL: http://svn.apache.org/viewvc/karaf/trunk/management/mbeans/pom.xml?rev=1309898&r1=1309897&r2=1309898&view=diff
==============================================================================
--- karaf/trunk/management/mbeans/pom.xml (original)
+++ karaf/trunk/management/mbeans/pom.xml Thu Apr  5 15:21:55 2012
@@ -34,7 +34,6 @@
     <name>Apache Karaf :: Management :: MBeans</name>
 
     <modules>
-        <module>dev</module>
         <module>obr</module>
     </modules>
 

Modified: karaf/trunk/pom.xml
URL: http://svn.apache.org/viewvc/karaf/trunk/pom.xml?rev=1309898&r1=1309897&r2=1309898&view=diff
==============================================================================
--- karaf/trunk/pom.xml (original)
+++ karaf/trunk/pom.xml Thu Apr  5 15:21:55 2012
@@ -386,6 +386,17 @@
             </dependency>
 
             <dependency>
+                <groupId>org.apache.karaf.dev</groupId>
+                <artifactId>org.apache.karaf.dev.core</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.karaf.dev</groupId>
+                <artifactId>org.apache.karaf.dev.command</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <dependency>
                 <groupId>org.apache.karaf.log</groupId>
                 <artifactId>org.apache.karaf.log.core</artifactId>
                 <version>${project.version}</version>
@@ -456,11 +467,6 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.karaf.management.mbeans</groupId>
-                <artifactId>org.apache.karaf.management.mbeans.dev</artifactId>
-                <version>${project.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.apache.karaf.management.mbeans</groupId>
                 <artifactId>org.apache.karaf.management.mbeans.log</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -619,11 +625,6 @@
                 <artifactId>org.apache.karaf.shell.commands</artifactId>
                 <version>${project.version}</version>
             </dependency>
-            <dependency>
-                <groupId>org.apache.karaf.shell</groupId>
-                <artifactId>org.apache.karaf.shell.dev</artifactId>
-                <version>${project.version}</version>
-            </dependency>
 
             <dependency>
                 <groupId>org.apache.karaf.jaas</groupId>

Modified: karaf/trunk/shell/pom.xml
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/pom.xml?rev=1309898&r1=1309897&r2=1309898&view=diff
==============================================================================
--- karaf/trunk/shell/pom.xml (original)
+++ karaf/trunk/shell/pom.xml Thu Apr  5 15:21:55 2012
@@ -36,7 +36,6 @@
     <modules>
         <module>commands</module>
         <module>console</module>
-        <module>dev</module>
         <module>obr</module>
         <module>ssh</module>
     </modules>