Closed GoogleCodeExporter closed 9 years ago
This is definitely a nice idea for OmniFaces 1.6.
Original comment by balusc
on 31 May 2013 at 1:10
Great! I'm assuming you looked over my initial implementation - did anything
look amiss or incomplete? I'd be happy to further improve on it.
Original comment by rdcrng
on 2 Jun 2013 at 4:40
rdcrng, I haven't looked at your implementation yet, but I too think this is a
great idea for OmniFaces 1.6.
Incidentally it also nicely aligns with our plans for adding CDI based features
in OmniFaces 1.6 :)
Original comment by arjan.tijms
on 2 Jun 2013 at 4:12
I didn't look closer at it (we're currently very busy with our job), but the
idea is sound and is definitely worth it, given that it didn't make it into JSF
2.2.
When the time allows it, I will take a closer look at it (also at the initial
Mojarra's implementation of it) and make improvements and/or give feedback if
necessary.
Original comment by balusc
on 2 Jun 2013 at 5:31
Sounds good, I'll be looking forward to it. Meanwhile, I'm using it at work and
will keep you posted should any issues arise.
Original comment by rdcrng
on 2 Jun 2013 at 6:13
Hi again guys. I came up with a better implementation. This time injection for
converters and validators is supported no matter which tag handleris used;
<o:converter>, <f:converter>, <h:component converter="">, etc.
https://code.google.com/r/rdcrng-omnifaces-cdi/source/detail?r=b4753c69d4119b4c3
f1ba18a928b34dee645be2e
P.S. My intention is not to rush you, but to simply provide an update.
Original comment by rdcrng
on 4 Jun 2013 at 5:40
Radu,
I am a happy somewhat-new user of CDI in my web app and 'majority' of
@FacesConverter in my web app is @FacesConverter(class =
someEntityClass.class). I attempted to use MyFaces CODI to reference EJBs via
CODI BeanManager, but no success there.
Can you please implement CDI injection for @FacesConverter(class =
someEntityClass.class) as well?
My apologies, I don't remember the code that I was 'trying' to implement
earlier, but most of my converters look like the following, where I am
referencing @EJB via JSF-managed @RequestScoped bean.
package converter;
import jpa.entities.Address;
import jpa.session.AddressFacade;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
@ManagedBean(name = "addressController")
@RequestScoped
public class AddressController implements Serializable {
@EJB
private jpa.session.AddressFacade ejbFacade;
public AddressController() {
}
@FacesConverter(forClass = Address.class)
public static class AddressControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
AddressController controller = (AddressController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "addressController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Integer getKey(String value) {
java.lang.Integer key;
key = Integer.valueOf(value);
return key;
}
String getStringKey(java.lang.Integer value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Address) {
Address o = (Address) object;
return getStringKey(o.getAddressId());
} else {
throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + Address.class.getName());
}
}
}
}
Original comment by smithh03...@gmail.com
on 10 Jun 2013 at 4:33
Hi smithh03,
First, I'd like to note that I'm not a project member and my implementation was
intended as a proof of concept for BalusC and Arjan to go along with this
feature request. If they decide to use it, I'd be very happy.
That said, the implementation I have at [1] supports
FacesConverter(forClass=...), so be my guest - download it, build it, and use
it. I am using it in my own project currently and I'm quite happy with it.
[1] https://code.google.com/r/rdcrng-omnifaces-cdi/source/detail?r=b4753c69d4119b4c3f1ba18a928b34dee645be2e
That said, I'm not sure it would work with the example you have provided and I
don't have the time to test it at the moment. CDI should scan your static inner
class, but I'm not sure how that would play along with my code - in theory it
should work.
Also, I see that you're suing mostly JSF annotations. My solution is built
around CDI and sometimes CDI and JSF artefacts don't play nice together. I'd
suggest switching to CDI / EJB all the way.
Original comment by rdcrng
on 10 Jun 2013 at 4:49
Radu, thanks for the response. I'll wait for this issue to be marked as fixed.
:)
Original comment by smithh03...@gmail.com
on 10 Jun 2013 at 10:53
Hey guys,
is it just the injection support in validators, converters and else?
this features are already avaialble in DS, Seam and CODI.
IMO this is more related to CDI, as to JSF.
Should we really also provide again this functionality in OmniFaces?
Original comment by andrasch...@gmail.com
on 12 Jun 2013 at 3:12
Agree with the last comment. If you use CDI (and you use it), simple add CODI
and be happy with the injection into JSF converters / validators. It works
smoothly. What is the problem and why this functionality should belong to
OmniFaces. I think it is outside of the OmniFaces' scope.
Original comment by ovarak...@googlemail.com
on 12 Jun 2013 at 3:23
Implemented:
https://code.google.com/p/omnifaces/source/detail?r=4a68a3ddbc625d49e8a77a0450f5
f4623349e834 It will be available in the next 1.6 snapshot. Due to recent
changes in Google Code downloads policy, I can't attach a 1.6 snapshot right
here.
@ovaraksin: I agree to a certain degree. We initially considered it long before
JSF 2.2 was released but we decided to wait for it anyway. However, as it
didn't made it into JSF 2.2 after all, the urge was big to get it in OmniFaces
anyway. We already have planned another CDI feature for 1.6 (injecting a HTTP
request parameter), so this another CDI feature is a welcome bonus.
It's certainly not outside OmniFaces' scope if it can actually be solved from
JSF API itself on. JSF itself is also moving towards CDI (new CDI compatible
@ViewScoped and so on). Also, not everyone uses or wants to use MyFaces CODI.
The OmniFaces one does by the way not require any additional
modifiation/configuration whereas MyFaces CODI requires an additional @Advanced
annotation.
Original comment by balusc
on 30 Jun 2013 at 1:31
@rcdrng: as you see I've improved the code at several points.
- It should be Java 1.6 compatible. So I removed Objects#equals().
- Periods in EL names are illegal. I replaced it by underscore.
- ApplicationFactory#setApplication() wasn't done right. It should wrap the
given application if not an instance of custom application.
- Converters can have both ID and forClass, not an ID *OR* forClass.
- I removed the INFO logger, we'd rather not want to pollute the log with
success cases.
But for the remainder, thank you very much for the kickoff!
Original comment by balusc
on 30 Jun 2013 at 1:34
2 other improvements I forgot to mention:
- Extend from ApplicationWrapper instead of from Application. Extending from a
wrapper class is cleaner as you don't need to write/generate a bunch of
delegate methods.
- Removed nullcheck on @FacesValidator value. This is impossible as that would
not have compiled.
Original comment by balusc
on 30 Jun 2013 at 1:46
+1 looking forward to the showcase example and the next 1.6 snapshot!
Original comment by smithh03...@gmail.com
on 30 Jun 2013 at 8:32
@balusc I'm very glad I could help!
One thought however - it may be a good idea to make the ConverterProvider and
ValidatorProvider @RequestScoped instead of @ApplicationScoped. I am not quite
sure how our explicit invokation of BeanManager#createCreationalContext()
treats @Default converters and validators, but intuitively they become
dependent on the ConverterProvider and ValidatorProvider, respectively.
Assuming that JSF does not cache converter instances, this would mean that we
would end up with multiple instances of the same converters and validators in,
essentially, the application scope. Making the providers @RequestScoped should
clear up any dependent instances in a timely fashion.
Original comment by rdcrng
on 1 Jul 2013 at 4:05
1.6 snapshot is available for download and snapshot showcase has also been
updated.
@rdcrng: No, they do not become dependent on scope of the provider. It are just
the converter/validator IDs which are application scoped, not the created
instances. The current showcase also confirms this as they print the instance
itself with hashcode. They are request scoped -as expected.
Original comment by balusc
on 1 Jul 2013 at 1:55
Tested OmniFaces 1.6 snapshot and got exception on startup of my container
(TomEE 1.6.0 snapshot). see omnifaces issue URL below.
https://code.google.com/p/omnifaces/issues/detail?id=198
Original comment by smithh03...@gmail.com
on 1 Jul 2013 at 9:37
As reported on Issue 198 at
https://code.google.com/p/omnifaces/issues/detail?id=198#c7,
Downloaded today's 1.6 snapshot, and this issue is fixed, and my existing
converters (not modified yet with new Omnifaces CDI facesconverter feature) is
working as designed/expected.
I hope to test the new OmniFaces CDI/EJB in FacesConverter, ASAP.
Original comment by smithh03...@gmail.com
on 2 Jul 2013 at 12:16
Wow, EJB injection in FacesConverter(forClass = ...) and
FacesConverter("converterName") working good in my app via OmniFaces 1.6
snapshot 2013-07-02 (omnifaces-1.6-20130702.112021-1.jar)!
Right now, I have no need for @Inject someCDI, so I didn't test that. I'll let
someone else test that.
Original comment by smithh03...@gmail.com
on 3 Jul 2013 at 10:13
And @EJB injection working for the following in my app as well:
@FacesConverter(value = "ChargesConverter", forClass = Charges.class)
Original comment by smithh03...@gmail.com
on 3 Jul 2013 at 11:21
Guys, when testing on WebLogic 12.1.2 it appears that this server and/or the
specific Weld version it shipped, does not want to inject the extension. When
starting up, the following 2 exceptions are reported:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied
dependencies for type [ValidatorExtension] with qualifiers [@Default] at
injection point [[field] @Inject private
org.omnifaces.cdi.validator.ValidatorManager.extension]
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:311)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:280)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:143)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:163)
at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:382)
at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:367)
at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:379)
at com.oracle.injection.provider.weld.WeldInjectionContainer.start(WeldInjectionContainer.java:106)
at com.oracle.injection.integration.CDIAppDeploymentExtension.initCdi(CDIAppDeploymentExtension.java:70)
at com.oracle.injection.integration.CDIAppDeploymentExtension.activate(CDIAppDeploymentExtension.java:47)
at weblogic.application.internal.flow.AppDeploymentExtensionFlow.activate(AppDeploymentExtensionFlow.java:37)
at weblogic.application.internal.BaseDeployment$2.next(BaseDeployment.java:729)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:42)
at weblogic.application.internal.BaseDeployment.activate(BaseDeployment.java:258)
at weblogic.application.internal.EarDeployment.activate(EarDeployment.java:61)
at weblogic.application.internal.DeploymentStateChecker.activate(DeploymentStateChecker.java:165)
at weblogic.deploy.internal.targetserver.AppContainerInvoker.activate(AppContainerInvoker.java:80)
at weblogic.deploy.internal.targetserver.BasicDeployment.activate(BasicDeployment.java:222)
at weblogic.deploy.internal.targetserver.BasicDeployment.activateFromServerLifecycle(BasicDeployment.java:414)
at weblogic.management.deploy.internal.DeploymentAdapter$1.doActivate(DeploymentAdapter.java:51)
at weblogic.management.deploy.internal.DeploymentAdapter.activate(DeploymentAdapter.java:200)
at weblogic.management.deploy.internal.AppTransition$2.transitionApp(AppTransition.java:30)
at weblogic.management.deploy.internal.ConfiguredDeployments.transitionApps(ConfiguredDeployments.java:240)
at weblogic.management.deploy.internal.ConfiguredDeployments.activate(ConfiguredDeployments.java:169)
at weblogic.management.deploy.internal.ConfiguredDeployments.deploy(ConfiguredDeployments.java:123)
at weblogic.management.deploy.internal.DeploymentServerService.resume(DeploymentServerService.java:191)
at weblogic.management.deploy.internal.DeploymentServerService.start(DeploymentServerService.java:99)
at weblogic.t3.srvr.SubsystemRequest.run(SubsystemRequest.java:64)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:295)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:254)
at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:394)
at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:367)
at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:379)
at com.oracle.injection.provider.weld.WeldInjectionContainer.start(WeldInjectionContainer.java:106)
at com.oracle.injection.integration.CDIAppDeploymentExtension.initCdi(CDIAppDeploymentExtension.java:70)
And:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied
dependencies for type [ConverterExtension] with qualifiers [@Default] at
injection point [[field] @Inject private
org.omnifaces.cdi.converter.ConverterManager.extension]
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:311)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:280)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:143)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:163)
at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:382)
at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:367)
at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:379)
at com.oracle.injection.provider.weld.WeldInjectionContainer.start(WeldInjectionContainer.java:106)
at com.oracle.injection.integration.CDIAppDeploymentExtension.initCdi(CDIAppDeploymentExtension.java:70)
at com.oracle.injection.integration.CDIAppDeploymentExtension.activate(CDIAppDeploymentExtension.java:47)
at weblogic.application.internal.flow.AppDeploymentExtensionFlow.activate(AppDeploymentExtensionFlow.java:37)
at weblogic.application.internal.BaseDeployment$2.next(BaseDeployment.java:729)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:42)
at weblogic.application.internal.BaseDeployment.activate(BaseDeployment.java:258)
at weblogic.application.internal.EarDeployment.activate(EarDeployment.java:61)
at weblogic.application.internal.DeploymentStateChecker.activate(DeploymentStateChecker.java:165)
at weblogic.deploy.internal.targetserver.AppContainerInvoker.activate(AppContainerInvoker.java:80)
at weblogic.deploy.internal.targetserver.operations.AbstractOperation.activate(AbstractOperation.java:586)
at weblogic.deploy.internal.targetserver.operations.ActivateOperation.activateDeployment(ActivateOperation.java:148)
at weblogic.deploy.internal.targetserver.operations.ActivateOperation.doCommit(ActivateOperation.java:114)
at weblogic.deploy.internal.targetserver.operations.StartOperation.doCommit(StartOperation.java:151)
at weblogic.deploy.internal.targetserver.operations.AbstractOperation.commit(AbstractOperation.java:339)
at weblogic.deploy.internal.targetserver.DeploymentManager.handleDeploymentCommit(DeploymentManager.java:846)
at weblogic.deploy.internal.targetserver.DeploymentManager.activateDeploymentList(DeploymentManager.java:1275)
at weblogic.deploy.internal.targetserver.DeploymentManager.handleCommit(DeploymentManager.java:442)
at weblogic.deploy.internal.targetserver.DeploymentServiceDispatcher.commit(DeploymentServiceDispatcher.java:176)
at weblogic.deploy.service.internal.targetserver.DeploymentReceiverCallbackDeliverer.doCommitCallback(DeploymentReceiverCallbackDeliverer.java:195)
at weblogic.deploy.service.internal.targetserver.DeploymentReceiverCallbackDeliverer.access$100(DeploymentReceiverCallbackDeliverer.java:13)
at weblogic.deploy.service.internal.targetserver.DeploymentReceiverCallbackDeliverer$2.run(DeploymentReceiverCallbackDeliverer.java:68)
at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:550)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:295)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:254)
Liberty 8.5.5 is problematic too. Here the showcase app will deploy and pages
can be requested, but when trying the converter and validator examples on
http://localhost:8080/omnifaces-showcase/cdi/FacesConverter and
http://localhost:8080/omnifaces-showcase/cdi/FacesValidator it will print:
Validator currently used: org.omnifaces.showcase.cdi.SomeValidator@57a9d4fc
EJB injected in validator: null
CDI injected in validator: null
Perhaps surprisingly, but with Geronimo 3.0.0.4 (IBM packaged version) and
3.0.1 (Apache packaged version) everything just seems to work.
After some hassle to get the show case to run on Resin 4.0.36 (i.e. Resin
doesn't know <cookie-config> and <tracking-mode> in web.xml, it needs the
explicit "com.sun.faces.config.ConfigureListener" class, etc), it appeared to
have the same issue as Liberty 8.5.5:
Validator currently used: org.omnifaces.showcase.cdi.SomeValidator@7f488ddb
EJB injected in validator: null
CDI injected in validator: null
I'll re-open this issue so we can take a look at it.
Original comment by arjan.tijms
on 31 Aug 2013 at 10:23
[deleted comment]
I'm not sure but based on
http://docs.jboss.org/weld/reference/latest/en-US/html/extend.html it looks
like that we've to create a ValidatorManager/ConverterManager constructor
taking an Extension instead of @Injecting it. I will give it a try.
GlassFish 4.0 has by the way also the same problem as Liberty 8.5.5.
Original comment by balusc
on 31 Aug 2013 at 1:13
Btw, I'm pretty much still a CDI novice when it comes to the internals, but I
read the following on
http://docs.oracle.com/javaee/6/api/javax/enterprise/inject/package-summary.html
Managed beans
A managed bean is a bean that is implemented by a Java class. The basic
lifecycle and semantics of managed beans are defined by the Managed Beans
specification.
A top-level Java class is a managed bean if it is defined to be a managed bean
by any other Java EE specification, or if it meets all of the following
conditions:
• It is not a non-static inner class.
• It is a concrete class, or is annotated @Decorator.
• It is not annotated with an EJB component-defining annotation or declared as an EJB bean class in ejb-jar.xml.
• It does not implement Extension.
I wonder if the last rule "it does not implement Extension" isn't problematic
here. CDI 1.1 implements a method for obtaining an extension instance from the
BeanManager (see
http://docs.oracle.com/javaee/7/api/javax/enterprise/inject/spi/BeanManager.html
#getExtension(java.lang.Class)) but this method is not in CDI 1.0.
Original comment by arjan.tijms
on 31 Aug 2013 at 1:13
Well, but then the javadoc for extension specifically mentions "Service
providers are made available for injection as beans with the qualifier
@Default.", see [1]. Don't know what could be the problem though. :/
http://docs.oracle.com/javaee/6/api/javax/enterprise/inject/spi/Extension.html
Original comment by rdcrng
on 31 Aug 2013 at 1:29
Fixed:
https://code.google.com/p/omnifaces/source/detail?r=09d2796077c227d28f08b2c2b185
68acdeddbadb
Did not test at WebLogic/WebSphere as I don't have them at hands right now, but
this change made it to work on GF4 (and it still works fine on JBoss EAP 6.1,
GF 3.1.2.2, TomEE 1.5.2 and 1.6.0).
Fix is available in today's snapshot: omnifaces-1.6-20130831.133615-40.jar
@Arjan: please give it a try. In the meanwhile, I'm downloading WebLogic
12.1.2c.
Original comment by balusc
on 31 Aug 2013 at 1:37
Well, WebLogic Eclipse plugin says "C:\Java\WebLogic1212c\wlserver does not
contain a valid WebLogic server install" :/
Original comment by balusc
on 31 Aug 2013 at 2:20
downloaded latest/today's (2013-Aug-31) 1.6 snapshot, tested, and deployed to
production. still working good on TomEE 1.6.0 snapshot 2013-Aug-28. thanks!
Original comment by smithh03...@gmail.com
on 31 Aug 2013 at 10:54
>Well, WebLogic Eclipse plugin says "C:\Java\WebLogic1212c\wlserver does not
contain a valid WebLogic server install" :/
Unfortunately, despite Oracle labeling the WebLogic you downloaded as an "unzip
installer" it's anything but. You have to configure and install it using
scripts.
See
http://henk53.wordpress.com/2012/05/01/is-weblogic-12c-a-heavy-weight-enterprise
-solution and specifically
https://blogs.oracle.com/arungupta/entry/get_started_with_oracle_weblogic
Arun's instruction are for OS X, but I guess (hope) they'll be similar for
Windows. There's one difference I encountered and that's that the initial unzip
for WebLogic 12.1.2 results in an extra directory, whereas the unzip for 12.1.1
wrote all files directly into the unzip location. Arun's instructions are for
12.1.1.
Also be aware that the JDK you happen to have on your OS path when you run
these install scripts will be hardcoded into the installation. If you set a
different JDK using Eclipse it simply won't take effect. See
arjan-tijms.blogspot.com/2013/08/testing-jaspic-implementations-using.html for
some extra details on that.
Original comment by arjan.tijms
on 1 Sep 2013 at 2:18
>@Arjan: please give it a try.
I will. In the mean time, I quickly looked at Liberty 8.5.5, and the extension
is being injected there correctly. This is not the problem thus.
I debugged through OmniApplication, and both during the initial page request as
well as the subsequent post back the converter and validator is correctly
obtained WITH the CDI and EJB beans injected.
HOWEVER.. when the value is *actually* being converted the MyFaces that ships
with Liberty DOES NOT seem to go through OmniApplication and as a result the
converter it obtains is a direct instance without any injections being done.
I'll have to dig a little deeper. From a previous issue I know Liberty ships
with an ancient MyFaces version (2.0.4/2.0.5) which is additionally supposedly
"heavily" modified by IBM. This has been the source of a myriad of issues
before :X I'll have to dig a little deeper to find out what's happening here.
Original comment by arjan.tijms
on 1 Sep 2013 at 2:24
>Well, but then the javadoc for extension specifically mentions "Service
providers are made available for injection as beans with the qualifier
@Default.", see [1].
Indeed, and section 11.5 in the CDI 1.0 spec even says:
"For each service provider, the container must provide a bean of scope
@ApplicationScoped and qualifier @Default, supporting injection of a reference
to the service provider instance. The bean types of this bean include the class
of the service provider and all superclasses and interfaces."
So injection of an extension into a normal scoped application bean should be
100% supported. Injection into other extensions would be an issue, but that's
not what's happening here. Also see https://issues.jboss.org/browse/CDI-245
Original comment by arjan.tijms
on 1 Sep 2013 at 2:28
Original issue reported on code.google.com by
rdcrng
on 31 May 2013 at 6:48