Hi, I wanted to add a new command to apache karaf to be able to troubleshoot some more in detail in to the dependencies. I use the bundles command from the karaf source as input/inspiration.
Nevertheless, I am getting undeterministic behavior. Sometimes the command (acme:deps) works, but other times, both the existing bundle command and the new acme commands stop working. At other times, it works again so the behavior is undeterministic. I don't know how to troubleshoot this further. Do you have any tips? Environment: 1. karaf 4.2.4, with the following features installed: http, http-whiteboard, war, jndi, transaction, jdbc, webconsole, pax-jdbc-pool-dbcp2, jms, eclipselink, paxx-cdi-openwebbeans 2. centos 7, 64 bit, Linux whistler 3.10.0-862.3.2.el7.x86_64 #1 SMP Mon May 21 23:36:36 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux 3. jdk 1.8.0_131, Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode) The source files are attached. below: 1. pom.xml 2. Hello.java: a dummy command 3. RevTreeShow.java: the command that I am interested in 4. acme.tar.gz: an archive with the above files in the correct directory structure. Cheers Erik PS. output of feature:list -i is: karaf@root()> feature:list -i Name â Version â Required â State â Repository â Description ââââââââââââââââââââââââââââââ¼âââââââââââââââââââ¼âââââââââââ¼ââââââââââ¼âââââââââââââââââââââââââââ¼ââââââââââââââââââââââââââââââââââââââââââââââââââ aries-proxy â 4.2.4 â â Started â standard-4.2.4 â Aries Proxy feature â 4.2.4 â â Started â standard-4.2.4 â Features Support shell â 4.2.4 â â Started â standard-4.2.4 â Karaf Shell deployer â 4.2.4 â â Started â standard-4.2.4 â Karaf Deployer bundle â 4.2.4 â â Started â standard-4.2.4 â Provide Bundle support config â 4.2.4 â â Started â standard-4.2.4 â Provide OSGi ConfigAdmin support diagnostic â 4.2.4 â â Started â standard-4.2.4 â Provide Diagnostic support instance â 4.2.4 â â Started â standard-4.2.4 â Provide Instance support jaas â 4.2.4 â â Started â standard-4.2.4 â Provide JAAS support log â 4.2.4 â â Started â standard-4.2.4 â Provide Log support package â 4.2.4 â â Started â standard-4.2.4 â Package commands and mbeans service â 4.2.4 â â Started â standard-4.2.4 â Provide Service support system â 4.2.4 â â Started â standard-4.2.4 â Provide System support http â 4.2.4 â x â Started â standard-4.2.4 â Implementation of the OSGI HTTP Service pax-http-service â 7.2.8 â â Started â standard-4.2.4 â Pax-Web OSGi HTTP Service http-whiteboard â 4.2.4 â x â Started â standard-4.2.4 â Provide HTTP Whiteboard pattern support war â 4.2.4 â x â Started â standard-4.2.4 â Turn Karaf as a full WebContainer kar â 4.2.4 â â Started â standard-4.2.4 â Provide KAR (KARaf archive) support webconsole â 4.2.4 â x â Started â standard-4.2.4 â Base support of the Karaf WebConsole ssh â 4.2.4 â â Started â standard-4.2.4 â Provide a SSHd server on Karaf management â 4.2.4 â â Started â standard-4.2.4 â Provide a JMX MBeanServer and a set of MBeans in scr â 4.2.4 â â Started â standard-4.2.4 â Declarative Service support minimal â 4.2.4 â x â Started â standard-4.2.4 â Wrap feature describing all features part of a mi pax-transx-tm-api â 0.4.2 â â Started â pax-transx-0.4.2 â pax-transx-tm-geronimo â 0.4.2 â â Started â pax-transx-0.4.2 â pax-transx-tm â 0.4.2 â â Started â pax-transx-0.4.2 â pax-transx-connector â 0.4.2 â â Started â pax-transx-0.4.2 â pax-transx-jms â 0.4.2 â â Started â pax-transx-0.4.2 â pax-jdbc-spec â 1.3.4 â â Started â org.ops4j.pax.jdbc-1.3.4 â Provides OSGi JDBC Service spec pax-jdbc â 1.3.4 â â Started â org.ops4j.pax.jdbc-1.3.4 â Provides JDBC Service support pax-jdbc-config â 1.3.4 â â Started â org.ops4j.pax.jdbc-1.3.4 â Provides JDBC Config support pax-jdbc-pool-dbcp2 â 1.3.4 â x â Started â org.ops4j.pax.jdbc-1.3.4 â Provides JDBC Pooling DataSourceFactory pax-cdi â 1.1.1 â â Started â org.ops4j.pax.cdi-1.1.1 â Provide CDI support pax-cdi-openwebbeans â 1.1.1 â x â Started â org.ops4j.pax.cdi-1.1.1 â OpenWebBeans CDI support pax-jms-core â 1.0.3 â â Started â pax-jms-1.0.3 â pax-jms-config â 1.0.3 â â Started â pax-jms-1.0.3 â pax-jms-pool-pooledjms â 1.0.3 â â Started â pax-jms-1.0.3 â pax-jms-pool-transx â 1.0.3 â â Started â pax-jms-1.0.3 â pax-jms-pool â 1.0.3 â â Started â pax-jms-1.0.3 â jpa â 2.7.2 â â Started â aries-jpa-2.7.2 â OSGi Persistence Container pax-web-core â 7.2.8 â â Started â org.ops4j.pax.web-7.2.8 â Provide Core pax-web bundles pax-jetty â 9.4.12.v20180830 â â Started â org.ops4j.pax.web-7.2.8 â Provide Jetty engine support pax-http-jetty â 7.2.8 â â Started â org.ops4j.pax.web-7.2.8 â pax-http â 7.2.8 â â Started â org.ops4j.pax.web-7.2.8 â Implementation of the OSGI HTTP Service pax-http-whiteboard â 7.2.8 â â Started â org.ops4j.pax.web-7.2.8 â Provide HTTP Whiteboard pattern support pax-war â 7.2.8 â â Started â org.ops4j.pax.web-7.2.8 â Provide support of a full WebContainer transaction-api â 1.2.0 â â Started â enterprise-4.2.4 â transaction-manager-geronimo â 3.1.3 â â Started â enterprise-4.2.4 â Geronimo Transaction Manager transaction â 2.0.0 â x â Started â enterprise-4.2.4 â OSGi Transaction Manager eclipselink â 2.7.4 â x â Started â enterprise-4.2.4 â Eclipselink JPA persistence engine support jndi â 4.2.4 â x â Started â enterprise-4.2.4 â OSGi Service Registry JNDI access jdbc â 4.2.4 â x â Started â enterprise-4.2.4 â JDBC service and commands jms â 4.2.4 â x â Started â enterprise-4.2.4 â JMS service and commands
<?xml version="1.0"?> <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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.acme</groupId> <artifactId>acme-karaf-commands</artifactId> <packaging>bundle</packaging> <version>1.0.0-SNAPSHOT</version> <name>Axxerion Karaf commands</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> <version>5.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> <version>5.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.karaf</groupId> <artifactId>org.apache.karaf.util</artifactId> <version>4.2.4</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.karaf.shell</groupId> <artifactId>org.apache.karaf.shell.core</artifactId> <optional>true</optional> <version>4.2.4</version> </dependency> <dependency> <groupId>org.apache.karaf.bundle</groupId> <artifactId>org.apache.karaf.bundle.core</artifactId> <optional>true</optional> <version>4.2.4</version> <scope>provided</scope> </dependency> </dependencies> <build> <resources> <resource> <directory>${project.basedir}/src/main/resources</directory> <includes> <include>**/*</include> </includes> </resource> <!-- <resource> <directory>${project.basedir}/src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/*.info</include> </includes> </resource> --> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <target>1.8</target> <source>1.8</source> </configuration> </plugin> <!-- <plugin> <groupId>org.apache.karaf.tooling</groupId> <artifactId>karaf-services-maven-plugin</artifactId> <version>4.3.0-SNAPSHOT</version> <executions> <execution> <id>service-metadata-generate</id> <phase>process-classes</phase> <goals> <goal>service-metadata-generate</goal> </goals> </execution> </executions> </plugin> --> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>4.2.0</version> <extensions>true</extensions> <configuration> <instructions> <Export-Package> com.acme.karaf.commands </Export-Package> <Import-Package> org.apache.karaf.shell*;version="[4,5)", org.apache.karaf.util*;version="[4,5)", * </Import-Package> <Karaf-Commands>com.acme.karaf.commands</Karaf-Commands> </instructions> </configuration> </plugin> </plugins> </build> </project>
/* =============================================================================
* Author : Axxerion B.V.
* Copyright: (c) 2012 Axxerion B.V., the Netherlands. All rights reserved.
* =============================================================================
* No part of this file may be reproduced or transmitted in any form or by any
* means, electronic or mechanical, for the purpose, without the express written
* permission of the copyright holder.
* =============================================================================
*/
package com.acme.karaf.commands;
import org.apache.karaf.shell.api.action.Action;
import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.lifecycle.Service;
@Service
@Command(scope = "acme", name = "hello", description = "Hello world")
public class Hello implements Action {
@Argument(index = 0, name = "message")
String message;
@Override
public Object execute() {
return message;
}
}
/* =============================================================================
* Author : Axxerion B.V.
* Copyright: (c) 2012 Axxerion B.V., the Netherlands. All rights reserved.
* =============================================================================
* No part of this file may be reproduced or transmitted in any form or by any
* means, electronic or mechanical, for the purpose, without the express written
* permission of the copyright holder.
* =============================================================================
*/
package com.acme.karaf.commands;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.karaf.bundle.core.BundleService;
import org.apache.karaf.shell.api.action.Action;
import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.lifecycle.Reference;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@Service
@Command(scope = "acme", name = "deps", description = "Show dependencies on a module")
public class RevTreeShow implements Action {
@Argument(index = 0, name = "id", description = "The bundle ID or name or name/version", required = true, multiValued = false)
String id;
@Reference
BundleContext bundleContext;
@Reference
BundleService bundleService;
public Object execute() throws Exception {
Bundle bundle = bundleService.getBundle(id);
return doExecute(bundle);
}
public Object doExecute(Bundle bundle) {
System.out.println();
printHeader(bundle);
System.out.println();
List<Bundle> allBundles = bundleService.selectBundles(Collections.emptyList(), true);
int namelen = allBundles.stream().map(Bundle::getSymbolicName).mapToInt(String::length).max().orElse(1);
{
System.out.println("REQUIRED");
System.out.println();
Map<String, Bundle> wires = bundleService.getWiredBundles(bundle);
for (Map.Entry<String, Bundle> wire : wires.entrySet()) {
Bundle otherBundle = wire.getValue();
System.out.println(
String.format("%-" + namelen + "s <- [%-3d] %-" + namelen + "s",
wire.getKey(),
otherBundle.getBundleId(),
otherBundle.getSymbolicName()));
}
}
System.out.println();
System.out.println("PROVIDED");
System.out.println();
for (Bundle b : allBundles) {
Map<String, Bundle> wires = bundleService.getWiredBundles(b);
for (Map.Entry<String, Bundle> wire : wires.entrySet()) {
Bundle otherBundle = wire.getValue();
if (otherBundle.getBundleId() == bundle.getBundleId()) {
System.out.println(
String.format("%-" + namelen + "s -> [%-3d] %-" + namelen + "s",
wire.getKey(),
b.getBundleId(),
b.getSymbolicName()));
}
}
}
System.out.println();
return null;
}
private void printHeader(Bundle bundle) {
System.out.printf("Bundle %s [%s] is currently %s%n",
bundle.getSymbolicName(),
bundle.getBundleId(),
getState(bundle));
}
private String getState(Bundle bundle) {
switch (bundle.getState()) {
case Bundle.UNINSTALLED:
return "UNINSTALLED";
case Bundle.INSTALLED:
return "INSTALLED";
case Bundle.RESOLVED:
return "RESOLVED";
case Bundle.STARTING:
return "STARTING";
case Bundle.STOPPING:
return "STOPPING";
case Bundle.ACTIVE:
return "ACTIVE";
default:
return "UNKNOWN";
}
}
}
acme.tar.gz
Description: application/gzip
