1 2 3 4 5 Previous Next 68 Replies Latest reply on Apr 17, 2012 8:54 AM by alesj Go to original post
      • 30. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
        hostalp

        I've found out that if I specify an ear file name as domain name in jboss-classloading-domain.xml then I see two classloaders in JMX view:

         

        domain: "jboss.j2ee:extension=LoaderRepository,service=EARDeployment,url='myapp.ear'" - the default one created by ear deployer, with parent policy: "AFTER_BUT_JAVA_BEFORE" and parent domain "DefaultDomain"

         

        domain: "myapp.ear" - created from jboss-classloading-domain.xml, with parent policy: "(before=EXCLUDE [org.hibernate.validator] after=)" and no parent domain (null).

         

        So it looks like I'll have to either add jboss-classloading.xml to change the domain name to the same valuse which is in jboss-classloading-domain.xml or modify jboss-classloading-domain.xml to use the default one.

        I quickly tried both but it broke the app - it couldn't load javax.servlet.http.HttpServlet (using negated recursive package filter for org.hibernate.validator as before-filter). With some other filter it couldn't start for other reasons so I'll try figure out a bit more about what actually happens..

         

        Also I noticed that war classloaders don't show up any parent domain (null).

         

        So do you think that NothingClassFilter combined with RecursivePackageFilter (the same way as NegatingClassFilter) would do the desired blocking?

        • 31. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
          alesj
          I've found out that if I specify an ear file name as domain name in jboss-classloading-domain.xml then I see two classloaders in JMX view:

           

          domain: "jboss.j2ee:extension=LoaderRepository,service=EARDeployment,url='myapp.ear'" - the default one created by ear deployer, with parent policy: "AFTER_BUT_JAVA_BEFORE" and parent domain "DefaultDomain"

           

          domain: "myapp.ear" - created from jboss-classloading-domain.xml, with parent policy: "(before=EXCLUDE [org.hibernate.validator] after=)" and no parent domain (null).

           

          So it looks like I'll have to either add jboss-classloading.xml to change the domain name to the same valuse which is in jboss-classloading-domain.xml or modify jboss-classloading-domain.xml to use the default one.

          I quickly tried both but it broke the app - it couldn't load javax.servlet.http.HttpServlet (using negated recursive package filter for org.hibernate.validator as before-filter). With some other filter it couldn't start for other reasons so I'll try figure out a bit more about what actually happens..

          Ah, another thing I missed -- EARClassLoaderDeployer. ;-(

          Same issue as WebCLDeployer, it also sets some defaults, if no CLMetaData exists.

           

          Let me check what gets used if you don't define any parent-domain in jb-cl-domain.xml.

          Also I noticed that war classloaders don't show up any parent domain (null).

          How do you see this?

          Didn't we fix this with explicit jb-cl.xml in each of the wars? (until WebCLDeployer is fixed)

          So do you think that NothingClassFilter combined with RecursivePackageFilter (the same way as NegatingClassFilter) would do the desired blocking?

          If you use NothingFilter then there is nothing to combine. ;-)

          • 32. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
            alesj
            Let me check what gets used if you don't define any parent-domain in jb-cl-domain.xml.

            Yup, you need to explicitly define the parent -- otherwise it's null.

            Hence the "couldn't load javax.servlet.http.HttpServlet" error -- DefaultDomain is not the parent as we would expect.

             

            Do you think we should by default have DefaultDomain as a parent, if not explicitly defined?

            • 33. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
              alesj
              Ah, another thing I missed -- EARClassLoaderDeployer. ;-(

              * https://issues.jboss.org/browse/JBAS-8784

              • 34. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
                hostalp

                Yup, you need to explicitly define the parent -- otherwise it's null.

                Hence the "couldn't load javax.servlet.http.HttpServlet" error -- DefaultDomain is not the parent as we would expect.

                 

                Do you think we should by default have DefaultDomain as a parent, if not explicitly defined?

                Yeah that makes sense. But strange that it happens even when I specify parent domain via jboss-classloading.xml. Perhaps jboss-classloading-domain.xml overrides that.

                Yes I think DefaultDomain as parent by default (like elsewhere) would be acceptable here.

                And by the way, how one specifies parent in jboss-classloading-domain.xml? I didn't study the related source. Is there any attribute like 'parent' or so?

                • 35. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
                  hostalp
                  Also I noticed that war classloaders don't show up any parent domain (null).

                  How do you see this?

                  Didn't we fix this with explicit jb-cl.xml in each of the wars? (until WebCLDeployer is fixed)

                  I looked into jmx-console for jboss.classloader objects at entries for each of the wars. They don't show any parent there even with everything regarding classloading left untouched. But even though they don't show up any parents here they actually seem like they may have the parent setup from ear level. At least based on my brief tests with intentional screwing up something.

                  • 36. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
                    alesj
                    Yeah that makes sense. But strange that it happens even when I specify parent domain via jboss-classloading.xml. Perhaps jboss-classloading-domain.xml overrides that.

                    Yes.

                    As it's the jb-cl-domain.xml that defines the full domain.

                    jb-cl.xml just uses that domain, hence it cannot change its parent.

                    And by the way, how one specifies parent in jboss-classloading-domain.xml? I didn't study the related source. Is there any attribute like 'parent' or so?

                    @XmlAttribute
                       public void setParentDomain(String parentDomain)
                       {
                          this.parentDomain = parentDomain;
                       }

                     

                    There is an attribute parent-domain on the top jb-cl-domain.xml element.

                    • 37. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
                      hostalp

                      Alright, made some progress. When specifying after and before filters it seems to have effect, however I've found one issue when trying to setup a configuration simulating default classloading behavior for ear deployments.

                       

                      For ear deployments default is parent-first="false" ie. parent-policy "AFTER_BUT_JAVA_BEFORE".

                      When setting up jboss-classloading-domain.xml this changes to parent-first="true" ie. parent-policy "BEFORE"

                       

                      So what I tried was to modify jboss-classloading.xml to simulate the default behavior based on ParentPolicy class:

                      /** Java and Javax classes before, everything else after */
                         public static final ParentPolicy AFTER_BUT_JAVA_BEFORE = new ParentPolicy(ClassFilterUtils.JAVA_ONLY, ClassFilterUtils.EVERYTHING, "AFTER_BUT_JAVA_BEFORE");

                       

                      To start from the beginning, I've setup:

                       

                      <?xml version="1.0" encoding="UTF-8"?>
                      <classloading-domain xmlns="urn:jboss:classloading-domain:1.0" name="jboss.j2ee:extension=LoaderRepository,service=EARDeployment,url=&apos;myapp.ear&apos;" parent-domain="DefaultDomain">
                      <parent-policy>
                        <before-filter>
                         <javabean xmlns="urn:jboss:javabean:2.0" class="org.jboss.classloader.plugins.filter.JavaOnlyClassFilter" />
                        </before-filter>
                        <after-filter>
                         <javabean xmlns="urn:jboss:javabean:2.0" class="org.jboss.classloader.plugins.filter.EverythingClassFilter" />
                        </after-filter>
                      </parent-policy>
                      </classloading-domain>

                       

                      However both JavaOnlyClassFilter and EverythingClassFilter have private constructor so I'm getting:

                      java.lang.RuntimeException: Error constructing javabean

                      Caused by: java.lang.IllegalAccessException: Class org.jboss.reflect.plugins.introspection.ReflectionUtils can not access a member of class org.jboss.classloader.plugins.filter.JavaOnlyClassFilter with modifiers "private"

                       

                      And by the way - specifying multiple beans within one filter will work?

                      like for example:

                      <before-filter>
                         <javabean xmlns="urn:jboss:javabean:2.0" class="org.jboss.classloader.plugins.filter.JavaOnlyClassFilter" />
                         <javabean xmlns="urn:jboss:javabean:2.0" class="org.jboss.classloader.plugins.filter.NegatingClassFilter">
                          <constructor>
                           <parameter>
                            <javabean xmlns="urn:jboss:javabean:2.0" class="org.jboss.classloader.spi.filter.RecursivePackageClassFilter">
                             <constructor>
                              <parameter>org.hibernate</parameter>
                             </constructor>
                            </javabean>
                           </parameter>
                          </constructor>
                         </javabean>
                        </before-filter>

                      • 38. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
                        alesj
                        And by the way - specifying multiple beans within one filter will work?

                        like for example:

                        <before-filter>
                           <javabean xmlns="urn:jboss:javabean:2.0" class="org.jboss.classloader.plugins.filter.JavaOnlyClassFilter" />
                           <javabean xmlns="urn:jboss:javabean:2.0" class="org.jboss.classloader.plugins.filter.NegatingClassFilter">
                            <constructor>
                             <parameter>
                              <javabean xmlns="urn:jboss:javabean:2.0" class="org.jboss.classloader.spi.filter.RecursivePackageClassFilter">
                               <constructor>
                                <parameter>org.hibernate</parameter>
                               </constructor>
                              </javabean>
                             </parameter>
                            </constructor>
                           </javabean>
                          </before-filter>

                        No.

                        What exactly are you trying to configure here?

                        • 39. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
                          hostalp

                          I'm trying to setup the parent-first="false" ie. parent-policy "AFTER_BUT_JAVA_BEFORE" behavior and then add some package filters to it.

                           

                          With plain ear deployed it's "AFTER_BUT_JAVA_BEFORE" by default, but when I add any java-classloading-domain.xml file (even the minimal one without any custom filters) the behavior switches to parent-first="true" ie. parent-policy "BEFORE" and then any potentionally added custom filters are combined with that (which is OK but I want to get the aame to work for "AFTER_BUT_JAVA_BEFORE").

                           

                          I tried stuff like <parent-policy name="AFTER_BUT_JAVA_BEFORE"> which switches it to the desired state but then added filters have no effect.

                          • 40. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
                            alesj

                            I see.

                             

                            You should then configure / combine your own filters --

                            via before-filter and after-filter elements; e.g. CombiningClassFilter.

                             

                            It's a bit more work, but check the source on how we define those JAVA* filters.

                            • 41. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
                              hostalp

                              But that departs more and more from the intended ease of use I fear

                              • 42. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
                                alesj
                                But that departs more and more from the intended ease of use I fear

                                Those are fine-grained details, and as such there is no way we can provide them all.

                                But this is OSS, and the ease of use was already done by providing very flexible VDF and CL layers.

                                Hence you're welcome to contribute. ;-)

                                • 43. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
                                  hostalp

                                  We'll try something here, but what upsets me is that just adding the jboss-classloading-domain.xml (or jboss-classloading.xml) automatically changes the classloader defaults even though I don't attempt to change them in the config, and especially the parent-first is interesting this case.

                                  Why is it so? Does it come from EarClassLoaderDeployer/WarClassLoaderDeployer ? Quick look at them shows that perhaps it does. Shouldn't that be fixed too to prevent that from changing depending on jboss-classloading-domain.xml presence?.

                                  • 44. Re: How to stop my WAR loading JBoss's provided 3rd party classes?
                                    alesj
                                    We'll try something here, but what upsets me is that just adding the jboss-classloading-domain.xml (or jboss-classloading.xml) automatically changes the classloader defaults even though I don't attempt to change them in the config, and especially the parent-first is interesting this case.

                                    OK, apart from the bugz in EAR and WAR CL deployers, other things are obvious.

                                    You're defining your own domain, hence its configuration applies.

                                    Why is it so? Does it come from EarClassLoaderDeployer/WarClassLoaderDeployer ? Quick look at them shows that perhaps it does.

                                    Yes.

                                    The parent-first comes form classLoadingMetaData.setJ2seClassLoadingCompliance(false);

                                    Shouldn't that be fixed too to prevent that from changing depending on jboss-classloading-domain.xml presence?.

                                    You are controlling this by the before-filter config.

                                    If it's AFTER_BUT_JAVA_ONLY then it's the same as what you get with parent-first=false.

                                     

                                    jb-cl-domain.xml is by default java-se compliant, meaning parent-first=true.

                                    It could be debated what should be the default, but I think this is more natural.