13

I've been trying to get this setup running for a couple of days now but still no luck. Here's the test application i've been using:

@Named
@RequestScoped
public class Test {

    private String test = "test";
    public String getTest() { return test; }
    public void setTest(String test) { this.test = test; }
}

And in the jsf page:

<h:outputText value="#{test.test}"/>

Running this sample without MyFaces works fine (renders "test" like it should), but when i deploy MyFaces in the WAR file and do the necessary configuration within weblogic.xml CDI seems to stop working (or at least, the integration bewteen JSF and CDI) and nothing is displayed in the output html. MyFaces itself seems to be ok, though.

My basic configuration is as follows:

  • WebLogic Server 12c (12.1.1.0), patches should be up-to-date as i just downloaded a development version yesterday just to be sure
  • MyFaces-2.1.10, deployed within WEB-INF/libs
  • Beans.xml is in place
  • org.apache.myfaces.webapp.StartupServletContextListener has been registered in web.xml
  • WebLogic is configured to use MyFaces using weblogic.xml

Weblogic.xml contents:

<prefer-application-packages>
    <package-name>javax.faces.*</package-name>
    <package-name>com.sun.faces.*</package-name>
    <package-name>com.bea.faces.*</package-name>
</prefer-application-packages>
<prefer-application-resources>
    <resource-name>javax.faces.*</resource-name>
    <resource-name>com.sun.faces.*</resource-name>
    <resource-name>com.bea.faces.*</resource-name>
    <resource-name>META-INF/services/javax.servlet.ServletContainerInitializer</resource-name>
    <resource-name>META-INF/services/com.sun.faces.spi.FacesConfigResourceProvider</resource-name>
</prefer-application-resources>

What i've learned so far:

  • WL12c is equipped with Weld 1.1.3 as it's CDI implementation.
  • I read somewhere (can't remember where) that whenever you decide to switch JSF implementation you're responsible for integrating JSF/CDI yourself. Is this true (sure hope not)?

Things i've tried so far:

  • Add MyFaces CODI into the mix, hoping it would somehow glue Weld and MyFaces together, but it didn't.
  • Replace Weld by OpenWebBeans as the CDI implementation. This seemed to work at first but gave all kinds of interesting ClassCastExceptions later on in some internal sun.reflection package. This is a solution i'd rather avoid anyway.
  • Manually trigger Weld using various options in web.xml and faces-config.xml. This seems to get Weld going in that it floods the log with all kinds of error messages. To some degree these can be "fixed" by upgrading weblogic to a newer Weld version but each time i do this i bump into the next error. Again, i'd rather avoid this route also.

Is it really that hard to use MyFaces on WL12c while preserving CDI support or am i just missing the obvious ? Thanks for any help.

Sjoerd van Kreel
  • 1,000
  • 6
  • 19
  • FYI: - CODI is independent of any other stuff at MyFaces and so it can't help here. - With CDI 1.0 application servers are bound to a specific CDI implementation (of one vendor and sometimes even to specific versions), if you would like to use the full integration. – Dar Whi Mar 31 '13 at 17:47
  • Using: com.sun.faces.* makes no sense, if you would like to use MyFaces-Core – Dar Whi Mar 31 '13 at 17:48
  • Ok.So i guess using Weblogic implies using Weld 1.1.3 then? I don't mind that, i'm really only interested in running MyFaces but without breaking CDI integration.In fact, i'd rather leave the rest of the weblogic stack alone. About the com.sun.faces.* packages, i guess these aren't part of the MyFaces distribution so i'll remove them from weblogic.xml (config was actually based on an (older) weblogic thread found here: https://forums.oracle.com/forums/thread.jspa?threadID=2335546). However, i'm still unclear if it's possible to use MyFaces on WL12 and somehow integrate it with Weld. Any hints? – Sjoerd van Kreel Apr 01 '13 at 00:09
  • Sjoerd did you ever get this to work. I am faced with the same issue. If so, can you detail how you got it to work? – John Yeary May 31 '13 at 11:41
  • Unfortunately, no. See my reply to Markus Eisele for details. Should you ever get this to work please let us know how you did it =) – Sjoerd van Kreel Jun 03 '13 at 14:36

3 Answers3

3

There are quite a few things which are not clear in your example. E.g. what package is the @RequestScoped from? Is it the javax.enterprise.context.RequestScoped (should work) or the javax.faces.bean.RequestScoped (will not work)? If you are using CDI beans only (and no javax.faces.bean stuff) then the only way the JSF container and the CDI container integrate with each other is actually the Unified Expression Language javax.el.ELResolver. And this must work out of the box.

org.apache.myfaces.webapp.StartupServletContextListener is not really needed imo. All you need is to set the FacesServlet.

The problematic spot might be that the JSF EG got forced to use the ServletContainerInitializer [1] to blindly activate the JSF impl, even if the app does not use JSF at all. This is hard to get around as the servlet-3.0 spec only defines how to automatically activate those features but there is NO way to disable them again.

[1] http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html

