【问题标题】:How to use Java-8 default-interface-implementation in a OSGi-Service如何在 OSGi 服务中使用 Java-8 默认接口实现
【发布时间】:2014-11-26 12:42:27
【问题描述】:

我想在应该支持 Java 8 的最新 Apache-Karaf 版本 (3.0.2) 上使用 Java 8 功能。

我的域层(存储库)中有一个服务接口,它有一个用于身份生成的默认方法

public interface MyRepository{

    ...

    default MyId nextIdentity() {
        return new MyId(UUID.randomUUID().toString().toUpperCase());
    }
}

然后我有一个该接口的实现,它使用蓝图 (Apache-Aries) 作为 OSGi 服务公开。

当我运行我的应用程序时,捆绑包安装成功,服务被注册,但是当应用程序层调用方法 nextIdentity 时,我得到一个异常。

IncompatibleClassChangeError: Found interface MyRepository, but class was expected

应用层是直截了当的:通过蓝图注入其类(在本例中为 OSGi-Service-Reference)的接口属性。

我确实检查了编译:所有模块都在 Eclipse 中使用 Java 8 合规级别编译。我猜这个问题与不是 Java 8 的 aries-proxy 有关,但由于 karaf 支持它......

编辑:添加堆栈跟踪

org.apache.wicket.WicketRuntimeException: Can't instantiate page using constructor 'public bikeshop.http.wicket.page.GaragePage()'. Might be it doesn't exist, may be it is not visible (public).
    at org.apache.wicket.session.DefaultPageFactory.newPage(DefaultPageFactory.java:193)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.session.DefaultPageFactory.newPage(DefaultPageFactory.java:66)[92:org.apache.wicket.core:6.7.0]
    at org.ops4j.pax.wicket.internal.PaxWicketPageFactory.newPage(PaxWicketPageFactory.java:76)[100:org.ops4j.pax.wicket.service:3.0.2]
    at org.apache.wicket.DefaultMapperContext.newPageInstance(DefaultMapperContext.java:133)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.core.request.handler.PageProvider.resolvePageInstance(PageProvider.java:268)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.core.request.handler.PageProvider.getPageInstance(PageProvider.java:166)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.request.handler.render.PageRenderer.getPage(PageRenderer.java:78)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.request.handler.render.WebPageRenderer.respond(WebPageRenderer.java:244)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.core.request.handler.RenderPageRequestHandler.respond(RenderPageRequestHandler.java:165)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:854)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.request.RequestHandlerStack.execute(RequestHandlerStack.java:64)[91:org.apache.wicket.request:6.7.0]
    at org.apache.wicket.request.cycle.RequestCycle.execute(RequestCycle.java:254)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:211)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:282)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.protocol.http.WicketFilter.processRequestCycle(WicketFilter.java:259)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByCGLIB$$91ca4a1b.CGLIB$processRequestCycle$4(<generated>)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByCGLIB$$91ca4a1b$$FastClassByCGLIB$$36c566fa.invoke(<generated>)[92:org.apache.wicket.core:6.7.0]
    at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)[99:org.apache.servicemix.bundles.cglib:2.2.2.1]
    at org.ops4j.pax.wicket.internal.servlet.PAXWicketServlet$WicketFilterCallback.intercept(PAXWicketServlet.java:150)[100:org.ops4j.pax.wicket.service:3.0.2]
    at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByCGLIB$$91ca4a1b.processRequestCycle(<generated>)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:201)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByCGLIB$$91ca4a1b.CGLIB$processRequest$12(<generated>)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByCGLIB$$91ca4a1b$$FastClassByCGLIB$$36c566fa.invoke(<generated>)[92:org.apache.wicket.core:6.7.0]
    at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)[99:org.apache.servicemix.bundles.cglib:2.2.2.1]
    at org.ops4j.pax.wicket.internal.servlet.PAXWicketServlet$WicketFilterCallback.intercept(PAXWicketServlet.java:150)[100:org.ops4j.pax.wicket.service:3.0.2]
    at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByCGLIB$$91ca4a1b.processRequest(<generated>)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:282)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByCGLIB$$91ca4a1b.CGLIB$doFilter$10(<generated>)[92:org.apache.wicket.core:6.7.0]
    at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByCGLIB$$91ca4a1b$$FastClassByCGLIB$$36c566fa.invoke(<generated>)[92:org.apache.wicket.core:6.7.0]
    at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)[99:org.apache.servicemix.bundles.cglib:2.2.2.1]
    at org.ops4j.pax.wicket.internal.servlet.PAXWicketServlet$WicketFilterCallback.intercept(PAXWicketServlet.java:150)[100:org.ops4j.pax.wicket.service:3.0.2]
    at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByCGLIB$$91ca4a1b.doFilter(<generated>)[92:org.apache.wicket.core:6.7.0]
    at org.ops4j.pax.wicket.internal.servlet.PAXWicketServlet.service(PAXWicketServlet.java:98)[100:org.ops4j.pax.wicket.service:3.0.2]
    at org.ops4j.pax.wicket.internal.filter.PAXWicketFilterChain.doFilter(PAXWicketFilterChain.java:61)[100:org.ops4j.pax.wicket.service:3.0.2]
    at org.ops4j.pax.wicket.internal.filter.FilterDelegator.doFilter(FilterDelegator.java:82)[100:org.ops4j.pax.wicket.service:3.0.2]
    at org.ops4j.pax.wicket.internal.servlet.ServletCallInterceptor.service(ServletCallInterceptor.java:168)[100:org.ops4j.pax.wicket.service:3.0.2]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:69)[80:org.ops4j.pax.web.pax-web-jetty:3.1.2]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:240)[80:org.ops4j.pax.web.pax-web-jetty:3.1.2]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:77)[80:org.ops4j.pax.web.pax-web-jetty:3.1.2]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.server.Server.handle(Server.java:370)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
    at java.lang.Thread.run(Thread.java:745)[:1.8.0_20]
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)[:1.8.0_20]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)[:1.8.0_20]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)[:1.8.0_20]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)[:1.8.0_20]
    at org.apache.wicket.session.DefaultPageFactory.newPage(DefaultPageFactory.java:174)[92:org.apache.wicket.core:6.7.0]
    ... 61 more
