Help

Controls

PermLinkWikiLink
Switch Workspace

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Forum: Seam Users Forum ListTopic List
28. Apr 2008, 18:26 America/New_York | Link

Hi

I start project with Seam. I have question about using seam components out of box. I'm planning write seam components which will be available outside ejb container (of course with limited functionality, just pojo)

@Stateless @Name("register") public class RegisterAction implements Register {
   @In private User user; // omited getter and setter for readability
   @EJB private IPuRegisterLocal puRegister; // omited getter and setter for readability
   @Resource private Messages messages; // // encapsulate FacesMessages, omited getter and setter for readability
   public String register() {
        SerwerResponse resp = puRegister.registerUser(user);
        if (resp.success()) {
            return "registered";   
        } else {
            messages.add(res.errorMessage());
            return null;
        }
   }
}

Layer IPU* (PU - polish User Case) is responsible of database, transactions and business. Seam will be responsible for UI.

I this example @EJB can inject only local interface OR remote interface, it depends on choose IPuRegisterLocal or IPuRegisterRemote at compile time. I suppose ejb-jar.xml could move this configuration to runtime time. I would need more flexibility in injecting objects and could inject local or remote interfaces which depends on configuration in JAVA CODE. Any idea?

I had using Guice with success and I know it would be nice to use Guice with Seam. I will be sufficient for my needs. Many annotation @EJB and @Resource will be replaced with Guice @Inject and configured in Guice Module.

I have founded integration Guice with Jboss MC (new Jboss Microcontainer):

http://anonsvn.jboss.org/repos/jbossas/projects/microcontainer/trunk/guice-int/src/tests/org/jboss/test/guice/test/

Does Seam use Jboss MC? If Yes, I think I could inject Guice Injector with Jboss MC and Seam and get object from Guice Injector...

Cheers Kamil

17 Replies:
28. Apr 2008, 19:10 America/New_York | Link

Hi Kamil,

You might be interested in the Seam and Guice integration I've implemented. It doesn't use MC, but it works as an interceptor.

Basically, all you need to do is to annotate your Seam component with @Guice annotation and configure default Guice module to use in the components.xml file.

@Name("myComponent")
@Guice
public class MyComponent {
  @Inject MyObject myObject;
}

and the components.xml file:

<component name="org.jboss.labs.injection.seam.guiceModule"
              class="com.domain.YourGuiceModule"
              auto-create="true" scope="APPLICATION" startup="true"/>

The Guice injection will be triggered automatically :)

You can also use more than one Guice module. Just pass it's name to the @Guice annotation, like @Guice("myGuiceModule").

You will find the sources in the repository. I'm in the middle of writing some wiki page describing how to use it ;)

Cheers, -Pawel

Rating:  * * * * *
28. Apr 2008, 20:36 America/New_York | Link

Thanks, it sounds cool ;)

29. Apr 2008, 22:57 America/New_York | Link

Hello,

I've just finished implementing Seam and Guice integration. As I mentioned before, it's all about @Guice annotation :)

You can find more information, including configuration and usage examples, on the wiki page.

You can also download seam-guice.jar and give it a try. Source code is also available.

Let me know what you think. Or maybe, you know a better way to integrate Seam and Guice, like using ELResolver? Your feedback is welcome.

Cheers, -Pawel

04. May 2008, 15:18 America/New_York | Link
Pawel Wrzeszcz wrote on Apr 29, 2008 10:57 PM:
Let me know what you think. Or maybe, you know a better way to integrate Seam and Guice, like using ELResolver? Your feedback is welcome.

I think integration at annotation level is great. First seam inject its members and next guice inject own members and annotations may coexist.

I'm against EL variables, besause it uses not-typesafe Strings. It is Spring fashion and it is reason I chose Guice instead of Spring. All with typesafe annotations with Java Code, No XML with not-typesafe strings,

If I would write with not-typesafe coding I chose one of dynamic lanugage (jython, jruby) over Java+XML. It's only comparision ;)

