【问题标题】:Class defined in another plugin cannot be found by the main plugin - Eclipse Product主插件找不到在另一个插件中定义的类 - Eclipse 产品
【发布时间】:2014-04-14 23:05:37
【问题描述】:

我将插件项目导出为产品,当我运行产品(eclipse 应用程序)时,主插件(org.example.framework.core)找不到在另一个插件(org.example.abc)中定义的类,该插件实现了对扩展的扩展主插件提供的点。类是扩展中定义的元素之一。但是,当我在 Eclipse 中运行项目时,一切正常!

这里是日志(atvste.ppt.ptfwDescription.abc.decoderInfoorg.example.abc plugin中的一个包):

0 [Worker-2] ERROR org.example.framework.core.ptfw.codec.decode.MsgDecoderInfo org.example.framework.core.ptfw.codec.decode.MsgDecoderInfo.createInstance(MsgDecoderInfo.java:114) : can not create class for :atvste.ppt.ptfwDescription.abc.decoderInfo.MsgDecoderInfoABC atvste.ppt.ptfwDescription.abc.decoderInfo.MsgDecoderInfoABC cannot be found by org.example.framework.core_1.0.0.201404111439 java.lang.ClassNotFoundException: atvste.ppt.ptfwDescription.abc.decoderInfo.MsgDecoderInfoABC cannot be found by org.example.framework.core_1.0.0.201404111439 at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501) at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421) at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412) at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at org.example.framework.core.ptfw.codec.decode.MsgDecoderInfo.createInstance(MsgDecoderInfo.java:104) at org.example.framework.core.ptfw.codec.decode.DecoderInfo.<init>(DecoderInfo.java:56) at org.example.framework.core.ptfw.codec.decode.DecoderInfo.createInstance(DecoderInfo.java:125) at org.example.framework.core.ptfw.codec.ptfwObjectsFactory.decoderInfoItf_createInstance(ptfwObjectsFactory.java:200) at org.example.framework.persistence.jaxb.ptfwDescriptionPersistenceJaxb.createptfwDescription(ptfwDescriptionPersistenceJaxb.java:326) at org.example.framework.persistence.jaxb.ptfwDescriptionPersistenceJaxb.fillptfwDescription(ptfwDescriptionPersistenceJaxb.java:247) at org.example.framework.persistence.jaxb.ptfwDescriptionPersistenceJaxb.createInstance(ptfwDescriptionPersistenceJaxb.java:232) at org.example.framework.persistence.jaxb.ptfwDescriptionPersistenceJaxb.open(ptfwDescriptionPersistenceJaxb.java:146) at org.example.framework.core.ptfw.codec.ptfwDescription.createInstance(ptfwDescription.java:152) at org.example.framework.core.ptfw.codec.command.CmdLoadptfwDescription.loadptfwDescription(CmdLoadptfwDescription.java:50) at org.example.framework.core.ptfw.codec.command.CmdLoadptfwDescription.execute(CmdLoadptfwDescription.java:40) at org.example.framework.core.runtime.JobService$2.run(JobService.java:93) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)

编辑:创建类实例的函数未找到

 public static IMessageDecoderInfo createInstance(XmlgMsgDecoderInfo pMsgDecoderInfoType,
        IMessageDecoderInfo msgDecoder)
{

    String className = pMsgDecoderInfoType.getClassName();
    if(className!=null)
    {
        try
        {
            Class<?> formalArgs[] = new Class[1];
            formalArgs[0] = XmlgMsgDecoderInfo.class;
            Class<?> clazz;
            if (msgDecoder != null)
            {
                clazz = msgDecoder.getClass();
            }
            else
            {
                clazz = Class.forName( className );
            }
            Constructor<?> constructor = clazz.getConstructor(formalArgs);
            java.lang.Object  actualArgs[] =
            { pMsgDecoderInfoType };

            return (IMessageDecoderInfo)constructor.newInstance(actualArgs);
        }catch(Exception e) {
            String error = "can not create class for :" +className+ " " + e.getMessage();
            if (LOGGER.isEnabledFor(Level.ERROR)) {
                LOGGER.error(error, e);
            }
            throw new CreatePtfwElementRuntimeException(error, e);
        }
    }
    return new MsgDecoderInfo(pMsgDecoderInfoType);
}`

【问题讨论】:

  • MsgDecoderInfo.createInstance 是如何创建类实例的?
  • 使用反射...我应该提供代码吗?
  • 好的编辑问题以显示创建实例的功能!

标签: java eclipse eclipse-plugin


【解决方案1】:

由于 Eclipse 使用了复杂的类加载器系统,您不能使用 Class.forName 在另一个插件中加载类。

如果您的代码正在处理扩展点定义,您将拥有用于指定类名的配置元素的IConfigurationElement。你可以使用

IConfigurationElement configElement = ....;

Object classInstance = configElement.createExecutableExtension("class attribute name");

其中“类属性名称”是扩展点元素中指定要加载的类的属性名称。正在创建的类必须有一个无参数构造函数。

或者,您可以使用以下方法加载类:

Bundle bundle = Platform.getBundle("plugin id");

Class<?> theClass = bundle.loadClass("class name");

... construct as usual ...

如果你有IConfigurationElement,你可以使用获取插件ID

String pluginId = configElement.getContributor().getName();

【讨论】:

  • 我遇到了类似的问题,但是我没有使用上述方法访问类,而是添加了依赖项,即包含该类的包。不是一样的场景吗?
  • @JohnDoe 可以添加依赖项,但这并不总是可行的。您可能希望人们使用您的扩展点编写他们自己的插件 - 他们无法向您的插件添加依赖项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-25
相关资源
最近更新 更多