【问题标题】:Pax Exam execute command against KarafPax Exam 对 Karaf 执行命令
【发布时间】:2016-02-28 12:20:54
【问题描述】:

我正在尝试运行一个 PAX 考试测试,该测试启动一个 Karaf 实例版本 4.0.2,然后部署一些功能。到目前为止一切正常。

但是,我还想运行一些命令来检查捆绑包是否已安装,即运行“bundle:list”命令。

我在此处添加了 executeCommand 和 getOsgiService 方法: https://github.com/christian-posta/rider-auto-osgi/blob/master/itests/src/test/java/org/jboss/fuse/example/support/FuseTestSupport.java#L80

但我得到了 RuntimeException:

java.lang.RuntimeException: Gave up waiting for service (objectClass=org.apache.felix.service.command.CommandProcessor)
    at com.axiell.tenantidlookup.integrationtest.TenantIdLookupTest.getOsgiService(TenantIdLookupTest.java:205)
    at com.axiell.tenantidlookup.integrationtest.TenantIdLookupTest.getOsgiService(TenantIdLookupTest.java:171)
    at com.axiell.tenantidlookup.integrationtest.TenantIdLookupTest.testProvisioning(TenantIdLookupTest.java:110)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:68)
    at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:37)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.invokeViaJUnit(JUnitProbeInvoker.java:124)
    at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.findAndInvoke(JUnitProbeInvoker.java:97)
    at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.call(JUnitProbeInvoker.java:73)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.ops4j.pax.exam.rbc.internal.RemoteBundleContextImpl.remoteCall(RemoteBundleContextImpl.java:80)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$256(TCPTransport.java:683)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

这是导致异常的代码。

 CommandProcessor cp = getOsgiService(CommandProcessor.class); 
        CommandSession cs = cp.createSession(System.in, System.out, System.err);
        //cs.execute("bundle:list");
        //cs.execute("wrapper:install --help");
        //System.out.println(executeCommand("bundle:list"));
        cs.close();

CommandProcessor 的某些问题无法正常工作。任何提示或帮助将不胜感激。谢谢

