java.lang.ClassCastException:ihtika2.i_testbundle.TestClasss无法强制转换为ihtika2.i_testbundle.service.TestClasssInter

时间:2012-07-31 06:51:33

标签: java osgi bundle apache-felix

我和菲利克斯一起玩,我无法理解一件事。 我有一些OSGi Felix包,我尝试从这个包中加载和使用服务。 捆绑代码:

 package ihtika2.i_testbundle;

import ihtika2.i_testbundle.service.TestClasssInter;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;

public class Activator implements BundleActivator {

    @Override
    public void start(BundleContext context) throws Exception {
        Hashtable<String, String> props = new Hashtable<String, String>();
        props.put("Funct", "TESTCl");

        context.registerService(TestClasssInter.class.getName(), new TestClasss(), props);


        ServiceReference[] refs;
        try {
            BundleContext bundleContext = context;

//            System.out.println(TestClasssInter.class.getName());
            refs = bundleContext.getServiceReferences("ihtika2.i_testbundle.service.TestClasssInter", "(Funct=TESTCl)");

            if (refs == null) {
                System.out.println("Not Found AboutForm on show!!!");
            } else {
                Object MainForm = bundleContext.getService(refs[0]);
                TestClasssInter sdfsdf = (TestClasssInter) MainForm;
                sdfsdf.printSomeLine();
//                    MainForm.sendContext(bundleContext);
//                    MainForm.showWindow();
            }

        } catch (InvalidSyntaxException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void stop(BundleContext context) throws Exception {
        // TODO add deactivation code here
    }
}

package ihtika2.i_testbundle;

import ihtika2.i_testbundle.service.TestClasssInter;

/**
 *
 * @author Arthur
 */
public class TestClasss implements TestClasssInter {

    @Override
    public void printSomeLine() {
        System.out.println("TEST MESSAGE");
    }
}

package ihtika2.i_testbundle.service;

/**
 *
 * @author Arthur
 */
public interface TestClasssInter {

    public void printSomeLine();
}

正如您在更新的示例中所看到的 - 必须显示行&#34; TEST MESSAGE&#34;来自捆绑代码。它的节目一切正常。

但如果我尝试在我的&#34; loader&#34;中执行此代码,则会显示错误

Could not create framework: java.lang.ClassCastException: ihtika2.i_testbundle.TestClasss cannot be cast to ihtika2.i_testbundle.service.TestClasssInter
java.lang.ClassCastException: ihtika2.i_testbundle.TestClasss cannot be cast to ihtika2.i_testbundle.service.TestClasssInter
    at com.google.code.ihtika.Starter.main(Starter.java:103)
Java Result: -1

加载程序的代码是

/*
 * 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 com.google.code.ihtika;

import ihtika2.i_testbundle.service.TestClasssInter;
import java.io.File;
import java.util.ArrayList;
import java.util.Map;
import java.util.ServiceLoader;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;

/**
 * This class provides a static {@code main()} method so that the bundle can be
 * run as a stand-alone host application. In such a scenario, the application
 * creates its own embedded OSGi framework instance and interacts with the
 * internal extensions to providing drawing functionality. To successfully
 * launch the stand-alone application, it must be run from this bundle's
 * installation directory using "{@code java -jar}". The locations of any
 * additional extensions that have to be started, have to be passed as command
 * line arguments to this method.
 */
public class Starter {

    private static Framework m_framework = null;

    /**
     * Enables the bundle to run as a stand-alone application. When this static
     * {@code main()} method is invoked, the application creates its own
     * embedded OSGi framework instance and interacts with the internal
     * extensions to provide drawing functionality. To successfully launch as a
     * stand-alone application, this method should be invoked from the bundle's
     * installation directory using "{@code java -jar}". The location of any
     * extension that shall be installed can be passed as parameters. <p> For
     * example if you build the bundles inside your workspace, maven will create
     * a target directory in every project. To start the application from within
     * your IDE you should pass: <p>
     * <pre>
     * {@code file:../servicebased.circle/target/servicebased.circle-1.0.0.jar
     * file:../servicebased.square/target/servicebased.square-1.0.0.jar
     * file:../servicebased.triangle/target/servicebased.triangle-1.0.0.jar}
     * </pre>
     *
     * @param args The locations of additional bundles to start.
     *
     */
    public static void main(String[] args) {
        // Args should never be null if the application is run from the command line.
        // Check it anyway.
        ArrayList<String> locations = new ArrayList<>();

        indexBundlesDir("I_Bundles/Stage_300", locations);
        indexBundlesDir("I_Bundles/Stage_400", locations);
        indexBundlesDir("I_Bundles/Stage_500", locations);

        // Print welcome banner.
        System.out.println("\nWelcome to My Launcher");
        System.out.println("======================\n");

        try {
            Map<String, String> config = ConfigUtil.createConfig();
            m_framework = createFramework(config);
            m_framework.init();
            m_framework.start();
            installAndStartBundles(locations);

            for (Bundle testBundle : m_framework.getBundleContext().getBundles()) {
                if (testBundle.getSymbolicName().equals("ihtika2.I_TestBundle")) {
                    System.out.println("found");

                    ServiceReference[] refs;
                    try {
                        BundleContext bundleContext = m_framework.getBundleContext();

//                        System.out.println(TestClasssInter.class.getName());
                        refs = bundleContext.getServiceReferences("ihtika2.i_testbundle.service.TestClasssInter", "(Funct=TESTCl)");

                        if (refs == null) {
                            System.out.println("Not Found AboutForm on show!!!");
                        } else {
                            Object MainForm = bundleContext.getService(refs[0]);
                            TestClasssInter sdfsdf = (TestClasssInter) MainForm;
//                    MainForm.sendContext(bundleContext);
//                    MainForm.showWindow();
                        }

                    } catch (InvalidSyntaxException ex) {
                        ex.printStackTrace();
                    }

                }
//                Dictionary<String, String> headerLine = testBundle.getHeaders();
//                Enumeration e = headerLine.keys();
//
//                while (e.hasMoreElements()) {
//                    Object key = e.nextElement();
//                    if (key.equals("Import-Package")) {
//                        System.out.println(key + " - " + headerLine.get(key));
//                    }
//                    System.out.println(key + " - " + headerLine.get(key));
//                }
            }

            m_framework.waitForStop(0);
            System.exit(0);
        } catch (Exception ex) {
            System.err.println("Could not create framework: " + ex);
            ex.printStackTrace();
            System.exit(-1);
        }
    }

    private static void indexBundlesDir(String bundlesDir, ArrayList<String> locations) {
        File dir = new File(bundlesDir);
        String[] children = dir.list();
        if (children == null) {
            // Either dir does not exist or is not a directory
        } else {
            for (int i = 0; i < children.length; i++) {
                // Get filename of file or directory
                locations.add("file:/c:/Art/Dropbox/OpenSource/MyGIT/ihtika-2/ihtika-2/MainApplication/" + bundlesDir + "/" + children[i]);
            }
        }
    }

    /**
     * Util method for creating an embedded Framework. Tries to create a
     * {@link FrameworkFactory} which is then be used to create the framework.
     *
     * @param config the configuration to create the framework with
     * @return a Framework with the given configuration
     */
    private static Framework createFramework(Map<String, String> config) {
        ServiceLoader<FrameworkFactory> factoryLoader = ServiceLoader.load(FrameworkFactory.class);
        for (FrameworkFactory factory : factoryLoader) {
            return factory.newFramework(config);
        }
        throw new IllegalStateException("Unable to load FrameworkFactory service.");
    }

    /**
     * Installs and starts all bundles used by the application. Therefore the
     * host bundle will be started. The locations of extensions for the host
     * bundle can be passed in as parameters.
     *
     * @param bundleLocations the locations where extension for the host bundle
     * are located. Must not be {@code null}!
     * @throws BundleException if something went wrong while installing or
     * starting the bundles.
     */
    private static void installAndStartBundles(ArrayList<String> bundleLocations) throws BundleException {
        BundleContext bundleContext = m_framework.getBundleContext();
//        Activator bundleActivator = new Activator();
//        bundleActivator.start(bundleContext);
        for (String location : bundleLocations) {
            Bundle addition = bundleContext.installBundle(location);
//            System.out.println(location);
            addition.start();
        }
    }
}

package ihtika2.i_testbundle.service;

/**
 *
 * @author Arthur
 */
public interface TestClasssInter {

    public void printSomeLine();
}

1 个答案:

答案 0 :(得分:4)

ClassLoaders就是不能那样工作,确实需要是同一个类/接口。 MainForm实现MainFormInterface,而不是MainFormInterface2,即使它们是相同的。

您需要做的是:

  • 确保您的MainFormInterface位于一个单独的包中(我认为它是:ihtika2.mainform.service)
  • 删除MainFormInterface2
  • 将所有MainFormInterface2引用替换为MainFormInterface
  • 将包添加到Felix中的org.osgi.framework.system.packages.extra设置中,我认为最简单的地方就是在ConfigUtil.createConfig()之后将其添加到Map中,这样Felix就可以访问从OSGi外部的ihtika2.mainform.service包
  • 确保您的捆绑包导入包ihtika2.mainform.service,因此您的捆绑包也可以访问ihtika2.mainform.service

应该这样做。