【问题标题】:Starting Wicket web application with OSGi HTTP Service使用 OSGi HTTP 服务启动 Wicket Web 应用程序
【发布时间】:2011-01-26 19:09:09
【问题描述】:

我正在尝试使用 OSGi HTTP 服务的 Felix 实现来启动 Wicket 应用程序,为此我只需使用 WicketServletapplicationClassName 参数注册服务:

props.put("applicationClassName", MainApplication.class.getName());
service = (HttpService)context.getService(httpReference);
service.registerServlet("/", new WicketServlet(), props, null);

我也尝试过使用 Felix Whiteboard 实现并将 Web 服务注册为Servlet one:

props.put("alias", "/");
props.put("init.applicationClassName", MainApplication.class.getName());
registration = context.registerService(Servlet.class.getName(), new WicketServlet(), props);

在这两种情况下,当我使用 Pax Runner 和 Felix (mvn package install pax:run -Dframework=felix -Dprofiles=log,config) 部署它时,它都会失败,异常似乎与 ClassLoader 有关:

[Jetty HTTP Service] ERROR org.apache.felix.http.whiteboard - Failed to register servlet
org.apache.wicket.WicketRuntimeException: Unable to create application of class es.warp.sample.HTTPLocalGUI.MainApplication
....
....
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
....
....

我已尝试导出捆绑包中的所有内容,但效果相同。

最奇怪的是,如果我使用 Equinox (mvn package install pax:run -Dframework=felix -Dprofiles=log,config) 部署它,它可以完美运行。

这似乎是一个可见性问题,但我不知道如何解决它,我做错了什么吗?我应该尝试扩展WicketServlet 以控制应用程序的实例化吗?或者也许使用应用程序工厂?

更新:或者可能使用应用程序工厂?

我尝试将参数 applicationFactoryClassName 设置为 ContextParamWebApplicationFactory.class.getName() 并没有帮助,仍然无法使用 felix 并使用 Equinox。

欢迎任何光线。

【问题讨论】:

    标签: osgi wicket embedded-jetty apache-felix httpservice


    【解决方案1】:

    这里的问题是 Wicket 似乎加载了 applicationClass 很糟糕。我没有查看执行此操作的代码,但我怀疑它正在使用当前线程的上下文类加载器。

    我做了以下事情来克服这个问题:

    1. 创建我自己的WicketFilter(称为MyWicketFilter)并覆盖getClassLoader。这将返回 this.getClass().getClassLoader()
    2. MyWicketFilter注册为过滤器服务,以供白板http服务获取。

    激活器启动代码:

    Hashtable<String, String> props = new Hashtable<String, String>();
    props.put("pattern", "/.*");
    props.put("init.applicationClassName", MyApplication.class.getName());
    
    final MyWicketFilter service = new MyWicketFilter();
    context.registerService(Filter.class.getName(), service, props);
    

    MyWicketFilter 的代码:

    public final class MyWicketFilter
        extends WicketFilter
    {
        @Override
        protected ClassLoader getClassLoader()
        {
            return this.getClass().getClassLoader();
        }
    }
    

    您也可以使用WicketServlet,但这涉及覆盖 newWicketFilter 并从这里返回 MyWicketFilter。

    【讨论】:

    • 知道为什么它似乎不适合我吗?而不是激活器启动中的代码,我将其设置在我的 web.xml 文件中: wicket.web-hubcom.hub.web.base.MyWicketFilter applicationClassNamecom.hub.web.base.WicketApplication
    猜你喜欢
    • 2011-01-31
    • 1970-01-01
    • 2011-02-02
    • 2016-03-12
    • 1970-01-01
    • 2013-06-14
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多