Repository: karaf
Updated Branches:
  refs/heads/karaf-2.x 4fd235fd0 -> c3fb61914


http://git-wip-us.apache.org/repos/asf/karaf/blob/c3fb6191/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/EnvironmentDumpProvider.java
----------------------------------------------------------------------
diff --git 
a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/EnvironmentDumpProvider.java
 
b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/EnvironmentDumpProvider.java
new file mode 100644
index 0000000..d6b76af
--- /dev/null
+++ 
b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/EnvironmentDumpProvider.java
@@ -0,0 +1,291 @@
+/*
+ * 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.karaf.diagnostic.core.providers;
+
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.lang.management.ClassLoadingMXBean;
+import java.lang.management.CompilationMXBean;
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryUsage;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ThreadMXBean;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Version;
+
+/**
+ * Provider which dumps runtime environment information to file named 
environment.txt.
+ */
+public class EnvironmentDumpProvider extends TextDumpProvider {
+    
+    private static final String KEY_VALUE_FORMAT = "%1$s\t: %2$s";
+    private static final String INDENT_KEY_VALUE_FORMAT = "    
"+KEY_VALUE_FORMAT;
+    private final BundleContext bundleContext;
+
+    /**
+     * Creates new dump entry which contains information about the runtime 
environment.
+     */
+    public EnvironmentDumpProvider(final BundleContext context) {
+        super("environment.txt");
+        this.bundleContext = context;
+    }
+
+    @Override
+    protected void writeDump(final OutputStreamWriter outputStream) throws 
Exception {
+    if( null == outputStream) {
+        return;
+    }
+    final PrintWriter outPW = new PrintWriter(outputStream);
+    // current date/time
+    final DateFormat dateTimeFormatInstance = 
DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, 
Locale.ENGLISH);
+    outPW.printf(KEY_VALUE_FORMAT,"Dump timestamp", 
dateTimeFormatInstance.format(new Date(System.currentTimeMillis()))).println();
+    outPW.println();
+    // karaf information
+    dumpKarafInformation(outPW);
+    outPW.println();
+    // OSGi information
+    dumpOSGiInformation(outPW);
+    outPW.println();
+    // OS information
+    dumpOSInformation(outPW);
+    outPW.println();
+    // general information about JVM
+    dumpVMInformation(outPW, dateTimeFormatInstance);
+    outPW.println();
+    // threads
+    dumpThreadsInformation(outPW);
+    outPW.println();
+    // classes
+    dumpClassesInformation(outPW);
+    outPW.println();
+    // memory
+    dumpMemoryInformation(outPW);
+    outPW.println();
+    // garbage collector
+    dumpGCInformation(outPW);
+    }
+
+    private void dumpKarafInformation(final PrintWriter outPW) {
+        outPW.printf(KEY_VALUE_FORMAT, "Karaf", 
System.getProperty("karaf.name", "root") + ' ' + 
System.getProperty("karaf.version", "")).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "home", 
System.getProperty("karaf.home", "")).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "base", 
System.getProperty("karaf.base", "")).println();
+    }
+
+    private void dumpOSGiInformation(final PrintWriter outPW) {
+        if( null == bundleContext ) {
+            return;
+        }
+        outPW.println("OSGi:");
+        final Bundle[] bundles = bundleContext.getBundles();
+        for (final Bundle bundle : bundles) {
+            if( null == bundle || 
!!!"osgi.core".equals(bundle.getSymbolicName())) {
+                continue;
+            }
+            outPW.printf(INDENT_KEY_VALUE_FORMAT, "version", 
bundle.getVersion()).println();
+            break;
+        }
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "framework", 
bundleContext.getBundle(0).getSymbolicName() + " - " +
+                bundleContext.getBundle(0).getVersion()).println();
+    }
+
+    private void dumpOSInformation(final PrintWriter outPW) {
+        final OperatingSystemMXBean mxBean = 
ManagementFactory.getOperatingSystemMXBean();
+        if( null == mxBean) {
+            return;
+        }
+        outPW.printf(KEY_VALUE_FORMAT, "Operating System", mxBean.getName() + 
' ' + mxBean.getVersion()).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "architecture", 
mxBean.getArch()).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "processors", 
mxBean.getAvailableProcessors()).println();
+//        outPW.printf(INDENT_KEY_VALUE_FORMAT, "current system load average", 
mxBean.getSystemLoadAverage()).println();
+    }
+
+    private void dumpVMInformation(final PrintWriter outPW,
+        final DateFormat dateTimeFormatInstance) {
+        final RuntimeMXBean mxBean = ManagementFactory.getRuntimeMXBean();
+        if( mxBean == null ) {
+            return;
+        }
+        outPW.printf(KEY_VALUE_FORMAT,"Instance name", 
mxBean.getName()).println();
+        outPW.printf(KEY_VALUE_FORMAT,"Start time", 
dateTimeFormatInstance.format(new Date(mxBean.getStartTime()))).println();
+        outPW.printf(KEY_VALUE_FORMAT,"Uptime", 
printDuration(mxBean.getUptime())).println();
+        outPW.println();
+        outPW.printf(KEY_VALUE_FORMAT, "Java VM", mxBean.getVmName() + " " + 
mxBean.getVmVersion()).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "vendor", 
mxBean.getVmVendor()).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "version", 
System.getProperty("java.version")).println();
+        outPW.println();
+        outPW.println("Input arguments:");
+        final List<String> inputArguments = mxBean.getInputArguments();
+        for (final String argument : inputArguments) {
+            if( argument != null && argument.contains("=")) {
+                final String[] split = argument.split("=");
+                outPW.printf(INDENT_KEY_VALUE_FORMAT, split[0], 
split[1]).println();
+            } else {
+                outPW.printf(INDENT_KEY_VALUE_FORMAT, argument,"").println();
+            }
+        }
+        outPW.println("Classpath:");
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "boot classpath", 
mxBean.getBootClassPath()).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "library path", 
mxBean.getLibraryPath()).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "classpath", 
mxBean.getClassPath()).println();
+        outPW.println("System properties:");
+        final Map<String, String> systemProperties = 
mxBean.getSystemProperties();
+        for (final Entry<String, String> property : 
systemProperties.entrySet()) {
+            outPW.printf(INDENT_KEY_VALUE_FORMAT, property.getKey(), 
property.getValue()).println();
+        }
+        outPW.println();
+        // JIT information
+        final CompilationMXBean compilationMXBean = 
ManagementFactory.getCompilationMXBean();
+        if( compilationMXBean != null ) {
+            outPW.printf(KEY_VALUE_FORMAT, "JIT compiler", 
compilationMXBean.getName()).println();
+            outPW.printf(INDENT_KEY_VALUE_FORMAT, "total compile time", 
printDuration(compilationMXBean.getTotalCompilationTime())).println();
+        }
+    }
+
+    private void dumpThreadsInformation(final PrintWriter outPW) {
+        final ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
+        if( null == mxBean) {
+            return;
+        }
+        outPW.println("Threads:");
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "live", 
formatLong(mxBean.getThreadCount())).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "daemon", 
formatLong(mxBean.getDaemonThreadCount())).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "peak", 
formatLong(mxBean.getPeakThreadCount())).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "total", 
formatLong(mxBean.getTotalStartedThreadCount())).println();
+    }
+
+    private void dumpClassesInformation(final PrintWriter outPW) {
+        final ClassLoadingMXBean mxBean = 
ManagementFactory.getClassLoadingMXBean();
+        if( null == mxBean) {
+            return;
+        }
+        outPW.println("Classes:");
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "loaded", 
formatLong(mxBean.getLoadedClassCount())).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "total", 
formatLong(mxBean.getTotalLoadedClassCount())).println();
+        outPW.printf(INDENT_KEY_VALUE_FORMAT, "unloaded", 
formatLong(mxBean.getUnloadedClassCount())).println();
+    }
+
+    private void dumpMemoryInformation(final PrintWriter outPW) {
+        final MemoryMXBean mxBean = ManagementFactory.getMemoryMXBean();
+        if( null == mxBean) {
+            return;
+        }
+        final MemoryUsage heapMemoryUsage = mxBean.getHeapMemoryUsage();
+        final MemoryUsage nonHeapMemoryUsage = mxBean.getNonHeapMemoryUsage();
+        if( heapMemoryUsage != null ) {
+            outPW.println("HEAP Memory:");
+            outPW.printf(INDENT_KEY_VALUE_FORMAT, "commited", 
printMemory(heapMemoryUsage.getCommitted())).println();
+            outPW.printf(INDENT_KEY_VALUE_FORMAT, "init", 
printMemory(heapMemoryUsage.getInit())).println();
+            outPW.printf(INDENT_KEY_VALUE_FORMAT, "used", 
printMemory(heapMemoryUsage.getUsed())).println();
+            outPW.printf(INDENT_KEY_VALUE_FORMAT, "maximal", 
printMemory(heapMemoryUsage.getMax())).println();
+        }
+        if( nonHeapMemoryUsage != null ) {
+            outPW.println("NON-HEAP Memory:");
+            outPW.printf(INDENT_KEY_VALUE_FORMAT, "commited", 
printMemory(nonHeapMemoryUsage.getCommitted())).println();
+            outPW.printf(INDENT_KEY_VALUE_FORMAT, "init", 
printMemory(nonHeapMemoryUsage.getInit())).println();
+            outPW.printf(INDENT_KEY_VALUE_FORMAT, "used", 
printMemory(nonHeapMemoryUsage.getUsed())).println();
+            outPW.printf(INDENT_KEY_VALUE_FORMAT, "maximal", 
printMemory(nonHeapMemoryUsage.getMax())).println();
+        }
+    }
+
+    private void dumpGCInformation(final PrintWriter outPW) {
+        final List<GarbageCollectorMXBean> mxBeans = 
ManagementFactory.getGarbageCollectorMXBeans();
+        if( null == mxBeans || mxBeans.isEmpty()) {
+            return;
+        }
+        final MemoryMXBean memoryMxBean = ManagementFactory.getMemoryMXBean();
+        if( memoryMxBean != null ) {
+            outPW.printf(INDENT_KEY_VALUE_FORMAT, "pending objects", 
formatLong(memoryMxBean.getObjectPendingFinalizationCount())).println();
+        }
+        final String gcFormat ="'%1$s' collections: %2$s\ttime: %3$s";
+        outPW.println();
+        for (final GarbageCollectorMXBean mxBean : mxBeans) {
+            if( null == mxBean) {
+                continue;
+            }
+            outPW.printf(KEY_VALUE_FORMAT, "Garbage Collectors", 
String.format(gcFormat, mxBean.getName(), 
formatLong(mxBean.getCollectionCount()), 
printDuration(mxBean.getCollectionTime()))).println();
+        }
+    }
+
+
+    private String formatLong(final long longValue) {
+        final NumberFormat fmtI = new DecimalFormat("###,###", new 
DecimalFormatSymbols(Locale.ENGLISH));
+        return fmtI.format(longValue);
+    }
+
+    private String printMemory(final long bytes) {
+        if( bytes <= 1024) {
+            return formatLong(bytes)+" bytes";
+        }
+        return formatLong(bytes/1024)+" kbytes";
+    }
+
+    /**
+     * Prints the duration in a human readable format as X days Y hours Z 
minutes etc.
+     *
+     * @param uptime the uptime in millis
+     * @return the time used for displaying on screen or in logs
+     */
+    private String printDuration(double uptime) {
+        // Code based on code taken from Karaf
+        // 
https://svn.apache.org/repos/asf/karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/impl/InfoAction.java
+
+        uptime /= 1000;
+        if (uptime < 60) {
+            final NumberFormat fmtD = new DecimalFormat("###,##0.000", new 
DecimalFormatSymbols(Locale.ENGLISH));
+            return fmtD.format(uptime) + " seconds";
+        }
+        uptime /= 60;
+        if (uptime < 60) {
+            final long minutes = (long) uptime;
+            final String s = formatLong(minutes) + (minutes > 1 ? " minutes" : 
" minute");
+            return s;
+        }
+        uptime /= 60;
+        if (uptime < 24) {
+            final long hours = (long) uptime;
+            final long minutes = (long) ((uptime - hours) * 60);
+            String s = formatLong(hours) + (hours > 1 ? " hours" : " hour");
+            if (minutes != 0) {
+                s += " " + formatLong(minutes) + (minutes > 1 ? " minutes" : " 
minute");
+            }
+            return s;
+        }
+        uptime /= 24;
+        final long days = (long) uptime;
+        final long hours = (long) ((uptime - days) * 24);
+        String s = formatLong(days) + (days > 1 ? " days" : " day");
+        if (hours != 0) {
+            s += " " + formatLong(hours) + (hours > 1 ? " hours" : " hour");
+        }
+        return s;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/c3fb6191/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/HeapDumpProvider.java
----------------------------------------------------------------------
diff --git 
a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/HeapDumpProvider.java
 
b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/HeapDumpProvider.java
new file mode 100644
index 0000000..6a6f040
--- /dev/null
+++ 
b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/HeapDumpProvider.java
@@ -0,0 +1,68 @@
+/*
+ * 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.karaf.diagnostic.core.providers;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import org.apache.karaf.diagnostic.core.DumpDestination;
+import org.apache.karaf.diagnostic.core.DumpProvider;
+
+import javax.management.MBeanServer;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+import java.lang.management.ManagementFactory;
+
+/**
+ * Create a heap dump.
+ */
+public class HeapDumpProvider implements DumpProvider {
+
+    public void createDump(DumpDestination destination) throws Exception {
+        File heapDumpFile = null;
+        FileInputStream in = null;
+        OutputStream out = null;
+        try {
+            MBeanServer mBeanServer = 
ManagementFactory.getPlatformMBeanServer();
+            HotSpotDiagnosticMXBean diagnosticMXBean = 
ManagementFactory.newPlatformMXBeanProxy(mBeanServer,
+                    "com.sun.management:type=HotSpotDiagnostic", 
HotSpotDiagnosticMXBean.class);
+            heapDumpFile = File.createTempFile("heapdump", ".txt");
+            heapDumpFile.delete();
+            diagnosticMXBean.dumpHeap(heapDumpFile.getAbsolutePath(), false);
+            // copy the dump in the destination
+            in = new FileInputStream(heapDumpFile);
+            out = destination.add("heapdump.txt");
+            byte[] buffer = new byte[2048];
+            int l;
+            while (((l = in.read(buffer)) != -1)) {
+                out.write(buffer, 0, l);
+            }
+        } finally {
+            if (in != null) {
+                in.close();
+            }
+            if (out != null) {
+                out.flush();
+                out.close();
+            }
+            // remove the original dump
+            if (heapDumpFile != null && heapDumpFile.exists()) {
+                heapDumpFile.delete();
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/c3fb6191/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/MemoryDumpProvider.java
----------------------------------------------------------------------
diff --git 
a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/MemoryDumpProvider.java
 
b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/MemoryDumpProvider.java
new file mode 100644
index 0000000..3711630
--- /dev/null
+++ 
b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/MemoryDumpProvider.java
@@ -0,0 +1,56 @@
+/*
+ * 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.karaf.diagnostic.core.providers;
+
+import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
+
+import java.io.OutputStreamWriter;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+
+/**
+ * Provider for memory information in memory.txt.
+ */
+public class MemoryDumpProvider extends TextDumpProvider {
+
+    /**
+     * Create a new dump entry which contains information about memory usage.
+     */
+    public MemoryDumpProvider() {
+        super("memory.txt");
+    }
+
+    @Override
+    protected void writeDump(OutputStreamWriter outputStream) throws Exception 
{
+        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
+
+        outputStream.write("Number of objects waiting finalization: " + 
memoryMXBean.getObjectPendingFinalizationCount() + "\n\n");
+
+        outputStream.write("Heap:\n");
+        outputStream.write("\tInit:      " + 
memoryMXBean.getHeapMemoryUsage().getInit() + "\n");
+        outputStream.write("\tUser:      " + 
memoryMXBean.getHeapMemoryUsage().getUsed() + "\n");
+        outputStream.write("\tCommitted: " + 
memoryMXBean.getHeapMemoryUsage().getCommitted() + "\n");
+        outputStream.write("\tMax:       " + 
memoryMXBean.getHeapMemoryUsage().getMax() + "\n");
+
+        outputStream.write("Non-Heap: \n");
+        outputStream.write("\tInit:      " + 
memoryMXBean.getNonHeapMemoryUsage().getInit() + "\n");
+        outputStream.write("\tUser:      " + 
memoryMXBean.getNonHeapMemoryUsage().getUsed() + "\n");
+        outputStream.write("\tCommitted: " + 
memoryMXBean.getNonHeapMemoryUsage().getCommitted() + "\n");
+        outputStream.write("\tMax:       " + 
memoryMXBean.getNonHeapMemoryUsage().getMax() + "\n");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/c3fb6191/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/ThreadDumpProvider.java
----------------------------------------------------------------------
diff --git 
a/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/ThreadDumpProvider.java
 
b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/ThreadDumpProvider.java
new file mode 100644
index 0000000..6b5a882
--- /dev/null
+++ 
b/diagnostic/core/src/main/java/org/apache/karaf/diagnostic/core/providers/ThreadDumpProvider.java
@@ -0,0 +1,117 @@
+/*
+ * 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.karaf.diagnostic.core.providers;
+
+import java.io.OutputStreamWriter;
+import java.lang.management.LockInfo;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MonitorInfo;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+
+import org.apache.karaf.diagnostic.core.common.TextDumpProvider;
+
+/**
+ * Provider which dumps thread info to file named threads.txt.
+ */
+public class ThreadDumpProvider extends TextDumpProvider {
+
+    /**
+     * Creates new dump entry which contains information about threads.
+     */
+    public ThreadDumpProvider() {
+        super("threads.txt");
+    }
+
+    @Override
+    protected void writeDump(OutputStreamWriter outputStream) throws Exception 
{
+        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+
+        outputStream.write("Number of threads: " + 
threadMXBean.getThreadCount() + "\n");
+
+        for (ThreadInfo threadInfo : 
threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds(), Integer.MAX_VALUE)) {
+            outputStream.write(getDumpThreadString(threadInfo) + "\n\n");
+        }
+
+    }
+    
+    protected String getDumpThreadString(ThreadInfo threadInfo) {
+        StringBuilder sb = new StringBuilder("\"" + threadInfo.getThreadName() 
+ "\"" + " Id=" + threadInfo.getThreadId() + " "
+                                             + threadInfo.getThreadState());
+        if (threadInfo.getLockName() != null) {
+            sb.append(" on " + threadInfo.getLockName());
+        }
+        if (threadInfo.getLockOwnerName() != null) {
+            sb.append(" owned by \"" + threadInfo.getLockOwnerName() + "\" 
Id=" + threadInfo.getLockOwnerId());
+        }
+        if (threadInfo.isSuspended()) {
+            sb.append(" (suspended)");
+        }
+        if (threadInfo.isInNative()) {
+            sb.append(" (in native)");
+        }
+        sb.append('\n');
+        int i = 0;
+        StackTraceElement[] stackTrace = threadInfo.getStackTrace();
+        for (; i < stackTrace.length; i++) {
+            StackTraceElement ste = stackTrace[i];
+            sb.append("\tat " + ste.toString());
+            sb.append('\n');
+            if (i == 0 && threadInfo.getLockInfo() != null) {
+                Thread.State ts = threadInfo.getThreadState();
+                switch (ts) {
+                case BLOCKED:
+                    sb.append("\t-  blocked on " + threadInfo.getLockInfo());
+                    sb.append('\n');
+                    break;
+                case WAITING:
+                    sb.append("\t-  waiting on " + threadInfo.getLockInfo());
+                    sb.append('\n');
+                    break;
+                case TIMED_WAITING:
+                    sb.append("\t-  waiting on " + threadInfo.getLockInfo());
+                    sb.append('\n');
+                    break;
+                default:
+                }
+            }
+
+            for (MonitorInfo mi : threadInfo.getLockedMonitors()) {
+                if (mi.getLockedStackDepth() == i) {
+                    sb.append("\t-  locked " + mi);
+                    sb.append('\n');
+                }
+            }
+        }
+        if (i < stackTrace.length) {
+            sb.append("\t...");
+            sb.append('\n');
+        }
+
+        LockInfo[] locks = threadInfo.getLockedSynchronizers();
+        if (locks.length > 0) {
+            sb.append("\n\tNumber of locked synchronizers = " + locks.length);
+            sb.append('\n');
+            for (LockInfo li : locks) {
+                sb.append("\t- " + li);
+                sb.append('\n');
+            }
+        }
+        sb.append('\n');
+        return sb.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/c3fb6191/diagnostic/management/src/main/java/org/apache/karaf/diagnostic/management/internal/DiagnosticDumpMBeanImpl.java
----------------------------------------------------------------------
diff --git 
a/diagnostic/management/src/main/java/org/apache/karaf/diagnostic/management/internal/DiagnosticDumpMBeanImpl.java
 
b/diagnostic/management/src/main/java/org/apache/karaf/diagnostic/management/internal/DiagnosticDumpMBeanImpl.java
index aa850b1..339846b 100644
--- 
a/diagnostic/management/src/main/java/org/apache/karaf/diagnostic/management/internal/DiagnosticDumpMBeanImpl.java
+++ 
b/diagnostic/management/src/main/java/org/apache/karaf/diagnostic/management/internal/DiagnosticDumpMBeanImpl.java
@@ -14,16 +14,14 @@
 package org.apache.karaf.diagnostic.management.internal;
 
 import java.io.File;
-import java.util.List;
 
 import javax.management.NotCompliantMBeanException;
 import javax.management.StandardMBean;
 
+import org.apache.karaf.diagnostic.core.Dump;
 import org.apache.karaf.diagnostic.core.DumpDestination;
-import org.apache.karaf.diagnostic.core.DumpProvider;
-import org.apache.karaf.diagnostic.core.common.DirectoryDumpDestination;
-import org.apache.karaf.diagnostic.core.common.ZipDumpDestination;
 import org.apache.karaf.diagnostic.management.DiagnosticDumpMBean;
+import org.osgi.framework.BundleContext;
 
 /**
  * Implementation of diagnostic mbean.
@@ -34,7 +32,7 @@ public class DiagnosticDumpMBeanImpl extends StandardMBean 
implements
     /**
      * Dump providers.
      */
-    private List<DumpProvider> providers;
+    private BundleContext bundleContext;
 
     /**
      * Creates new diagnostic mbean.
@@ -62,25 +60,18 @@ public class DiagnosticDumpMBeanImpl extends StandardMBean 
implements
 
         DumpDestination destination;
         if (directory) {
-            destination = new DirectoryDumpDestination(target);
+            destination = Dump.directory(target);
         } else {
-            destination = new ZipDumpDestination(target);
+            destination = Dump.zip(target);
         }
 
-        for (DumpProvider provider : providers) {
-            provider.createDump(destination);
-        }
-
-        destination.save();
+        Dump.dump(bundleContext, destination);
     }
 
     /**
-     * Sets dump providers.
-     * 
-     * @param providers Dump providers. 
+     * Sets the bundle context
      */
-    public void setProviders(List<DumpProvider> providers) {
-        this.providers = providers;
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/c3fb6191/diagnostic/management/src/main/resources/OSGI-INF/blueprint/diagnostic-management.xml
----------------------------------------------------------------------
diff --git 
a/diagnostic/management/src/main/resources/OSGI-INF/blueprint/diagnostic-management.xml
 
b/diagnostic/management/src/main/resources/OSGI-INF/blueprint/diagnostic-management.xml
index 1ff894b..1f1cf13 100644
--- 
a/diagnostic/management/src/main/resources/OSGI-INF/blueprint/diagnostic-management.xml
+++ 
b/diagnostic/management/src/main/resources/OSGI-INF/blueprint/diagnostic-management.xml
@@ -19,15 +19,12 @@
 -->
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"; 
default-activation="eager">
 
-    <reference-list id="providers" availability="optional"
-        interface="org.apache.karaf.diagnostic.core.DumpProvider" />
-
     <reference id="mbeanServer" interface="javax.management.MBeanServer">
         <reference-listener ref="mbeanRegister" 
bind-method="registerMBeanServer" unbind-method="unregisterMBeanServer" />
     </reference>
 
     <bean id="mbeanImpl" 
class="org.apache.karaf.diagnostic.management.internal.DiagnosticDumpMBeanImpl">
-        <property name="providers" ref="providers" />
+        <property name="bundleContext" ref="blueprintBundleContext" />
     </bean>
 
     <bean id="mbeanRegister" 
class="org.apache.karaf.management.MBeanRegistrer" init-method="init" 
destroy-method="destroy">

Reply via email to