My question: why do you use guice module as seam component (and it is stored in application context of seam) instead of Guice Injector. I this case If I would used guice context outside seam components (eg. in other interceptor) I had to create other Injector? IMHO (I'm not guice expert) In guice is one assumption: one injector, one context, And It fallows up one instance of singleton etc.

Kamil

06. May 2008, 11:59 America/New_York | Link
Kamil Demecki wrote on May 04, 2008 03:18 PM:
My question: why do you use guice module as seam component (and it is stored in application context of seam) instead of Guice Injector. I this case If I would used guice context outside seam components (eg. in other interceptor) I had to create other Injector? IMHO (I'm not guice expert) In guice is one assumption: one injector, one context, And It fallows up one instance of singleton etc. Kamil

Kamil, you're absolutely right! Thanks for pointing this out.

There is also a small thread safety issue. There might be 2 injectors for one module created in almost the same time and only the second one will be stored in cache (but the first one will be used as well).

I'm going to rewrite my interceptor to use injector instead of guice module :)

-Pawel

06. May 2008, 12:37 America/New_York | Link

If you put Injector into servlet context you get get it from everywhere.

Resolver can be used to automatically inject members on every resolved bean that still keeps everything typesafe.

Cheers, Tomek

06. May 2008, 16:48 America/New_York | Link
Pawel Wrzeszcz wrote on May 06, 2008 11:59 AM:
Kamil, you're absolutely right! Thanks for pointing this out. There is also a small thread safety issue. There might be 2 injectors for one module created in almost the same time and only the second one will be stored in cache (but the first one will be used as well). I'm going to rewrite my interceptor to use injector instead of guice module :) -Pawel

No problem ;) I saw this thread leak. I think If you declare Guice Injector as seam component in components.xml there will be no problem with threads? (I dont know so much seam components). On the other side your solution has good support for many modules. What will it look with many Guice Injector? (many declarations in components.xml or no chancy many injectors?)

Cheers Kamil

06. May 2008, 16:54 America/New_York | Link
Tomasz Szymanski wrote on May 06, 2008 12:37 PM:
If you put Injector into servlet context you get get it from everywhere.

I think seam component at aplication scope is good abstraction above servlet context.

Resolver can be used to automatically inject members on every resolved bean that still keeps everything typesafe.

I strongly prefer @Inject Guice Annotation instead of EL expression. Run Injector.injectMembers(seamcompononet) after inject members by seam and before using components methods is cool.

Hm, what with two interceptors: one for authetification and one for guice, which runs first? Interceptor for authentification can use object injected by Guice?

-- Cheers Kamil

07. May 2008, 11:24 America/New_York | Link
Kamil Demecki wrote on May 06, 2008 04:54 PM:
Hm, what with two interceptors: one for authetification and one for guice, which runs first? Interceptor for authentification can use object injected by Guice? -- Cheers Kamil

If you have your own auth interceptor, you can always enforce specific order of interceptors using within and around attributes of the @Interceptor annotation.

-Pawel

14. May 2008, 16:36 America/New_York | Link

Here it is. New, updated Seam and Guice integration :)

As for the Java code, almost nothing changes. You annotate your class with @Guice and it works.

I've made significant changes to the configuration. To initialize Guice support just put this to the components.xml file:

<components xmlns="http://jboss.com/products/seam/components" ...
            xmlns:guice="http://jboss.org/jbosslabs/seam-guice">
   ...
   <guice:init injector="#{myGuiceInjector}"/>
</components>

and provide your injector. Any EL expression that evaluates to Injector is valid here.

Moreover, if you just want to build an injector from modules, there is a convenient way to do so:

<guice:injector name="myGuiceInjector">
        <guice:modules>
           <value>com.example.guice.GuiceModule1</value>
           <value>com.example.guice.GuiceModule2</value>
        </guice:modules>
</guice:injector>

I've updated documentation and download page.

Enjoy.

-Pawel

Rating:  * * * * *
14. May 2008, 21:22 America/New_York | Link

It looks nice work ;)

This code is heavy used (on creating millions of seam beans) and I'm fan using log.isDebugEnabled() and log.isTraceEnabled(). I dont know how it is jboss politcs to logging and dont know real performance... just my habit ;p Which way logging you are using?

-- Kamil

