使用 OSGi HTTP 服务启动 Wicket Web 应用程序

发布于 2024-08-24 12:19:46 字数 1724 浏览 4 评论 0原文

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

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

我也尝试过使用 Felix白板实现并将 Web 服务注册为 Servlet 之一:

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 一起工作仍然失败。

欢迎任何光。

I'm trying to start a Wicket Application using Felix implementation of OSGi HTTP service, for that I just register the service using WicketServlet with applicationClassName parameter:

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

I have also tried using Felix Whiteboard implementation and registering the web service as a Servlet one:

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

In both cases it fails when I deploy it using Pax Runner and Felix (mvn package install pax:run -Dframework=felix -Dprofiles=log,config), the exception seems to be related with the 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)
....
....

I have tried to export everything in the bundle and it does the same.

The strangest thing is that it works perfectly if I deploy it using Equinox (mvn package install pax:run -Dframework=felix -Dprofiles=log,config).

It seems to be a visibilty issue, but I don't know how to fix it, am I doing something wrong? Should I try to extend WicketServlet to take control on the instantiation of the application? Or maybe using an application Factory?

Update: Or maybe using an application Factory?

I tried to set the parameter applicationFactoryClassName to ContextParamWebApplicationFactory.class.getName() it and didn't help, still failing with felix and working with equinox.

Any light is welcomed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独夜无伴 2024-08-31 12:19:46

这里的问题是 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。

The problem here is that Wicket seems to load the applicationClass badly. I have not looked at the code that does this, but I suspect it's using current thread's context classloader.

I did the following to overcome this:

  1. Create my own WicketFilter (called MyWicketFilter) and override getClassLoader. This returns this.getClass().getClassLoader().
  2. Register the MyWicketFilter as a Filter service to be picked up by the whiteboard http service.

Code for activator start:

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);

Code for MyWicketFilter:

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

You can also use WicketServlet, but this involves overriding
newWicketFilter and return MyWicketFilter from here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文