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.
| Online: | 15 Members of 9400 |
| Forum: Seam Users |
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
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
:: pawel.wrzesz.cz/blog :: Seam exam at JavaBlackBelt ::
Thanks, it sounds cool ;)
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
:: pawel.wrzesz.cz/blog :: Seam exam at JavaBlackBelt ::
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
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
:: pawel.wrzesz.cz/blog :: Seam exam at JavaBlackBelt ::
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
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
I think seam component at aplication scope is good abstraction above servlet context.
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
If you have your own auth interceptor, you can always enforce specific order of interceptors using and attributes of the @Interceptor annotation.
-Pawel
:: pawel.wrzesz.cz/blog :: Seam exam at JavaBlackBelt ::
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
:: pawel.wrzesz.cz/blog :: Seam exam at JavaBlackBelt ::
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
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
:: pawel.wrzesz.cz/blog :: Seam exam at JavaBlackBelt ::
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
About twice computing values betore putting to cache there is section (number 5.19) in excellent book ;)
-- Kamil
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.
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:
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):
I don't know what you mean ;)
-- Kamil
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
:: pawel.wrzesz.cz/blog :: Seam exam at JavaBlackBelt ::