struberg
  • 730
  • 5
  • 12
  • RequestScoped is from enterprise.context, and we're indeed trying to resolve the CDI managed bean through EL, which is not working. About your "blindly activate jsf" comment, are you saying it's possible we ended up with 2 simultaneously active JSF implementations ? – Sjoerd van Kreel Jun 03 '13 at 13:32
  • It appears you are right along with @Markus comments. I looked in the JSF deployment (glassfish.jsf_1.0.0.0_2-1-5.jar) on Weblogic and see as part of their package a com.bea.faces.WeblogicInjectionProvider which registers Mojarra first. I also suspect that is right that there is a custom Weld (CDI) framework. – John Yeary Jun 07 '13 at 11:56
1

I'm afraid there is no way to do it. The weld glue code needs to be there. Those tiny little integration layer that is part of the wls deployable libraries for jsf isn't available for myfaces ....

Markus Eisele
  • 712
  • 4
  • 9
  • 1
    I've come to the same conclusion. WL12 ships with this jar called com.oracle.injection.provider.weld_1.0.0.0 which i believe contains the Mojarra/Weld integration code and which is unfortunately not part of any standard, neither CDI nor JSF. We also tried again recently with the new WL12 patch (12.1.1.0.4) with the same results (and it still runs on Weld 1.1.3 which dates back to november 2011). Since i believe this is the most accurate answer (just plain not possible) i will accept this answer as soon as the bounty period is over. – Sjoerd van Kreel Jun 03 '13 at 14:32
  • Also please keep in mind that exchanging anything of your WLS container is not allowed by the WLS enduser license. – struberg Nov 13 '14 at 17:42
  • do you have any updates to this answer? is it still valid? – Karim Ahmed Oct 29 '18 at 13:33
1

Just wondering, did you try enabling weld servlet within your app?

The reason I asked is because of this statement:

I read somewhere (can't remember where) that whenever you decide to switch JSF implementation you're responsible for integrating JSF/CDI yourself

Which is fairly accurate. The container is the one that does the whole combined layering of the JSF impl and CDI impl together. If you replace it with your own JSF impl, you are bypassing what the container gives you. If you haven't yet, I would strongly recommend you to try enabling Weld Servlet in your app to see if CDI boots up w/ the custom JSF impl.

John Ament
  • 11,595
  • 1
  • 36
  • 45
  • Yes. It's been 2 months so don't remember exactly what we tried, but i'm pretty sure i tried various configuration options mentioned under 'jsf' in http://docs.jboss.org/weld/reference/1.1.5.Final/en-US/html/ri-spi.html, without any luck. Note that i don't mind configuring some listener classes to bootstrap cdi/jsf integration, but i'm not about to write the bunch of integration classes i (by now) believe are necessary to get this working. – Sjoerd van Kreel Jun 03 '13 at 13:43
  • Switching to weld servlet isn't a different configuration, it's a different build structure. Since you're moving JSF into your WAR, you would also move the CDI runtime into your war. JSF can simply look up the bean manager over JNDI, so it's worth a shot. – John Ament Jun 08 '13 at 13:39
  • Actually i remember trying that also, packaging weld-core and weld-servlet inside the war but couldnt get it to work either. Anyway, thanks for your help on this John and everyone else but we've decided to stick to mojarra now. Just seems a lot easier. – Sjoerd van Kreel Jun 09 '13 at 09:22
  • 1
    Actually, I decided to try to verify your issue. I could not. I was able to create a simple app that had one JSF managed bean + one CDI managed object, using MyFaces as the JSF runtime. It seemed to work fine. Link is here, if you want to clone it https://github.com/johnament/myfaces-wls – John Ament Jun 09 '13 at 13:37
  • Hi John, thanks again for looking into this. Your sample app does indeed work however i don't see any prefer-application-packages in weblogic.xml. Am i completely mistaken in thinking this is actually required if one wants to override the built-in frameworks (eg JSF)? Just to be sure i added that also to your project and it continued to work as advertised =) On the other hand i still have the same test project here which i used when i originally asked the question and it still doesnt work... I'll try to look into it some more and see if i can find the cause. Thanks again. – Sjoerd van Kreel Jun 10 '13 at 09:23
  • Sjoerd, the difference is that prefer-web-inf-classes causes all classes in WEB-INF to take precedence over app server. No need to explicitly list them. You should try that over prefer-application-packages since it will take everything. – John Ament Jun 10 '13 at 16:31
  • I just found out the same thing. Once I remove prefer-web-inf-classes from your sample and put in prefer-application-packages instead, i got the "old" behaviour which caused me to start this question in the first place. So at first glance using prefer-web-inf over app-packages seems to fix the issue. Now (bear with me =)), try also including MyFaces CODI in the WAR (it's a bit of a pain as it has to be in exploded format inside your WAR, e.g. not in a jar). CODI will log what it believes to be the active JSF impl. ... continued in next comment ... – Sjoerd van Kreel Jun 10 '13 at 20:26
  • ... continued from prev comment... In case of prefer-app-packages, it logs MyFaces Core. In case of prefer-web-inf, it logs Mojarra. On top of that, in either case MyFaces itself spits out this log message: SEVERE: Both MyFaces and the RI are on your classpath. Please make sure to use only one of the two JSF-implementations. All in all i'm not at all comfortable with the combo MyFaces+WebLogic so we're not going to use it anyway. At this point it's more about getting to know if its at all possible, just out of curiosity. – Sjoerd van Kreel Jun 10 '13 at 20:26