You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Magesh Umasankar <um...@apache.org> on 2002/03/03 10:02:57 UTC

addXXX related question

Hi,

In the FilterChain class of the sandbox/filterreader proposal,
I have the following:

public final void addClassConstants(final ClassConstants classConstants) {
    filterReaders.addElement(classConstants);
}

There are numerous other addXXX methods also.

ClassConstants invokes BCEL APIs.  This is the only
addXXX method that takes in as argument a class that
depends upon an external API, currently.

Now, consider this scenario:

<copy file=blah" tofile="foo">
    <filterchain>
        <replacetokens>
            <token key="FOO" value="BAR"/>
        </replacetokens>
    </filterchain>
</copy>

When Ant is invoked without bcel.jar anywhere
in Ant's classpath, I am not able to execute this,
eventhough the filter that I am using is not
dependent upon an external jar.

The problem seems to be in IntrospectionHelper/
ProjectHelper.  If the method name begins with
"add", IntrospectionHelper requires to be able to 
create an instance of the argument, whether 
it is used as an element in the build file or not.
If it does not find the class, it throws a 
NoClassDefFoundError.

Is this limitation intended?  If so, why?
I wish to be able to provide FilterChain.java with
addXXX methods that may depend upon external APIs.
However, that must not translate into the user
having to have all those ext jars irrespective
of whether she is going to be using those filters
(with ext. deps.) or not.

Cheers,
Magesh



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: addXXX related question

Posted by Magesh Umasankar <um...@apache.org>.
From: "Peter Donald" <pe...@apache.org>

> On Mon, 4 Mar 2002 05:32, Magesh Umasankar wrote:
> > When I apply this patch (perhaps a bit hackish...), I can
> > work around the problem and everything works as I expect it to...
> > Please let me know if I can go ahead and apply this patch
> > against the main tree...
>
> The problem with this is what happens if they try to use the feature. They
> will not get a ClassNotFOundException - instead they will get a "nested
type
> X does not support attribute Y" which would cause more headaches IMO.
>

True.  I have created a helper class to which ClassConstants
delegates bcel based stuff.  This is good enough for me, for now,
and the Introspector is also happy...

>
> Pete
>

Cheers,
Magesh



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: addXXX related question

Posted by Peter Donald <pe...@apache.org>.
On Mon, 4 Mar 2002 05:32, Magesh Umasankar wrote:
> When I apply this patch (perhaps a bit hackish...), I can
> work around the problem and everything works as I expect it to...
> Please let me know if I can go ahead and apply this patch
> against the main tree...

The problem with this is what happens if they try to use the feature. They 
will not get a ClassNotFOundException - instead they will get a "nested type 
X does not support attribute Y" which would cause more headaches IMO.

Personally I would go with the wrapper approach for the time being

-- 
Cheers,

Pete

-----------------------------------------------
   "You can't depend on your eyes when your 
   imagination is out of focus." -Mark Twain 
-----------------------------------------------


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: addXXX related question

Posted by Magesh Umasankar <um...@apache.org>.
From: "Magesh Umasankar" <um...@apache.org>

> From: "Peter Donald" <pe...@apache.org>
>
> > On Sun, 3 Mar 2002 20:02, Magesh Umasankar wrote:
> > > The problem seems to be in IntrospectionHelper/
> > > ProjectHelper.  If the method name begins with
> > > "add", IntrospectionHelper requires to be able to
> > > create an instance of the argument, whether
> > > it is used as an element in the build file or not.
> > > If it does not find the class, it throws a
> > > NoClassDefFoundError.
> >
> > It is a feature of classloading. When you define the FilterChain class
you
> > need to able to define all classes it uses -
>
> I should be able to define all classes it uses, yes.  But
> why should I be forced to be able to instantiate them?
>
> > when you use reflection you
> > force the class to be fully defined. Thus it will try to load BCEL
anytime
> > you perform reflection on FilterChain.
>
> FilterChain uses ClassConstants - that is all.  It doesn't
> know about bcel until it tries to instantiate ClassConstants...
> Why should it be trying to instantiate elements that have
> not been added in the build file.  From the code, I see that
> each "add" method's element's constructor is obtained
> and an object of the class created.  I still do not understand
> the reason behind this...
>
> >
> > A way around this would to provide an interface+wrapper type system.
Take
> a
> > look at how the mappers or regex objects behave to see what I mean.
> >
>
> Yes, seems like a wrapper would be needed...  But still,
> why the extra layer?  Or am I totally missing something?
>
> >
> > Pete
> >
>