【问题讨论】:

    标签: osgi apache-karaf karaf pax-exam pax-runner


    【解决方案1】:

    在 Karaf 4.x 中,命令确实发生了变化,因此您需要相应地进行更改。 完整示例可以在here找到。

    作为快速总结,您需要在测试中使用 SessionFactory,见下文:

    @Inject
    protected SessionFactory sessionFactory;
    

    然后从那里创建一个会话对象:

    @Before
    public void setUpITestBase() throws Exception {
        session = sessionFactory.create(System.in, printStream, errStream);
    }
    

    我在测试的前一部分进行了此操作,以确保会话始终是新创建的。

    以下是执行命令的关键部分:

        String response;
        FutureTask<String> commandFuture = new FutureTask<String>(new Callable<String>() {
            public String call() {
                try {
                    System.err.println(command);
                    session.execute(command);
                } catch (Exception e) {
                    e.printStackTrace(System.err);
                }
                printStream.flush();
                errStream.flush();
                return byteArrayOutputStream.toString();
            }
        });
    
        try {
            executor.submit(commandFuture);
            response = commandFuture.get(10000L, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            e.printStackTrace(System.err);
            response = "SHELL COMMAND TIMED OUT: ";
        }
    

    【讨论】:

    • 谢谢,我现在就试试。这是否也意味着您不需要 TestProbeBuilder 方法?
    • 有效!非常感谢您的帮助。我到处搜索,但无济于事。
    【解决方案2】:

    Achim Nierbeck 为我解决了这个头痛问题,因此请查看他的答案以供参考。如果有人只想了解对我有用的代码。

    import static org.junit.Assert.*;
    import static org.ops4j.pax.exam.CoreOptions.maven;
    import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.*;
    
    import org.apache.camel.Exchange;
    import org.apache.camel.Processor;
    import org.apache.camel.builder.RouteBuilder;
    import org.apache.camel.component.mock.MockEndpoint;
    import org.apache.camel.model.language.ConstantExpression;
    import org.apache.camel.test.junit4.CamelTestSupport;
    import org.apache.karaf.features.FeaturesService;
    import org.apache.karaf.features.BootFinished;
    import org.apache.karaf.shell.api.console.Session;
    import org.apache.karaf.shell.api.console.SessionFactory;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.ops4j.pax.exam.Configuration;
    import org.ops4j.pax.exam.CoreOptions;
    import org.ops4j.pax.exam.Option;
    import org.ops4j.pax.exam.ProbeBuilder;
    import org.ops4j.pax.exam.TestProbeBuilder;
    import org.ops4j.pax.exam.junit.PaxExam;
    import org.ops4j.pax.exam.karaf.options.LogLevelOption;
    import org.ops4j.pax.exam.options.WrappedUrlProvisionOption;
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.Filter;
    import org.osgi.framework.FrameworkUtil;
    import org.osgi.framework.InvalidSyntaxException;
    import org.osgi.framework.ServiceReference;
    import org.osgi.util.tracker.ServiceTracker;
    import org.osgi.framework.Constants;
    
    import javax.inject.Inject;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.TimeUnit;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.IOException;
    import java.io.PrintStream;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.Dictionary;
    import java.util.Enumeration;
    
    @RunWith(PaxExam.class)
    public class TenantIdLookupTest {
    
        @Inject
        protected BundleContext bc;
        @Inject
        protected FeaturesService featuresService;
        @Inject
        protected BootFinished bootFinished;
        @Inject
        protected SessionFactory sessionFactory;
    
        private ExecutorService executor = Executors.newCachedThreadPool();
        private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        private PrintStream printStream = new PrintStream(byteArrayOutputStream);
        private PrintStream errStream = new PrintStream(byteArrayOutputStream);
        private Session session;
    
        @ProbeBuilder
        public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
            probe.setHeader(Constants.DYNAMICIMPORT_PACKAGE,
                    "*,org.apache.felix.service.*;status=provisional");
            return probe;
        }
    
        @Configuration
        public static Option[] configure() throws Exception {
            return new Option[] {
                    karafDistributionConfiguration()
                            .frameworkUrl(
                                    maven().groupId("org.apache.karaf")
                                            .artifactId("apache-karaf").type("zip")
                                            .version("4.0.2"))
                            .karafVersion("4.0.2").useDeployFolder(false)
                            .unpackDirectory(new File("target/paxexam/unpack")),
                    configureConsole().ignoreLocalConsole(),
                    features(
                            maven().groupId("org.apache.camel.karaf")
                                    .artifactId("apache-camel").type("xml")
                                    .classifier("features").version("2.15.1"),
                            "camel"),
                    features(
                            maven().groupId("org.apache.camel.karaf")
                                    .artifactId("apache-camel").type("xml")
                                    .classifier("features").version("2.15.1"),
                            "camel-blueprint"),
                    features(
                            maven().groupId("org.apache.camel.karaf")
                                    .artifactId("apache-camel").type("xml")
                                    .classifier("features").version("2.15.1"),
                            "camel-netty4"),
                    features(
                            maven().groupId("org.apache.camel.karaf")
                                    .artifactId("apache-camel").type("xml")
                                    .classifier("features").version("2.15.1"),
                            "camel-rabbitmq"),
                    CoreOptions.mavenBundle(CoreOptions.maven(
                            "com.google.code.gson", "gson").version("2.3")),
                    logLevel(LogLevelOption.LogLevel.INFO),
                    // features(maven().groupId("org.apache.camel.karaf").artifactId("apache-camel").type("xml").classifier("features").version("2.12.1"),
                    // "camel-blueprint", "camel-test"),
                    // features(maven().groupId("net.nanthrax.blog").artifactId("camel-blueprint").type("xml").classifier("features").version("1.0-SNAPSHOT"),
                    // "blog-camel-blueprint-route"),
                    keepRuntimeFolder(),
    
            };
    
        }
    
        @Before
        public void setUpITestBase() throws Exception {
            session = sessionFactory.create(System.in, printStream, errStream);
        }
    
        @Test
        public void testProvisioning() throws Exception {
             assertTrue(featuresService.isInstalled(featuresService.getFeature("camel-blueprint")));
                 System.out.println(executeCommand("bundle:list"));
    
        }
    
        protected String executeCommand(final String command) throws IOException {
            byteArrayOutputStream.flush();
            byteArrayOutputStream.reset();
    
            String response;
            FutureTask<String> commandFuture = new FutureTask<String>(
                    new Callable<String>() {
                        public String call() {
                            try {
                                System.err.println(command);
                                session.execute(command);
                            } catch (Exception e) {
                                e.printStackTrace(System.err);
                            }
                            printStream.flush();
                            errStream.flush();
                            return byteArrayOutputStream.toString();
                        }
                    });
    
            try {
                executor.submit(commandFuture);
                response = commandFuture.get(10000L, TimeUnit.MILLISECONDS);
            } catch (Exception e) {
                e.printStackTrace(System.err);
                response = "SHELL COMMAND TIMED OUT: ";
            }
    
            System.err.println(response);
    
            return response;
        }
    
        @SuppressWarnings({ "rawtypes", "unchecked" })
        protected <T> T getOsgiService(Class<T> type, String filter, long timeout) {
            ServiceTracker tracker = null;
            try {
                String flt;
                if (filter != null) {
                    if (filter.startsWith("(")) {
                        flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")" + filter + ")";
                    } else {
                        flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")(" + filter + "))";
                    }
                } else {
                    flt = "(" + Constants.OBJECTCLASS + "=" + type.getName() + ")";
                }
                Filter osgiFilter = FrameworkUtil.createFilter(flt);
                tracker = new ServiceTracker(bc, osgiFilter, null);
                tracker.open(true);
                // Note that the tracker is not closed to keep the reference
                // This is buggy, as the service reference may change i think
                Object svc = type.cast(tracker.waitForService(timeout));
                if (svc == null) {
                    Dictionary dic = bc.getBundle().getHeaders();
                    System.err.println("Test bundle headers: " + explode(dic));
    
                    for (ServiceReference ref : asCollection(bc.getAllServiceReferences(null, null))) {
                        System.err.println("ServiceReference: " + ref);
                    }
    
                    for (ServiceReference ref : asCollection(bc.getAllServiceReferences(null, flt))) {
                        System.err.println("Filtered ServiceReference: " + ref);
                    }
    
                    //logger.error("Gave up waiting for service " + flt);
                    return null;
                }
                return type.cast(svc);
            } catch (InvalidSyntaxException e) {
                throw new IllegalArgumentException("Invalid filter", e);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    
        /*
         * Explode the dictionary into a ,-delimited list of key=value pairs
         */
        @SuppressWarnings("rawtypes")
        private static String explode(Dictionary dictionary) {
            Enumeration keys = dictionary.keys();
            StringBuffer result = new StringBuffer();
            while (keys.hasMoreElements()) {
                Object key = keys.nextElement();
                result.append(String.format("%s=%s", key, dictionary.get(key)));
                if (keys.hasMoreElements()) {
                    result.append(", ");
                }
            }
            return result.toString();
        }
    
        /**
         * Provides an iterable collection of references, even if the original array
         * is null
         */
        @SuppressWarnings("rawtypes")
        private static Collection<ServiceReference> asCollection(ServiceReference[] references) {
            return references != null ? Arrays.asList(references) : Collections.<ServiceReference> emptyList();
        }
    
    }
    

    终于等到了输出:

    START LEVEL 100 , List Threshold: 50
     ID | State  | Lvl | Version      | Name
    --------------------------------------------------------------------------------------
      9 | Active |  80 | 2.3          | Gson
     10 | Active |  80 | 3.3.4        | RabbitMQ Java AMQP client library
     11 | Active |  80 | 4.0.26.Final | Netty/Buffer
     12 | Active |  80 | 4.0.26.Final | Netty/Codec
     13 | Active |  80 | 4.0.26.Final | Netty/Common
     14 | Active |  80 | 4.0.26.Final | Netty/Handler
     15 | Active |  80 | 4.0.26.Final | Netty/Transport
     29 | Active |  80 | 2.15.1       | camel-blueprint
     30 | Active |  80 | 2.15.1       | camel-catalog
     31 | Active |  80 | 2.15.1       | camel-commands-core
     32 | Active |  80 | 2.15.1       | camel-core
     33 | Active |  80 | 2.15.1       | camel-netty4
     34 | Active |  80 | 2.15.1       | camel-rabbitmq
     35 | Active |  80 | 2.15.1       | camel-spring
     36 | Active |  80 | 2.15.1       | camel-karaf-commands
     37 | Active |  80 | 1.6.0        | Commons Pool
     38 | Active |  80 | 1.0          | Apache Geronimo JSR-330 Spec API
     39 | Active |  80 | 1.1.1        | geronimo-jta_1.1_spec
     69 | Active |  80 | 2.2.6.1      | Apache ServiceMix :: Bundles :: jaxb-impl
     81 | Active |  80 | 1.5.0        | OPS4J Base - IO
     82 | Active |  80 | 1.5.0        | OPS4J Base - Lang
     83 | Active |  80 | 1.5.0        | OPS4J Base - Monitors
     84 | Active |  80 | 1.5.0        | OPS4J Base - Net
     85 | Active |  80 | 1.5.0        | OPS4J Base - Service Provider Access
     86 | Active |  80 | 1.5.0        | OPS4J Base - Store
     87 | Active |  80 | 1.5.0        | OPS4J Base - Util - Property
     88 | Active |  80 | 4.6.0        | OPS4J Pax Exam API
     89 | Active |  80 | 4.6.0        | OPS4J Pax Exam Extender Service
     90 | Active |  80 | 4.6.0        | OPS4J Pax Exam Injection
     91 | Active |  80 | 4.6.0        | OPS4J Pax Exam JUnit Probe Invoker
     92 | Active |  80 | 4.6.0        | OPS4J Pax Exam Remote Bundle Context
     93 | Active |  80 | 1.8.1        | OPS4J Pax Swissbox :: OSGi Core
     94 | Active |  80 | 1.8.1        | OPS4J Pax Swissbox :: Extender
     95 | Active |  80 | 1.8.1        | OPS4J Pax Swissbox :: Framework Helpers
     96 | Active |  80 | 1.8.1        | OPS4J Pax Swissbox :: Lifecycle
     97 | Active |  80 | 1.8.1        | OPS4J Pax Swissbox :: Tracker
     98 | Active |  80 | 1.3.0.1      | OPS4J Pax Tipi - hamcrest-core
     99 | Active |  80 | 4.12.0.1     | OPS4J Pax Tipi - junit
    112 | Active |  80 | 3.1.4        | Stax2 API
    113 | Active |  80 | 4.4.1        | Woodstox XML-processor
    114 | Active |  80 |              | PAXEXAM-PROBE-bb084675-f072-481b-8f3e-6e3657762bc3
    

    【讨论】:

    • 当我在上面运行时,我低于输出 14:48:20.390 [main] INFO oopercRemoteBundleContextClient - 等待远程捆绑上下文.. 在 21001 名称:52be8a65-7121-49ab-af8d-03ec1bf5b0fb timout: [RelativeTimeout value = 180000] 用法:java [-options] class [args...](执行一个类)或 java [-options] -jar jarfile [args...](执行一个 jar 文件)
    猜你喜欢
    • 2021-07-08
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 2013-12-16
    • 2012-08-06
    • 2012-04-29
    相关资源
    最近更新 更多