12 Replies Latest reply on Apr 28, 2008 3:10 PM by rafaelcba

    The JSF library situation in JBoss explained (it's called

    gdarius

      All,

      The JSF situation in JBoss has gone from bad to worse. In the pre-4.2.0 servers, if you wanted to package your own JSF implementation with a web app, you had to delete the JSF libraries folder that ship with JBoss. From all the trouble I read on various forums, users had only some success doing this. Telling me to modify my app server to deploy a single app is "bad".

      But, at least with 4.2.0 CR-2 (and I assume 5.0.0 Betas), there is no way to package your own JSF libraries with your web app! Check this wiki link for proof:

      http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossWithJSFCDDL

      The important line to look for is this little dandy:

      Before you begin, note: You should not add JSF implementation jars to your WAR!!


      Before you continue, note: Um, NO!!

      Maybe I WANT my own JSF implementation jars deployed! Maybe I've got something working on an older version of JSF and don't want anything to change. The whole point of J2EE is to give us deployment options not available in J2SE. You guys are getting just a little too JBossy, if you forgive the pun, by telling ME how I need to package MY app!

      But, the implications of this are worse, MUCH worse.

      1) You're squatting on a public namespace - you don't own javax.faces, you own org.jboss. If you want to ship your own mutant faces server-wide, fine, do it, just repackage everything so it pollutes your namespace and not mine.

      2) You're acting very proprietary. You're not J2EE anymore, now you're J2EE+JBoss Faces+JBoss Log4J+JBoss-whatever-specific-versions-you-bundle-and-force-us-to-use. Stop doing me favors, you're in the wrong. I hereby revoke any JBoss J2EE Certification until further notice.

      3) You're attempting to engage in vendor lock-in, plain and simple. I should be able to take my WAR that deploys fine on WebLogic, WebSphere, and Geronimo and deploy it on JBoss with only JBoss vendor deployment descriptor changes. But you take away my power in more than just the JSF case to decide what libraries and versions I can use. And, your vendor specific deployment descriptor tweaks for classloader control are toothless!! You are telling me to make a special version of my app, just for JBoss. No, it is not going to happen, I reject your vendor lock-in attempt!

      Thoughts? Am I way off base? Oh, and by the way, citing JBoss technicalities or idiosyncrasies is no excuse. The other vendors don't share your design issues to such an extent. Tell me how to invert or suppress the appserver classloader so that I can override your JSF libraries, or I will not support deployments to JBoss.

      gDarius

        • 1. ... (It's called "vendor lock-in")
          gdarius

          gDarius

          • 2. Re: The JSF library situation in JBoss explained (it's calle
            ssilvert

            Hi Darius,

            I think your beef is really with JEE5 rather than JBoss. JBoss 4.2 is an "almost" JEE5 compliant container. JEE5 requires that JSF 1.2 be fully integrated into the container. The result is that you should no longer bundle a JSF implementation into your WAR.

            So to use MyFaces with JBoss 4.2, you would need surgically remove the java.net version of JSF 1.2 that ships with the server. I'm a bit hesitant to provide instructions for that but I might be convinced to do it if customers really want/need it. But I hope you will listen to my arguments and decide if that's what you really want to do. There are compelling advantages to using the implementation that ships with the container. And if you change your WAR to be JEE5 compliant, your application will be more portable going forward.

            "gDarius" wrote:


            1) You're squatting on a public namespace - you don't own javax.faces, you own org.jboss. If you want to ship your own mutant faces server-wide, fine, do it, just repackage everything so it pollutes your namespace and not mine.


            As I explained above, this is how the spec tells us to do things now. We haven't stepped on the javax.faces namespace.

            "gDarius" wrote:

            2) You're acting very proprietary. You're not J2EE anymore, now you're J2EE+JBoss Faces+JBoss Log4J+JBoss-whatever-specific-versions-you-bundle-and-force-us-to-use. Stop doing me favors, you're in the wrong. I hereby revoke any JBoss J2EE Certification until further notice.


            That's very true. JBoss 4.2 is not really a J2EE container, though it is mostly compliant with J2EE. It's goal is to take a large step toward JEE5 compliance.

            "gDarius" wrote:

            3) You're attempting to engage in vendor lock-in, plain and simple. I should be able to take my WAR that deploys fine on WebLogic, WebSphere, and Geronimo and deploy it on JBoss with only JBoss vendor deployment descriptor changes.


            I notice that you didn't include Glassfish in that list. I think you will have the same problem on any JEE5 server. If not, I'd be very interested in how they handled having two JSF implementations in the same classloader namespace.

            As for vendor lock-in, JBoss has never tried to do that and we never will. We want you to use our server because it is the best, not because you are forced to. Unfortunately, being spec-compliant with JEE5 does have a few pitfalls.

            "gDarius" wrote:

            But you take away my power in more than just the JSF case to decide what libraries and versions I can use. And, your vendor specific deployment descriptor tweaks for classloader control are toothless!! You are telling me to make a special version of my app, just for JBoss. No, it is not going to happen, I reject your vendor lock-in attempt!


            All vendors have vendor-specific settings. I'm not aware of anything that keeps you from running fully-portable, spec-compliant applications on JBoss. Do you have an example?

            "gDarius" wrote:

            Thoughts? Am I way off base? Oh, and by the way, citing JBoss technicalities or idiosyncrasies is no excuse. The other vendors don't share your design issues to such an extent. Tell me how to invert or suppress the appserver classloader so that I can override your JSF libraries, or I will not support deployments to JBoss.
            gDarius


            I don't think you are way off base. You've got a legitimate gripe, but I think you just need to consider that this is a JEE5 migration problem rather than a JBoss problem per se.

            I don't think there is a classloader solution, but it might be worth investigation. Are you building a product that runs on many app servers? If so, you might want to consider having both a J2EE version and a JEE5 version. There are great advantages to the JEE5 way of doing things. You get all the features of JSF 1.2, JSP 2.1, and JSTL 1.2. Plus, you get things like dependency injection on your managed beans. See http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossWithJSFCDDL.

            Also, think of it this way. Would you ever bundle your own implementation of JSP with your WAR? You could certainly do so. You could take the Weblogic JSP impl and deploy it on Tomcat. But it wouldn't make much sense since both comply with the same spec. In a JEE5 container, you have the exact same situation with JSF. JSF is now a standard, spec-compliant, service. The problem is just with migration of pre-JEE5 applications.

            Regards,

            Stan
            http://jsf.jboss.org

            • 3. Re: The JSF library situation in JBoss explained (it's calle
              ssilvert

               

              "stan.silvert@jboss.com" wrote:


              "gDarius" wrote:

              2) You're acting very proprietary. You're not J2EE anymore, now you're J2EE+JBoss Faces+JBoss Log4J+JBoss-whatever-specific-versions-you-bundle-and-force-us-to-use. Stop doing me favors, you're in the wrong. I hereby revoke any JBoss J2EE Certification until further notice.


              That's very true. JBoss 4.2 is not really a J2EE container, though it is mostly compliant with J2EE. It's goal is to take a large step toward JEE5 compliance.


              I wish I could go back and edit this. The "That's very true." refers to J2EE certification, not "You're acting very proprietary." :-)

              Stan
              http://jsf.jboss.org

              • 4. Re: The JSF library situation in JBoss explained (it's calle
                gdarius

                Hello Stan,

                Thanks for writing back so quickly. It was not clear on the wiki that the forced JSF was due to JEE5 compliance efforts, which is why I took such an incredulous tone. Regardless, you are correct about JEE5, I read the spec and sure enough, it requires JSF 1.2. Wow, I'm floored, that's a pretty gutsy move on their part ... And they are making your life difficult because then I see they say some seemingly contradictory things...

                From section EE.11.1, it states:

                Compatibility is a core value of the Java EE platform. A Java EE product is required to support portable applications written to previous versions of the platform.


                ... but then at then end of that section, they get a bit dodgy with this:
                Portable applications depend only on the APIs and behavior required by the Java EE specifications. In general, portable applications written to a previous version of the platform will continue to work without change and with identical behavior on the current version of the platform.


                So, what does "in general" mean? Does that mean you are required or you are not required to host older J2EE applications? What percentage of the time is "in general"? 50%? 99.9%?

                And from section EE.6.1.2, where it discusses that you must include JSF 1.2, it states:
                All classes and interfaces required by the specifications for the APIs must be provided by the Java EE containers. In some cases, a Java EE product is not required to provide objects that implement interfaces intended to be implemented by an application server, nevertheless, the definitions of such interfaces must be included in the Java EE platform.


                So, our app is a J2EE 1.4 app, not a 1.5 app. And by this spec, you're supposed to support apps written to those older versions WHILE loading JSF 1.2. I think they must mean for you to dynamically load JSF for web applications if the deployment descriptor identifies the app as JEE5, and to NOT load JSF otherwise (since it wasn't required for J2EE 1.4 and below.) Is this your interpretation as well?

                I can tell you right now, it's going to be a long time before we upgrade to JEE5. So, for now, we are bundling our own JSF libraries and deploying to other vendor's platforms without trouble. We can't deploy our app to JBoss 4.2+ where our deployment descriptor indicates J2EE 1.4 (servlet 2.4 indicated in web.xml) and JSF 1.2 also gets pre-loaded for us. For my situation, if you could give me a way to override or mask off your JSF libraries from being loaded using the jboss-web.xml, that would be fine.

                This is a difficult situation for JBoss. Sorry for being so harsh in my original message, I had no idea what was happening in JEE5 and how that was affecting you.

                I will try to deploy to Glassfish and see how it does. We do not consider Glassfish to be a "force" in the market yet like JBoss is, but it will be an interesting experiment to see how well it does deploying our app. Geronimo was our initial platform only because its rich classloader controls made prototyping easy for other parts of our app.

                Thanks,
                gDarius

                • 5. Re: The JSF library situation in JBoss explained (it's calle
                  gdarius

                  Stan,

                  I did not specifically address some things you wrote, here's my responses to those things:

                  All vendors have vendor-specific settings. I'm not aware of anything that keeps you from running fully-portable, spec-compliant applications on JBoss. Do you have an example?


                  It's not that you have vendor-specific settings that keep me from running. It's that the ones you DO have don't seem to have the mojo that other vendors have. For example, other vendors have inverted-classloader hierarchy things that allow you to delegate to the parent AFTER the application's child classloader has the chance to load classes for the app - it allows me to override the parent's classloader and just for my app. You have classloader isolation techniques, but there are a whole boatload of server-supplied libraries that do not appear to be affected by that isolation...

                  IMHO, if you ever find your people saying "just remove the log4j jar from your WAR and it will work" or something like that, you're missing the point of J2EE. The value prop of J2EE is all wrapped up in the classloader controls and (re)deployment. Anytime you cause me grief by saying something like "a local EJB from one EAR can't call another local EJB from another EAR" or "just remove log4j from your WAR and it will work", you're missing the point and limiting the ways I can use JBoss.

                  That all said, vendor deployment descriptors are your escape hatch and your ginsu knife. It's SO EASY for me to add a specific DD to the WAR to get things to work specifically on JBoss only. Sure, it's often a hack, what do I care? It works, moving on. But, it's anywhere from hard-to-impossible for me to do things like "remove jars" because then I have to retest and rejigger my brains to get things working again on every other appserver. Hence, my accusation that JBoss was attempting a lock-in.

                  Also, think of it this way. Would you ever bundle your own implementation of JSP with your WAR? You could certainly do so. You could take the Weblogic JSP impl and deploy it on Tomcat. But it wouldn't make much sense since both comply with the same spec. In a JEE5 container, you have the exact same situation with JSF. JSF is now a standard, spec-compliant, service. The problem is just with migration of pre-JEE5 applications.


                  No, I would not bundle JSP with my app because the spec has always said the vendor supplies it. Similarly, if I were writing a JEE5 app, I wouldn't bundle JSF.

                  There is no required migration for me; I should, by the spec language, be able to run unmodified J2EE 1.4 apps on your JEE5 server - which means my bundling an older JSF should be legal. If you are saying we need to migrate, you're essentially ditching backwards compatibility and you should say so someplace and you should puke a huge error if any app with DD's from earlier specs tries to deploy. Which is all probably a really bad thing unless you don't think so.

                  I agree, after thinking about it for a bit, JEE5 is a step in the right direction. It will be good for everyone that the spec maintainers are going through a standardizing effort for many of the java optional libraries.

                  Cheers,
                  gDarius

                  • 6. Re: The JSF library situation in JBoss explained (it's calle
                    ssilvert

                     

                    "gDarius" wrote:
                    For my situation, if you could give me a way to override or mask off your JSF libraries from being loaded using the jboss-web.xml, that would be fine.


                    What would you say to a context-param in web.xml?
                    <context-param>
                     <param-name>org.jboss.jbossfaces.WAR_BUNDLES_JSF</param-name>
                     <param-value>true</param-value>
                    </context-param>


                    I've been discussing this and prototyping internally. It works as long as you don't change the default WAR classloader setting to useJBossWebLoader=true. There are pros and cons. What do you think?

                    Stan
                    http://jsf.jboss.org

                    • 7. Re: The JSF library situation in JBoss explained (it's calle
                      gdarius

                       

                      What would you say to a context-param in web.xml?


                      I'd say it's exactly what you need! It achieves configuration specific to faces on JBoss that everyone else will safely ignore. Good stuff! As far as default settings for this flag go, may I suggest that if the accompanying web.xml has version 2.4 or lower you make the value true, otherwise false. This way you get backwards compat by default.

                      I take it this flag does not yet exist and you are still in the discussion phase, I just tried it on 4.2.0 CR2 and it didn't seem to have an effect with useJbossWebLoader unset.

                      Thanks,
                      gDarius


                      • 8. Re: The JSF library situation in JBoss explained (it's calle
                        ssilvert

                        This has been committed to 4.2 and 5.0. It doesn't look at the web.xml version. It should be legal to run a 2.4 web.xml with the built-in JSF impl. It would go against the JEE5 spec if we required a JSF impl in the war for that.

                        Instructions for using this new feature are at the bottom of this wiki:
                        http://wiki.jboss.org/wiki/Wiki.jsp?page=JBoss5AndMyFaces

                        This feature is "community only" and not "officially supported". To explain that, if you are a JBoss/Red Hat support customer we will only support the built-in version of JSF. We always do our best to help our support customers even when they use non-standard libraries. But we can't give any sort of guarantee when a customer uses their own JSF implementation.

                        Stan

                        • 9. Re: The JSF library situation in JBoss explained (it's calle
                          gdarius

                           

                          This has been committed to 4.2 and 5.0. It doesn't look at the web.xml version. It should be legal to run a 2.4 web.xml with the built-in JSF impl. It would go against the JEE5 spec if we required a JSF impl in the war for that.


                          Stan,

                          Thanks for your responsiveness and patient guidance on this issue. It's great that you and the organization are open to making these changes, even if it's on a community-only basis.

                          Sorry again for jumping to conclusions initially on what I was seeing.

                          Cheers,
                          gDarius


                          • 10. Re: The JSF library situation in JBoss explained (it's calle
                            mariuszs

                            Anyone can confirm than this feature (WAR_BUNDLES_JSF_IMPL) is working in cluster (with JBoss Portal for example)

                            I have strange errors:
                            2007-10-19 09:28:29,628 DEBUG [org.jboss.portal.faces.loader.FacesClassLoader] Want to load org.jboss.portal.core.admin.ui.common.PageManagerBean will delegate
                            2007-10-19 09:28:29,628 DEBUG [org.apache.catalina.loader.WebappClassLoader] loadClass(org.jboss.portal.core.admin.ui.common.PageManagerBean, false)
                            2007-10-19 09:28:29,628 DEBUG [org.apache.catalina.loader.WebappClassLoader] Searching local repositories
                            2007-10-19 09:28:29,628 DEBUG [org.apache.catalina.loader.WebappClassLoader] findClass(org.jboss.portal.core.admin.ui.common.PageManagerBean)
                            2007-10-19 09:28:29,628 DEBUG [org.apache.catalina.loader.WebappClassLoader] Delegating to parent classloader at end: java.net.FactoryURLClassLoader@14d0e66
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] loadClass(org.jboss.portal.portlet.InvalidPortletIdException, false)
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] Searching local repositories
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] findClass(org.jboss.portal.portlet.InvalidPortletIdException)
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] Delegating to parent classloader at end: java.net.FactoryURLClassLoader@3c4c33
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] Loading class from parent
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] loadClass(org.jboss.portal.portlet.InvalidPortletIdException, false)
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] Searching local repositories
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] findClass(org.jboss.portal.portlet.InvalidPortletIdException)
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] Delegating to parent classloader at end: java.net.FactoryURLClassLoader@3c4c33
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] Loading class from parent
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] loadClass(org.jboss.portal.portlet.InvalidPortletIdException, false)
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] Searching local repositories
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] findClass(org.jboss.portal.portlet.InvalidPortletIdException)
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] Delegating to parent classloader at end: java.net.FactoryURLClassLoader@3c4c33
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] Loading class from parent
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] loadClass(org.jboss.portal.portlet.InvalidPortletIdException, false)
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] Searching local repositories
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] findClass(org.jboss.portal.portlet.InvalidPortletIdException)
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] Delegating to parent classloader at end: java.net.FactoryURLClassLoader@3c4c33
                            2007-10-19 09:28:33,284 DEBUG [org.apache.catalina.loader.WebappClassLoader] Loading class from parent

                            ...

                            2007-10-19 09:28:36,081 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/portal].[PortalServletWithPathMapping]] Servlet.service() for servlet PortalServletWithPathMapping threw exception
                            java.lang.OutOfMemoryError: PermGen space
                            at java.lang.Throwable.getStackTraceElement(Native Method)
                            at java.lang.Throwable.getOurStackTrace(Throwable.java:592)
                            at java.lang.Throwable.printStackTrace(Throwable.java:511)
                            at org.apache.log4j.spi.ThrowableInformation.getThrowableStrRep(ThrowableInformation.java:59)
                            at org.apache.log4j.spi.LoggingEvent.getThrowableStrRep(LoggingEvent.java:342)
                            at org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:304)
                            at org.apache.log4j.WriterAppender.append(WriterAppender.java:159)
                            at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:230)
                            at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:65)
                            at org.apache.log4j.Category.callAppenders(Category.java:203)
                            at org.apache.log4j.Category.forcedLog(Category.java:388)
                            at org.apache.log4j.Category.log(Category.java:853)
                            at org.jboss.logging.Log4jLoggerPlugin.error(Log4jLoggerPlugin.java:206)
                            at org.jboss.logging.Logger.error(Logger.java:234)
                            at org.jboss.portal.core.impl.model.content.InternalContentProvider.renderWindow(InternalContentProvider.java:280)
                            at org.jboss.portal.core.model.portal.command.render.RenderWindowCommand.execute(RenderWindowCommand.java:88)
                            at org.jboss.portal.core.controller.ControllerCommand$1.invoke(ControllerCommand.java:68)
                            at org.jboss.portal.common.invocation.Invocation.invokeNext(Invocation.java:131)
                            at org.jboss.portal.core.aspects.controller.node.EventBroadcasterInterceptor.invoke(EventBroadcasterInterceptor.java:123)
                            at org.jboss.portal.core.controller.ControllerInterceptor.invoke(ControllerInterceptor.java:40)
                            at org.jboss.portal.common.invocation.Invocation.invokeNext(Invocation.java:115)
                            at org.jboss.portal.core.aspects.controller.ControlInterceptor.invoke(ControlInterceptor.java:57)
                            at org.jboss.portal.core.controller.ControllerInterceptor.invoke(ControllerInterceptor.java:40)
                            at org.jboss.portal.common.invocation.Invocation.invokeNext(Invocation.java:115)
                            at org.jboss.portal.core.aspects.controller.PageCustomizerInterceptor.invoke(PageCustomizerInterceptor.java:133)
                            at org.jboss.portal.core.controller.ControllerInterceptor.invoke(ControllerInterceptor.java:40)
                            at org.jboss.portal.common.invocation.Invocation.invokeNext(Invocation.java:115)
                            at org.jboss.portal.core.aspects.controller.PolicyEnforcementInterceptor.invoke(PolicyEnforcementInterceptor.java:77)
                            at org.jboss.portal.core.controller.ControllerInterceptor.invoke(ControllerInterceptor.java:40)
                            at org.jboss.portal.common.invocation.Invocation.invokeNext(Invocation.java:115)
                            at org.jboss.portal.core.aspects.controller.node.PortalNodeInterceptor.invoke(PortalNodeInterceptor.java:81)
                            at org.jboss.portal.core.controller.ControllerInterceptor.invoke(ControllerInterceptor.java:40)

                            • 11. Re: The JSF library situation in JBoss explained (it's calle
                              ssilvert

                              I don't know if it's working with cluster or not. But cluster and JBoss Portal are two different things, so I don't understand your question. I do know that JBoss Portal is using a custom classloader to deal with some of the JSF issues discussed earlier in this thread.

                              For your OutOfMemoryError, there is a good wiki on that here:
                              http://wiki.jboss.org/wiki/Wiki.jsp?page=OutOfMemoryExceptions

                              Stan

                              • 12. Re: The JSF library situation in JBoss explained (it's calle
                                rafaelcba

                                hi!

                                remember that context-param (org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL) need be placed on top into <web-app> tag.

                                <?xml version="1.0" ?>
                                <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
                                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
                                 version="2.4">
                                
                                 <context-param>
                                 <param-name>org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL</param-name>
                                 <param-value>true</param-value>
                                 </context-param>
                                
                                ...
                                
                                



                                regards,