Peaberry and ServletModule

212 views
Skip to first unread message

Evan Ruff

unread,
Aug 21, 2012, 1:04:30 AM8/21/12
to guice...@googlegroups.com
Hey guys,

I'm trying to convert my application over to OSGi. Previously, I was rocking a straight Jetty deployed WAR with Guice all over the place. As I've migrated it to Felix, I've got JUUUST about everything working, but I get some nasty error when trying to install a ServletModule. If I comment the ServletModule out of my Activator, it works as expected; however, when it's in there, I get this:

java.lang.NoClassDefFoundError: com/google/inject/internal/util/$Preconditions
at com.google.inject.servlet.ServletModule.configure(ServletModule.java:44)
at com.google.inject.AbstractModule.configure(AbstractModule.java:59)
at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:223)
at com.google.inject.AbstractModule.install(AbstractModule.java:118)

Which really kills just about anything.

I am attempting to register my GuiceFilter to the ExtHttpService, which works great when the ServletModule is commented out. The GuiceFilter registration looks like this:
service.registerFilter( new GuiceFilter(), "/*", null, 0, null );

Where am I going wrong here? I have confirmed that guice-servlet.jar is making it into my bundle, so I don't think that's the problem.

Any help would be greatly appreciated. Getting started with OSGi is... tedious...

Thanks!!

Evan



Stuart McCulloch

unread,
Aug 21, 2012, 8:34:24 AM8/21/12
to guice...@googlegroups.com
What version of guice (and guice-servlet) are you using and did you get the bundles from google-code/maven-central or Eclipse Orbit? What does the headers command show (on the Felix console) for the guice and guice-servlet bundles when they're installed?

The guice-servlet bundle is currently shipped as a fragment to the main guice bundle, as it relies on an internal non-exported package. Since it's a fragment it should be able to see the internal Preconditions class - note that the reason for the dollar prefix on the classname is because this is a relocated/embedded copy of the Guava Preconditions class. You might want to make sure that the guice and guice-servlet bundles are at the same level and come from the same source, since some vendors (such as Eclipse Orbit) decided to repackage the guice bundle and tweak the contents/metadata.

Evan Ruff

unread,
Aug 21, 2012, 9:07:52 AM8/21/12
to guice...@googlegroups.com
Stuart,

Thank you so much for your reply. I'm just taking blind stabs at the problem and it's great to hear that what I'm doing isnt stupid/crazy!

I am using the Maven Central Repository. At the top-level of my project, I have the following entries:

       <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>3.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.inject.extensions</groupId>
            <artifactId>guice-servlet</artifactId>
            <version>3.0</version>
        </dependency>
        <dependency>
            <groupId>com.googlecode.guava-osgi</groupId>
            <artifactId>guava-osgi</artifactId>
            <version>11.0.1</version>
        </dependency>
<dependency>
            <groupId>org.ops4j</groupId>
            <artifactId>peaberry</artifactId>
            <version>1.2</version>
        </dependency>

I put the guava dependency in there in an attempt to resolve this error. I'm not actually using Guava in any other classes.

E

Stuart McCulloch

unread,
Aug 21, 2012, 11:17:24 AM8/21/12
to guice...@googlegroups.com
I've uploaded a simple example of using guice-servlet in OSGi (based on http://svn.apache.org/repos/asf/felix/trunk/http/samples/filter/)


   # to rebuild the example:   cd maven-build ; mvn clean install ; cp target/guice-servlet-osgi-example-0.1.0-SNAPSHOT.jar ../felix-framework/bundle/

   # to launch the example:   cd felix-framework ; java -jar bin/felix.jar

   # to view example servlet:   http://127.0.0.1:8080/example/test/message.html

It doesn't use peaberry at the moment, but it should be straightforward to extend as necessary.

Hopefully this should help diagnose what's wrong in your environment by providing some sort of baseline to 'diff' against.

PS. you might want to try removing your felix-cache in case it's caching some old bundles.

--
Cheers, Stuart

--
You received this message because you are subscribed to the Google Groups "Guice and OSGi" group.
To view this discussion on the web visit https://groups.google.com/d/msg/guice-osgi/-/0LtAiEEC4vIJ.
To post to this group, send email to guice...@googlegroups.com.
To unsubscribe from this group, send email to guice-osgi+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/guice-osgi?hl=en.

Evan Ruff

unread,
Aug 21, 2012, 1:14:26 PM8/21/12
to guice...@googlegroups.com
Hey Stuart,

Thanks for the examples! I'll give them a try and figure out where my thing is going off the rails.

Thanks man!

E

Evan Ruff

unread,
Aug 22, 2012, 8:31:31 AM8/22/12
to guice...@googlegroups.com, evan...@hendersonsawmill.com
Hey Stuart,

I've got my ServletModule listening and everything is going great. The one thing I hit a snag on was getting the OSGi-published services from Peaberry in there. It was quite simple actually, just needed to create my GuiceListener as so:

GuiceFilter guiceFilter = Guice.createInjector( osgiModule( bundleContext ), new CoreImportModue() ).getInstance( GuiceFilter.class );

For others trying to get it going, I needed to pass the osgiModule( bundleConext ) in there as well. That binds everything up a usual. Also, for all the people out there rocking the Felix/Jetty combo, the servlet listener binding is a little funny: 

httpService.registerFilter( CoreActivator.this.guiceFilter, "/.*", null, 0, null );

Notice the "/." as the context path. This differs a little bit from the standard Jetty Webserver component.

I do have one question about the Peaberry thing. When I update a bundle and another Activator attempts to bind to one of my interfaces, will this over write the current binding and automatically inject the new bundle into my servlet on next run?

Thanks,

E

Stuart McCulloch

unread,
Aug 23, 2012, 6:01:59 AM8/23/12
to guice...@googlegroups.com
On 22 Aug 2012, at 13:31, Evan Ruff wrote:

Hey Stuart,

I've got my ServletModule listening and everything is going great. The one thing I hit a snag on was getting the OSGi-published services from Peaberry in there. It was quite simple actually, just needed to create my GuiceListener as so:

GuiceFilter guiceFilter = Guice.createInjector( osgiModule( bundleContext ), new CoreImportModue() ).getInstance( GuiceFilter.class );

For others trying to get it going, I needed to pass the osgiModule( bundleConext ) in there as well. That binds everything up a usual. Also, for all the people out there rocking the Felix/Jetty combo, the servlet listener binding is a little funny: 

httpService.registerFilter( CoreActivator.this.guiceFilter, "/.*", null, 0, null );

Notice the "/." as the context path. This differs a little bit from the standard Jetty Webserver component.

Yes, that threw me as well at first - it appears to be specific to the ExtHttpService implementation:


where the filter string is a regular expression rather than a glob pattern.

I do have one question about the Peaberry thing. When I update a bundle and another Activator attempts to bind to one of my interfaces, will this over write the current binding and automatically inject the new bundle into my servlet on next run?

Standard Guice bindings are static to the bundle (unless it is restarted of course) - bindings that use peaberry to import services are dynamic (it uses a proxy under the covers) and delegate to the highest ranked, oldest matching service. That's the same semantics as in OSGi, but you could always use a decorator to change this behaviour - see the various Decorator classes under util/decorators for some examples. Services typically come from the OSGi service registry (but you can actually use your own registry implementation) which is how you can interoperate with other component models, such as DS/Blueprint/iPOJO, etc. Ditto for exported services.


To view this discussion on the web visit https://groups.google.com/d/msg/guice-osgi/-/HykzdG--F1kJ.
Reply all
Reply to author
Forward
0 new messages