Am 28.06.2011 10:08, schrieb Daniël van 't Ooster:

- This implementation assumes the web bundle knows about all bundles
providing services;

wicket-osgi currently assumes that the web application bundle (WAB) explicitly imports all packages or bundles which contribute Wicket components used by the application.

Otherwise, for the injection stuff, the WAB only needs to import the service interface packages, but not the implementation packages or bundles.

in our case (the case attached to WICKET-3737 is a
stripped down version), we have one 'web bundle', which hosts the Wicket
application; individual bundles provide pages and their mount points (in the
example case, bundles provide some panels).

Yes, I had a look at that example - it's a rather advanced scenario and far more than what I'm currently aiming at with wicket-osgi.

The first major goal I would like to achieve is support for the following scenario:

- OSGi Web Container and Web Application Bundles according to OSGi Enterprise Spec 4.2.

- Wicket is deployed as a plain old OSGi bundle.

- One or more WABs are deployed as separate bundles. Each WAB provides a Web Application according to the Servlet Spec. The WABs are completely isolated from each other, just like plain old WARs.

I don't think that your scenario with other bundles contributing new pages or resources to a running web application is currently covered by the OSGi Enterprise Spec. A WAB is always a single bundle, which may of course import packages and use services from other bundles, but for anything related to the Web Context Path, there is a one-to-one relation between context paths and bundles. At least that's my understanding, but I'm not in any of the Java EE or OSGi expert groups...

Of course you can attach OSGi fragments to your WAB as bundle host, but an independent bundle registering services that contribute to a web context owned by some other bundle is currently out of scope, I'd say.

Mind you, I'm not saying that your scenario doesn't make sense or cannot be done, but it sounds like the second or third step to me.

Do you have examples of any OSGi Web containers supports your flavour of multi-bundle WABs? So far, I've looked at Pax Web, Eclipse Gemini Web and Glassfish, and my impression is they all follow the rule "one web context, one bundle".

In cases like that, there is no
single class loader which knows all classes, so you need one bundle with a
DynamicImport-Package: *.

I'd say your assumption is right, but your conclusion is not... Let's say your WAB retrieves WebPages from the service registry and mounts them. To do so, it only needs to load the WebPage base class from Wicket, but not the implementation class from some other bundle.

In this situation, page deserialization will fail, because neither the Wicket bundle class loader nor your WAB nor the ThreadContextClassLoader can load the class from the contributor bundle.

But even then, there are other and better solutions than DynamicImport-Package, which I think is something like an emergency amputation when you have to save your application's life and need to use some third-party lib that simply doesn't play by OSGi rules.

> To reduce the number of bundle refreshes we
delegate this job to a tiny 'class resolver bundle', which exposes an
IClassResolver instance as OSGi service.

And this class resolver bundle still uses dynamic imports, right?

I'd suggest one of the following options:

1) Your contributor bundles provide an IContributor service for an interface exported by your WAB. Your WAB tracks all implementations, builds a composite ClassResolver from all their classloaders and registers the ClassResolver with Wicket.

2) Extender Pattern: You define a special manifest header that all your contributors need to include, then your WAB tracks bundle events, identifies its contributors from the manifest header and builds a composite ClassResolver as in 1).

In any case, I would leave wicket-bundle and wicket-osgi out of the game. There may be more than one WAB, each with a number of contributor bundles, and the Wicket bundle cannot decide how to match them up.

While generating JDK / CGLib proxies, you need a class loader which can
access all proxied classes, one way to solve this is a minor change to the
IClassResolver interface to get access to the almightly class loader. I have
added a method getClassLoader(), which is used in the DefaultClassResolver
to load classes. This simple change will save some code duplication in OSGi
compatible classResolvers.


What's your use case for these proxies? Do you create them at application level, or is this something that Spring DM does at framework level.

- Another difference is how OSGi services are used; we are using Spring DM,
which creates one applicationContext per bundle. Fields annotated with
@SpringBean will be injected with beans (imported OSGi reference is also a
bean) from the applicationContext of the bundle in which the component is
created.

The wicket-osgi test bundles uses OSGi Blueprint. And Blueprint is nothing but Spring DM standardized. However, wicket-osgi does NOT depend on Blueprint.

wicket-osgi supports injection of OSGI service references via @Inject. (This does not currently cover other Blueprint beans.)

I'm all in favour of injection by annotation - XML is not type safe and violates the DRY principle. The problem is, there are too many competing sets of annotations that all basically to the same thing:

- @Inject (JSR-330 and JSR-299 (CDI))
- @Autowired (Spring)
- @SpringBean (wicket-spring)
- @Inject + @OSGiService qualifier (Glassfish)
- @Reference, @Bean, @Service (Apache Aries)

I would love to see standardized annotations in the next version of the OSGi Blueprint specification. Until then, I think the most portable approach that does not tie you to any given implementation is @Inject + @Qualifier (JSR-330).


In my opinion, the advantage of this is that each bundle has to be
explicit about the services it depends on, spring beans do not have to be
unique, not all beans have to be exported as OSGi service and there is need
to register ServiceTracker instances (Spring DM solves this problem).


Replace Spring DM by Blueprint and you're portable. And you can move from Spring DM/Eclipse Gemini to Apache Aries which is the more solid and innovative implementation, IMHO.

[This is an Apache mailing list, so I had to say that ;-) ]

- Is it an idea to extend the wicket-osgi project with some classes which
support this pattern?

Absolutely.

So wicket-osgi will become the toolkit you need when
combining OSGi and Wicket? I think it would be nice when it has injectors
for services from the OSGi service registry, as well as the pattern in which
spring beans from the bundle application context are used (more similar to
wicket-spring, the only difference is you have multiple, small application
contexts). One attachment to WICKET-3737 contains the injector stack
required for wiring spring beans from the bundle application context into
wicket components (not completely finished).


The first step is already made with the current @Inject support. This is rather basic at the moment because it does not allow you to choose the one you need when there's more than one service for a given interface.

Second step: support a JSR-330 qualifier (e.g. @OSGiService) that wraps a filter and/or some service properties for service disambiguation.

Third step: additionally support injection of Blueprint Beans.

Any supporting framework classes for step 3 might have to move to a separate bundle wicket-blueprint, because step 1 and 2 do not depend on Blueprint. Service injection should work independent of the service registration method (programmatically, DS, Blueprint, whatever...)

Cheers,
Harald

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Reply via email to