Ever wondered why JSF doesn’t support bean @Inject-ion in Converters or Validators? Ever wondered how to listen to a single PhaseEvent or ComponentSystemEvent, or filter on events by componentId, or view? Ever wondered why you can’t just @Inject FacesContext, or NavigationHandler?
Well… now you can, with the brand-new, just-out release of Seam Faces — 3.0.0.Alpha3
<dependency>
<groupId>org.jboss.seam.faces</groupId>
<artifactId>seam-faces</artifactId>
<version>3.0.0.Alpha3</version>
</dependency> |
<dependency>
<groupId>org.jboss.seam.faces</groupId>
<artifactId>seam-faces</artifactId>
<version>3.0.0.Alpha3</version>
</dependency>
(Currently only available through
Maven)
Note: For Jetty Users:
I’ve figured out how to resolve the “Could not wrap External Context” problem. You can find the solution in the first issue (first link)
https://jira.jboss.org/browse/WELDX-126
https://jira.jboss.org/browse/WELD-584
You can implement this in your application for now, but it should eventually be included in Weld-Extensions, which is why I’ve filed issues for it (and for the incorrect weld documentation.)
Sample some features:
Focused on harnessing the power of Weld/CDI for Java, Seam Faces 3.0.0 has a good deal to offer, and more is in the works. Take a look below to see some of the powerful new functionality you’ll be able to deliver with your JSF 2.0 application. (View the latest
user’s guide.)
No more statics!
With Seam Faces, you’ve got no more statics! Unit test with ease. Seam Faces breaks the static
FacesContext.getCurrentInstance().getExternalContext()
anti-pattern by
producing these artifacts for easy @Inject-ion.
public class ExampleBean {
@Inject ExternalContext context;
@Inject FacesContext context;
@Inject NavigationHandler handler;
} |
public class ExampleBean {
@Inject ExternalContext context;
@Inject FacesContext context;
@Inject NavigationHandler handler;
}
Now unit tests can draw upon a mock faces context, such as:
@RequestScoped public class MockFacesContext extends FacesContext {
// mock stuff here
} |
@RequestScoped public class MockFacesContext extends FacesContext {
// mock stuff here
}
This works perfectly, for example, if you were using JBoss
Arquillian (the future of integration testing) to do real in-container testing; your test setup would look something like
this.
Converter/Validator Injection:
By default, JSF treats Converters and Validators like “dumb objects.” It creates and throws them away whenever it pleases. With Seam, you can take back control of these artifacts. Take the following example converter, for instance:
As you can see below, this class is SessionScoped, meaning the user will retain the same Converter for the duration of the session. In other words: this converter is stateful. It supports @Inject! Not only that, but you can register
interceptors and
decorators on JSF Converters/Validators. They are beans just like any other CDI-managed object!
Note: If you do not @Scope your converter/validator, it will not be stateful, and the only enhanced support will be @Inject. @PreDestroy and @PostConstruct lifecycle callbacks will not function – the bean is not managed by CDI, only injected.
@SessionScoped
@FacesConverter("authorConverter")
public class AuthorConverter implements Converter
{
@Inject
FacesContext context;
@PostConstruct
public void setup()
{
System.out.println("AuthorConverter started up");
}
@PreDestroy
public void shutdown()
{
System.out.println("AuthorConverter shutting down");
}
@Override
public Object getAsObject(final FacesContext arg0, final UIComponent arg1, final String name)
{
System.out.println("getAsObject - Context is: " + context);
return new Author(name);
}
@Override
public String getAsString(final FacesContext arg0, final UIComponent arg1, final Object author)
{
System.out.println("getAsString - Context is: " + context);
if (author instanceof Author)
{
return ((Author) author).getName();
}
return "";
}
} |
@SessionScoped
@FacesConverter("authorConverter")
public class AuthorConverter implements Converter
{
@Inject
FacesContext context;
@PostConstruct
public void setup()
{
System.out.println("AuthorConverter started up");
}
@PreDestroy
public void shutdown()
{
System.out.println("AuthorConverter shutting down");
}
@Override
public Object getAsObject(final FacesContext arg0, final UIComponent arg1, final String name)
{
System.out.println("getAsObject - Context is: " + context);
return new Author(name);
}
@Override
public String getAsString(final FacesContext arg0, final UIComponent arg1, final Object author)
{
System.out.println("getAsString - Context is: " + context);
if (author instanceof Author)
{
return ((Author) author).getName();
}
return "";
}
}
PhaseEvent Observers
Let’s say you want to observe a JSF PhaseEvent. Now, instead of registering an entire PhaseListener class in faces-config.xml, simply create an
observer method!
public void observeBefore(@Observes @Before PhaseEvent e)
{
// Listens to all phases, before the phase
}
public void observeAfter(@Observes @After @RenderResponse PhaseEvent e)
{
// Listens to the RenderResponse phase, after the phase
} |
public void observeBefore(@Observes @Before PhaseEvent e)
{
// Listens to all phases, before the phase
}
public void observeAfter(@Observes @After @RenderResponse PhaseEvent e)
{
// Listens to the RenderResponse phase, after the phase
}
This gives us an incredible amount of control when listening to specific phases. We no longer have to write boiler-plate code to determine which phases your listener cares about, just filter using @Annotations!
Additional Scope Annotations:
JSF 2.0 introduced the concept of
@javax.faces.bean.ViewScoped
and
@javax.faces.bean.FlashScoped
, but only provided an annotation for the View Scope!
Seam Faces goes the extra mile, and provides the @FlashScoped annotation, which means that a bean in this scope will be stored in the JSF Flash. @ViewScoped means that the object will be stored in the UIViewRoot, unique for each JSF View/Page.
That’s all for now.
There are more features, and more that are coming, but for now — that should get you started 😉 Try it out;
get involved with the project; tell us what you think!
I started off with a simple Weld Maven Archetype project and added seam-faces dependency into the project. When deploying into GlassfishV3, the project crashed with NPE:
java.lang.NullPointerException
at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:731)
at org.jboss.seam.faces.util.BeanManagerUtils.getContextualInstance(BeanManagerUtils.java:69)
at org.jboss.seam.faces.environment.SeamApplicationWrapper.createValidator(SeamApplicationWrapper.java:88)
at com.sun.faces.component.validator.ComponentValidators.addValidatorsToComponent(ComponentValidators.java:291)
at com.sun.faces.component.validator.ComponentValidators.addDefaultValidatorsToComponent(ComponentValidators.java:158)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.processValidators(ComponentTagHandlerDelegateImpl.java:366)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.privateOnComponentPopulated(ComponentTagHandlerDelegateImpl.java:347)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:215)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:114)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:91)
at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:120)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:204)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:114)
Is this with Alpha1 or Alpha2?
Could you email me your example? I think the problem may be with the Archetype, but… I need to see your configuration/etc.
It would be a great help.
Thanks!
This is Alpha2. Tried it with latest Netbeans 6.9beta with bundled GlassfishV3 (3.0.1-b14). FYI, just a while ago I tried to deploy the project on JBossAS6 M2, which couldn’t start it up properly either. Probably just noob mistake on my part.
I sent an example through admin@ocpsoft.com. I apologize if this isn’t the one to use. You can try to contact me via my email if needed.
You found a nasty bug! This was revealed by the dependency on hibernate validation. Fixed now, thank you!
The SeamApplicationWrapper was blowing up when JSF requested a validator CDI didn’t know how to produce.
To get the latest version, do:
svn co http://anonsvn.jboss.org/repos/seam/modules/faces/trunk seam-faces
cd seam-faces
mvn install
I’m on another machine now. At first I had a bit of problem building the code, but things went smoothly once I manually added JBoss Repository into the POM.
Trying to deploy the project again, this time it worked and able to started up as expected on GlassfishV3. Thanks a bunch! 🙂
Awesome! Thank you — yes, I forgot that you probably needed the weld-parent POM, which would have required the jboss repo to build.
Let me know if you find anything else or if there’s anything else you think should be included to make your (and everyone’s) life easier!
I am trying test, and I get the same NullPointerException than bboy has received. How I fix it?
Try the latest version from the trunk. All issues related to this should be resolved (the next release is Alpha 3, and will include these fixes.) Turns out there’s a Bug in Weld/CDI that causes this, but we found a workaround while that gets fixed.
I try use short-ly example, just change pom.xml ( seam-faces to Alpha2 ), and I get a NullPointerException
That’s because Alpha 2 has the bug 😉 You’ll have to get a SNAPSHOT build to get the latest version:
http://oss.sonatype.org/content/repositories/jboss-snapshots/org/jboss/seam/faces/seam-faces/3.0.0-SNAPSHOT/
Try that.
Running the snapshot version on Jetty (with weld-servlet-1.0.1-Final.jar) gives me the following exception:
org.jboss.weld.exceptions.DefinitionException: Exception #0 :java.lang.RuntimeException: by java.lang.IllegalAccessError: class org.jboss.weld.extensions.core.CoreExtension_$$_javassist_3 cannot access its superclass org.jboss.weld.extensions.core.CoreExtension
at org.jboss.weld.bootstrap.events.AbstractDefinitionContainerEvent.fire(AbstractDefinitionContainerEvent.java:45)
at org.jboss.weld.bootstrap.events.ProcessAnnotatedTypeImpl.fire(ProcessAnnotatedTypeImpl.java:44)
at org.jboss.weld.bootstrap.BeanDeployer.addClass(BeanDeployer.java:61)
at org.jboss.weld.bootstrap.BeanDeployer.addClasses(BeanDeployer.java:88)
at org.jboss.weld.bootstrap.BeanDeployment.deployBeans(BeanDeployment.java:134)
at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:377)
at org.jboss.weld.environment.servlet.Listener.contextInitialized(Listener.java:207)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
at org.mortbay.jetty.Server.doStart(Server.java:224)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at de.gmorling.moapa.vehiclemanager.main.JettyRunner.main(JettyRunner.java:33)
Do you have any idea, what could be the issue here?
Thanks, Gunnar
Hi
I am getting the following error with the latest seam-faces 3.0.0 snapshot.
CONFIGURATION FAILED! WELD-001308 Unable to resolve managed beans for Types: [class org.jboss.seam.faces.component.FormValidationTypeOverrideExtension]; Bindings: [@javax.enterprise.inject.Default()]
I am getting this error while deploying this in Glassfish 3.
can you please let me know how to resolve this ?
Seam Faces Alpha 3 is out, try that and see if you have the same problem. You might need to get it straight from the JBoss releases Maven Repository:
org.jboss.seam.faces:seam-faces:3.0.0.Alpha3
http://community.jboss.org/wiki/MavenGettingStarted-Users
Hi
I am still getting this error in glassfish 3 even after using Alpha 3
org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308 Unable to resolve managed beans for Types: [class org.jboss.seam.faces.component.FormValidationTypeOverrideExtension]; Bindings: [@javax.enterprise.inject.Default()]
Can you please let me know how to resolve this ?
What version of GlassFish 3?
What version of Weld?
Can you send a project that reproduces this?
Are you using Maven?
What artifactId did you include?
Thanks,
Lincoln
Hi
I am using Glassfish 3.0.1 b19. Weld 1.0.1 final. Yes I can prepare a sample project and send it over. Where do i send it ? I use maven 2.2.1. I downloaded seam-faces-api and seam-faces 3.0.0.alpha3 and installed it my local maven repository.
When I am trying to deploy the EAR i get this error.
I can’t seem to reproduce. Works on all versions of GlassFish/JBoss that I’ve tried.
please email to lincoln@ocpsoft.com
Hi
I kind of figured out why this is happening. When i create a web application and deploy as war things work fine. However, when I use a EAR with one ejb module and one web module , and both of them use CDI/Weld, this error happens. seam-faces jar is in WEB-INF/lib directory. However , if I move it up and make it in the same level as ejb jar file and war file, this again works fine. However for the custom validators I use and they are part of WEB-INF/classes I am getting this error now ( WELD-001308 Unable to resolve managed beans for Types). Do i need to create a jar for these as well and move it outside WEB-INF/classeds ?
Do you think this maY be a classloader setting in Glassfish 3.0.1 server that i am using.
It may be a class-loader issue. Do you have a /WEB-INF/beans.xml file in your web application with the custom validators?
I just tried to use Seam-Faces 3.0.0.Alpha2 in my JavaEE6-Maven-Weld(provided by Glassfish)-WARonly-GlassfishV3-app.
When trying to deploy the App, i get the following Exception:
org.glassfish.deployment.common.DeploymentException: Injection point has ambiguous dependencies. Injection point: field org.jboss.seam.faces.event.PhaseEventBridge.log; Qualifiers: [@javax.enterprise.inject.Default()]; Possible dependencies: [org.jboss.weld.bean-/D:/Program Files (x86)/GlassFish-Tools-Bundle-For-Eclipse-1.2/glassfishv3/glassfish/domains/teachernews/applications/teachernews/-ProducerMethod-org.jboss.weld.log.LoggerProducer.produceLog(javax.enterprise.inject.spi.InjectionPoint), org.jboss.weld.bean-/D:/Program Files (x86)/GlassFish-Tools-Bundle-For-Eclipse-1.2/glassfishv3/glassfish/domains/teachernews/applications/teachernews/-ProducerMethod-org.jboss.weld.extensions.log.LoggerProducer.produceLog(javax.enterprise.inject.spi.InjectionPoint)]
at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:183)
at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:125)
If you want to see my dependencies, i uploaded my pom.xml: http://mackaz.de/public/pom.xml
Try Alpha3 — This should be resolved 🙂
work´s on tomcat 6?
Because its hard to configure weld on tomcat, and I need the seam-faces to use ViewScope and Named annotations.
on seam-faces docs:
“In a Servlet 3.0 or Java EE 6 environment, your configuration is now complete; however, if you are still using Servlet 2.5 or Java EE 5, then you need to add the following code to your application’s web.xml file:
But for weld I´m already have:
I think that two listeners on web.xml is causing:
thanks!
Have you tried changing the order of the listeners so that the Seam Faces listener triggers after the Weld listener?
Yes, I have tried this before, but without sucess.
Unfortunately I’m forced to use the tomcat, but I have not given up.
Anyway, thanks for attention.
If someone found the solution, please contact me: marcos.alcantara gmail . com
Are you using Alpha3? Can you send me an example tomcat project that reproduces this problem? Thanks: lincoln@ocpsoft.com
ok. I already sent an email with the project.
Do you have a workaround for this problem? I’m using Jetty and I have get the same error.
Thank’s.
It takes extra work to set up CDI/Weld in Jetty & Tomcat — are you sure you’ve completed those steps correctly?
http://docs.jboss.org/weld/reference/1.0.1-Final/en-US/html/gettingstarted.html#jetty
Lincoln,
The problem isn’t with CDI. Weld is working pretty well with jetty.
The problem just happen when I put Seam Faces as dependency in pom.xml.
Do you have tested Seam Faces with Jetty?
I was looking the sources and I’m happy to see the pretty good job made by you and your team!
Thanks 😉 Do you think you could send me your test project with Jetty? I’d like to take a closer look at how things are set up.
You can post a link to the example here, or email me at lincoln@ocpsoft.com
Just tried Seam-Faces Alpha 3. But it seems to have a problem with a wrong dependency:
‘org.jboss.spec:jboss-javaee-6.0′ not found in repository: Unable to download the artifact from any repository’
The corresponding issue:
https://jira.jboss.org/browse/SEAM-10
So i just copied and modified the classes i need out of the trunk and use them as standalone in my JEE6app, which works for me, until these problems are solved.
Until this is fixed, you can find the dependency by adding the following repository to your POM file. Also, are you using Maven 3?
If so, you could also add this to your .m2/settings.xml file (in your home-directory.)
Thank you guys!
However, I will try to convince the customer to use another web container.
really thanks!
I still know there is a way to get Weld to work on Tomcat, but it’s not pretty.
Thanks for the help. I’m using Maven 2.
I added the Jboss releases to my pom.xml, but now i’m getting the same error like with Faces Alpha 2 again:
Exception while loading the app : org.glassfish.deployment.common.DeploymentException: Injection point has ambiguous dependencies. Injection point: field org.jboss.seam.faces.component.FormValidationFieldProducer.log; Qualifiers: [@javax.enterprise.inject.Default()]; Possible dependencies: [org.jboss.weld.bean-/D:/Program Files (x86)/GlassFish-Tools-Bundle-For-Eclipse-1.2/glassfishv3/glassfish/domains/teachernews/applications/teachernews/-ProducerMethod-org.jboss.weld.log.LoggerProducer.produceL…
(Full Stacktrace here: http://mackaz.de/public/stacktrace.txt)
Please try Alpha3 – Or you may need to upgrade your glassfish version – this bug has been resolved already.
I’m getting the same exception with Seam-Faces Alpha3 like i got with Alpha2 . So i guess it’s because of the out-dated Weld version provided by Glassfish V3.
Will upgrade Weld soon and check again.
Ok, try upgrading and let me know what happens. We’ve actually tested on many versions of GlassFish, so it may be a problem with an old artifact being on the classpath. Try cleaning all JARs, and delete your local /repository/org/jboss/* folders. Let them re-download, and try again.
Hopefully that’ll work for you 🙂
Got the exception because i had an dependency to weld-logger 1.0.0-CR2 in my pom.xml. So i guess there where 2 LoggerProducers and Weld didn’t know which one to choose when i injected one. Removing Weld-Logger from my pom.xml removed the exception, now SeamFaces Alpha3 works.
Thanks for your help, and keep up the good work on Seam 3!
Hi,
I’m having the exact same problem as venkat above:
(CONFIGURATION FAILED! WELD-001308 Unable to resolve managed beans for Types: [class org.jboss.seam.faces.component.FormValidationTypeOverrideExtension]; Bindings: [@javax.enterprise.inject.Default()]
Seam Faces works properly when I use it in a war but when it’s part of an ear I get that error. Has anyone solved this yet? (Or will it be solved soon?)
…or do you need more details about my setup?
Thanks
Is there an easy way to just extract the classes required for @ViewScoped and @FlashScoped to use in another application. I am having the dependency issue and really do not need anything else provided, other than CDI based view scoped support.
Any guidance on if I can just use the 5 or so source files directly would be helpful.
Seam Faces really does seem to make JSF 2.0 easier, the “original” JSF 2.0 isn’t really harmonic with CDI.
Does this work with Seam 2 + JSF 2, or it’s only available with Seam 3?
Nope, this is just Seam 3 🙂 Sorry! But Seam 2 does a lot of the same things (for JSF 1.2)
I am struggling for seam3-jsf2-richfaces4. I faced so many errors, but still I didn’t get.
i want to sample application for that seam3-jsf2-richfaces4.
please send xml configurations and maven
Thanks in advance
For Jetty Users:
I’ve figured out how to resolve the “Could not wrap External Context” problem. You can find the solution in the first issue (first link)
https://jira.jboss.org/browse/WELDX-126
https://jira.jboss.org/browse/WELD-584
You can implement this in your application for now, but it should eventually be included in Weld-Extensions, which is why I’ve filed issues for it (and for the incorrect weld documentation.)
In Glassfish 3.01 (even in 3.1) I get this message when seam-faces libraries are present in WEB-INF\lib
cannot Deploy Test
Deployment Error for module: Test: Error during deployment : org/jboss/weld/extensions/beanManager/BeanManagerProvider%%%EOL%%%
If I remove seam-faces library, the application can be deployed again.
Still have no luck in getting Seam Faces (3.0.0.Beta1) working with Tomcat 6 despite following all the relevant instructions in the documentation as well as looking at the 2 jira links posted by Lincoln. Container.available() is called by “org.jboss.weld.resources.ManagerObjectFactory” and returns false because this happens before the Weld servlet listener. The ManagerObjectFactory then just throws a NamingException resulting in no BeanManager instance being located as part of Seam Faces’
“org.jboss.seam.faces.event.DelegatingSystemEventListener” PostConstructApplicationEvent system event listener.
Has anyone successfully got Seam Faces to work with Tomcat 6 yet? Any pointers would be greatly appreciated.
The following is the error I get when I try to start Tomcat 6 with an application that has Seam Faces in the lib directory.
Hi,
i got the same exception on tomcat with Seam Faces (3.0.0.Beta1) :
java.lang.IllegalStateException: Could not locate a BeanManager from the providers…
have anyone a soultion ?
Greets,
Paul