20. May 2008, 17:35 America/New_York | Link
Kamil Demecki wrote on May 14, 2008 09:22 PM:
This code is heavy used (on creating millions of seam beans) and I'm fan using log.isDebugEnabled() and log.isTraceEnabled(). I dont know how it is jboss politcs to logging and dont know real performance... just my habit ;p Which way logging you are using?

Using Seam logger you don't have to care about it. If you have a look at the org.jboss.seam.log.LogImpl source code, it solves the issue with boring log.isDebugEnabled() :)

-P

22. May 2008, 13:11 America/New_York | Link
Pawel Wrzeszcz wrote on May 20, 2008 17:35:
Using Seam logger you don't have to care about it. If you have a look at the org.jboss.seam.log.LogImpl source code, it solves the issue with boring log.isDebugEnabled() :) -P

I Java arguments are evaluated at each method invocation, sometimes it cares and even sql is executed at simple log statement:

log.debug("user=" + user + ", roles=" + user.getRoles())

In such situation additional methods are executed: string concatenation and user methods user#toString() and user#getRoles(). if user#getRoles is lazy (normal case) addition sql is executed ;/

-- Kamil

23. May 2008, 12:59 America/New_York | Link

About twice computing values betore putting to cache there is section (number 5.19) in excellent book Java Concurrency in Practise ;)

-- Kamil

23. May 2008, 15:20 America/New_York | Link

Kamil,

Pawel was referring to the solution provided by the seam logger, which I can also recommend. You can find more information in the seam logging documentation.

This at least solves the problem with string concatenation, and if you want to prevent the lazy execution in the persistence layer, you might use EL. Example:

log.debug("user=#1, roles=#2", user, user.getRoles());

If you can use EL:

log.debug("user=#{user}, roles=#{user.roles}");

But as I can see from your previous comments, you don't really like to use EL in Java. I also don't use EL in logging, but the seam logging capabilities are really great, and I sometimes even use the in simple pojos. It's just much easier to read.

By the way, you can also use logging in all components that extend org.jboss.seam.framework.Controller which provides delegates to a class level org.jboss.seam.log.Log.

23. May 2008, 20:25 America/New_York | Link
Kariem Hussein wrote on May 23, 2008 15:20:
Kamil, Pawel was referring to the solution provided by the seam logger, which I can also recommend. You can find more information in the seam logging documentation.

Yes, I also aware of verbose code using log.isDebugEnabled(). In our system logging is making code more verbose (logging is mandatory). I'm thinking about using logging with AOP (most logging instruction are simply imformation about parameters from function) Result is short functions with annotations. It would be like:

Logger(Debug)
void smallFunction(int a, int b)
This at least solves the problem with string concatenation, and if you want to prevent the lazy execution in the persistence layer, you might use EL. Example:
log.debug("user=#1, roles=#2", user, user.getRoles());
If you can use EL:
log.debug("user=#{user}, roles=#{user.roles}");
But as I can see from your previous comments, you don't really like to use EL in Java. I also don't use EL in logging, but the seam logging capabilities are really great, and I sometimes even use the in simple pojos. It's just much easier to read.

Yes I'm not big fan of intesively using dynamic values when they aren't need. Refactoring and searching occurences of methods /atributes fails. (IMHO few occurences of EL are ok but not more than in 30% code)

At now would be helpfull some inner class and syntactic sugar like CICE. Example

log.debug("user#1 has roles: #2", LazyArguments { user, user.getRoles() })

And maybe in future some metaprogramming features will be available. Java is using intensively XML, SQL and String operations but there is not some STATIC typed - Language Builtin - Type Template supported by compiler. I would need executing some user code on compilation phase builtin in language. Compilation and runtime phases are too far.

Sample using type Template ($user and $user#getRoles() are static typed, refactorable, lazy evaluated):

log.debug(Template$$user: $user has roles $user#getRoles$$)
By the way, you can also use logging in all components that extend org.jboss.seam.framework.Controller which provides delegates to a class level org.jboss.seam.log.Log.

I don't know what you mean ;)

-- Kamil

20. Jun 2008, 15:06 America/New_York | Link

FYI, I've just blogged about Seam and Guice integration. I've also submitted it as a patch, so you can vote for it ;)

Thanks for your feedback, Kamil!

Pawel