T5: TypeCoercer uses unsafe route for void to Integer

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

T5: TypeCoercer uses unsafe route for void to Integer

Michael Capper
Hi,

I've got a BeanForm in my Tapestry 5.0.9 Application, with the Bean
expecting some Integers as input. When I submit the form without
entering any data in these fields, I get an RuntimeException in the
TypeCoercerImpl (line 130), because while converting my void to Integer
it uses void --> String --> Long --> Integer, and comes accross a
NullPointerException in the constructor for a Long(String).

It seems the TypeCoercerImpl.findOrCreateCoercion(...) method preferes
this Coercion to the COERCION_NULL_TO_OBJECT, which in my case would
have suited me better.

To overcome this, I added a few lines in TypeCoercerImpl.coerce(...) at
line 130
<pre>
        try
        {
            result = coercion.coerce(input);
        }
        catch (Exception ex)
        {
            if (input == null)
            {
                try
                {
                        result = COERCION_NULL_TO_OBJECT.coerce(input);
                }
                catch (Throwable t)
                {
                    throw new
RuntimeException(ServiceMessages.failedCoercion(
                            input,
                            targetType,
                            coercion,
                            ex), ex);
                }
            }
            else
            throw new RuntimeException(ServiceMessages.failedCoercion(
                    input,
                    targetType,
                    coercion,
                    ex), ex);
        }
</pre>

Not sure about the side-effects of this workaround, but I thought I'd
post it, as it might be a bug.

Greetings,
M.C.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: T5: TypeCoercer uses unsafe route for void to Integer

JWiegman
Michael,

I just encountered this yesterday.  I actually think this is a bug
because the default NullFieldStrategy for TextFields is to leave nulls
as null, but the bug is that it still goes through the type conversion
hierarchy to do so (why not just return me null if you get a null?).
The more interesting problem is... What if the field is a primitive int
rather than an Integer?  Can't do null anymore!

There's an easier work around for the problem... You don't have to
modify Tapestry code.  Just add the following code to your app's Module:

        public static void contributeTypeCoercer(
                        Configuration<CoercionTuple> configuration) {
                add(configuration, void.class, Integer.class,
                                new Coercion<Void, Integer>() {
                                        public Integer coerce(Void
input) {
                                                return null;
                                        }
                                });
        }

        private static <S, T> void add(Configuration<CoercionTuple>
configuration,
                        Class<S> sourceType, Class<T> targetType,
Coercion<S, T> coercion) {
                CoercionTuple<S, T> tuple = new CoercionTuple<S,
T>(sourceType,
                                targetType, coercion);

                configuration.add(tuple);
        }

Hope that helps...

Joel

-----Original Message-----
From: Michael Capper [mailto:[hidden email]]
Sent: Wednesday, January 30, 2008 8:18 AM
To: [hidden email]
Subject: T5: TypeCoercer uses unsafe route for void to Integer

Hi,

I've got a BeanForm in my Tapestry 5.0.9 Application, with the Bean
expecting some Integers as input. When I submit the form without
entering any data in these fields, I get an RuntimeException in the
TypeCoercerImpl (line 130), because while converting my void to Integer
it uses void --> String --> Long --> Integer, and comes accross a
NullPointerException in the constructor for a Long(String).

It seems the TypeCoercerImpl.findOrCreateCoercion(...) method preferes
this Coercion to the COERCION_NULL_TO_OBJECT, which in my case would
have suited me better.

To overcome this, I added a few lines in TypeCoercerImpl.coerce(...) at
line 130 <pre>
        try
        {
            result = coercion.coerce(input);
        }
        catch (Exception ex)
        {
            if (input == null)
            {
                try
                {
                        result = COERCION_NULL_TO_OBJECT.coerce(input);
                }
                catch (Throwable t)
                {
                    throw new
RuntimeException(ServiceMessages.failedCoercion(
                            input,
                            targetType,
                            coercion,
                            ex), ex);
                }
            }
            else
            throw new RuntimeException(ServiceMessages.failedCoercion(
                    input,
                    targetType,
                    coercion,
                    ex), ex);
        }
</pre>

Not sure about the side-effects of this workaround, but I thought I'd
post it, as it might be a bug.

Greetings,
M.C.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]