Caused by: java.lang.IncompatibleClassChangeError: Found interface bikeshop.domain.repository.BikeRepository, but class was expected
    at Proxy04d92f46_988d_4726_9355_6b6381790fde.nextIdentity(Unknown Source)
    at bikeshop.application.service.BikeApplicationService.loadGarage(BikeApplicationService.java:22)
    at Proxyc25af47a_a344_4a1b_8d0e_429a76d453c6.loadGarage(Unknown Source)
    at Proxy163e0a74_12bc_4124_827b_2119133222e8.loadGarage(Unknown Source)
    at bikeshop.presentation.internal.GaragePresentationService.init(GaragePresentationService.java:21)
    at Proxy5a3bd46a_6830_438c_b5eb_0ca9ec091479.init(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.8.0_20]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)[:1.8.0_20]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_20]
    at java.lang.reflect.Method.invoke(Method.java:483)[:1.8.0_20]
    at org.ops4j.pax.wicket.util.proxy.LazyInitProxyFactory$JdkHandler.invoke(LazyInitProxyFactory.java:253)
    at org.ops4j.pax.wicket.util.proxy.$Proxy22.init(Unknown Source)
    at bikeshop.http.wicket.page.GaragePage.<init>(GaragePage.java:30)

【问题讨论】:

  • 听起来至少有一个组件正确支持 Java 8。
  • 我猜它是 aries-proxy。但是,如果没有堆栈跟踪,很难找出真正的原因。
  • 通常我不喜欢添加 Stacktraces,因为我不想给其他人增加负担,并且因为我认为我错过了一些重要的细节 :) 在这种情况下,我认为提供一个可能会更好。跨度>
  • "Proxy04d92f46_988d_4726_9355_6b6381790fde.nextIdentity(Unknown Source)":这就是我真正喜欢的魔法技术 :)
  • 好吧,我想我们应该更清楚地了解 Java8 支持。它可以与 Java8 JVM 一起运行,但并非 Java8 的所有新功能都始终可用。尤其是使用 JDK7 编译 Aries Blueprint 并确保它向后兼容 JDK6。不支持只能使用 JDK8 运行的新特性。

标签: osgi java-8 apache-karaf


【解决方案1】:

这里的罪魁祸首可能是 Blueprint,它为每个导入的服务生成一个代理类,而不是直接给你服务对象。我不认为 Aries 蓝图已针对 Java 8 兼容性进行了更新。

解决方案是避免蓝图并使用声明式服务 (DS) 之类的东西,它更接近“真正的”OSGi 服务,并为您的消费者提供实际的服务实例。 DS 绝对适用于具有默认方法的 Java 8 接口。

【讨论】:

  • 我一开始使用 DS,但为 karaf-jpa 示例切换到 Blueprint。 Blueprint 的原因实际上是由我的需求驱动的:集成 JPA。我知道 OSGi 社区对 Blueprint 不满意,但来自标准 JEE 我需要从“标准”(Spring、JPA、...)缓慢迁移到 OSGi。据我所知,DS 只能注入 OSGi-Services(我想请求服务可能比使用注入组合类更好),但是对于缓慢的迁移,有必要提供一些 bean-injection 作为好。离题的要求就这么多了:-)
  • 查看堆栈跟踪,我在任何地方都看不到蓝图。我确实看到了 Pax Wicket 代理:org.ops4j.pax.wicket.util.proxy。所以这可能是 Java 8 而不是 Blueprint 的 Pax Wicket 问题。
  • 如果您正在寻找更纯粹的 OSGi 方式的 JPA 支持,请查看 Amdatu JPA:amdatu.org/components/jpa.html。不需要蓝图:)
  • 感谢 Amdatu-Link。我还发现 enRoute-examples (github.com/osgi/osgi.enroute.blog/tree/10-jpa) 非常有趣……我只需要弄清楚 bndtools 如何通过 JPM 解决依赖关系。在我的示例中,我复制了 Local-Repo 中的所有内容
【解决方案2】:

更新:

这个问题似乎在 Aries / Karaf 4.2.3 的 proxy-impl 1.1.4 中得到修复

KARAF-6087

ARIES-1849

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-17
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    • 2015-12-16
    相关资源
    最近更新 更多