When I apply this patch (perhaps a bit hackish...), I can
work around the problem and everything works as I expect it to...
Please let me know if I can go ahead and apply this patch
against the main tree...

Index: IntrospectionHelper.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/IntrospectionHelper.java
,v
retrieving revision 1.37
diff -u -w -r1.37 IntrospectionHelper.java
--- IntrospectionHelper.java 24 Feb 2002 08:57:02 -0000 1.37
+++ IntrospectionHelper.java 3 Mar 2002 18:21:25 -0000
@@ -348,6 +348,16 @@
                         });
                     nestedStorers.remove(name);
                 } catch (NoSuchMethodException nse) {
+                } catch (NoClassDefFoundError ncdfe) {
+                    String propName = getPropertyName(name, "add");
+                    nestedTypes.put(propName, args[0]);
+                    nestedCreators.put(propName, new NestedCreator() {
+                        public Object create(Object parent) {
+                            return new Object();
+                        }
+
+                    });
+                    nestedStorers.remove(name);
                 }
             }
         }

> Magesh
>

Cheers,
Magesh



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: addXXX related question

Posted by Magesh Umasankar <um...@apache.org>.
From: "Peter Donald" <pe...@apache.org>

> On Sun, 3 Mar 2002 20:02, Magesh Umasankar wrote:
> > The problem seems to be in IntrospectionHelper/
> > ProjectHelper.  If the method name begins with
> > "add", IntrospectionHelper requires to be able to
> > create an instance of the argument, whether
> > it is used as an element in the build file or not.
> > If it does not find the class, it throws a
> > NoClassDefFoundError.
>
> It is a feature of classloading. When you define the FilterChain class you
> need to able to define all classes it uses -

I should be able to define all classes it uses, yes.  But
why should I be forced to be able to instantiate them?

> when you use reflection you
> force the class to be fully defined. Thus it will try to load BCEL anytime
> you perform reflection on FilterChain.

FilterChain uses ClassConstants - that is all.  It doesn't
know about bcel until it tries to instantiate ClassConstants...
Why should it be trying to instantiate elements that have
not been added in the build file.  From the code, I see that
each "add" method's element's constructor is obtained
and an object of the class created.  I still do not understand
the reason behind this...

>
> A way around this would to provide an interface+wrapper type system. Take
a
> look at how the mappers or regex objects behave to see what I mean.
>

Yes, seems like a wrapper would be needed...  But still,
why the extra layer?  Or am I totally missing something?

>
> Pete
>

Cheers,
Magesh



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: addXXX related question

Posted by Peter Donald <pe...@apache.org>.
On Sun, 3 Mar 2002 20:02, Magesh Umasankar wrote:
> The problem seems to be in IntrospectionHelper/
> ProjectHelper.  If the method name begins with
> "add", IntrospectionHelper requires to be able to
> create an instance of the argument, whether
> it is used as an element in the build file or not.
> If it does not find the class, it throws a
> NoClassDefFoundError.

It is a feature of classloading. When you define the FilterChain class you 
need to able to define all classes it uses - when you use reflection you 
force the class to be fully defined. Thus it will try to load BCEL anytime 
you perform reflection on FilterChain.

A way around this would to provide an interface+wrapper type system. Take a 
look at how the mappers or regex objects behave to see what I mean.


-- 
Cheers,

Pete

----------------------------------------
Whatever you do will be insignificant, 
but it is very important that you do it. 
                              --Gandhi
----------------------------------------

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>