Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id C2B2CEC19 for ; Tue, 12 Feb 2013 20:22:24 +0000 (UTC) Received: (qmail 63019 invoked by uid 500); 12 Feb 2013 20:22:24 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 62916 invoked by uid 500); 12 Feb 2013 20:22:24 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 62908 invoked by uid 99); 12 Feb 2013 20:22:24 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 12 Feb 2013 20:22:24 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 12 Feb 2013 20:22:21 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 006C823889D7; Tue, 12 Feb 2013 20:22:00 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1445335 - in /commons/sandbox/beanutils2/trunk/src: changes/ main/java/org/apache/commons/beanutils2/ test/java/org/apache/commons/beanutils2/ Date: Tue, 12 Feb 2013 20:22:00 -0000 To: commits@commons.apache.org From: britter@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130212202201.006C823889D7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: britter Date: Tue Feb 12 20:22:00 2013 New Revision: 1445335 URL: http://svn.apache.org/r1445335 Log: [SANDBOX-441] - Handling of types that can not be instantiated in DefaultClassAccessor should be improved to give users better feedback Modified: commons/sandbox/beanutils2/trunk/src/changes/changes.xml commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanInstantiationException.java commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultClassAccessor.java commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/ConstructorsTestCase.java Modified: commons/sandbox/beanutils2/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/sandbox/beanutils2/trunk/src/changes/changes.xml?rev=1445335&r1=1445334&r2=1445335&view=diff ============================================================================== --- commons/sandbox/beanutils2/trunk/src/changes/changes.xml (original) +++ commons/sandbox/beanutils2/trunk/src/changes/changes.xml Tue Feb 12 20:22:00 2013 @@ -23,6 +23,10 @@ + + Handling of types that can not be instantiated in DefaultClassAccessor should + be improved to give users better feedback + Rename ClassLoaderBuilder.loadWithClassLoader to loadWith Modified: commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanInstantiationException.java URL: http://svn.apache.org/viewvc/commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanInstantiationException.java?rev=1445335&r1=1445334&r2=1445335&view=diff ============================================================================== --- commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanInstantiationException.java (original) +++ commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanInstantiationException.java Tue Feb 12 20:22:00 2013 @@ -27,7 +27,12 @@ public class BeanInstantiationException public BeanInstantiationException( Class beanType, Throwable cause ) { - super( cause, beanType, "Could not create a new instance of type '%s'.", beanType ); + super( cause, beanType, "Cannot not create a new instance of type '%s'.", beanType ); + } + + BeanInstantiationException( Class beanType, String reason ) + { + super( null, beanType, "Cannot not create a new instance of type '%s'. Reason: " + reason, beanType ); } } Modified: commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultClassAccessor.java URL: http://svn.apache.org/viewvc/commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultClassAccessor.java?rev=1445335&r1=1445334&r2=1445335&view=diff ============================================================================== --- commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultClassAccessor.java (original) +++ commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultClassAccessor.java Tue Feb 12 20:22:00 2013 @@ -23,6 +23,8 @@ import static org.apache.commons.beanuti import static org.apache.commons.beanutils2.Assertions.checkNoneIsNull; import static org.apache.commons.beanutils2.Assertions.checkNotNull; +import static java.lang.reflect.Modifier.isAbstract; + import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -50,19 +52,7 @@ final class DefaultClassAccessor */ public BeanAccessor newInstance() { - try - { - B bean = beanClass.newInstance(); - return new DefaultBeanAccessor( bean ); - } - catch ( InstantiationException e ) - { - throw new BeanInstantiationException( beanClass, e ); - } - catch ( IllegalAccessException e ) - { - throw new ConstructorNotAccessibleException( beanClass, e ); - } + return invokeConstructor(); } // constructors @@ -104,6 +94,7 @@ final class DefaultClassAccessor */ private BeanAccessor invokeConstructor( boolean exact, Argument... arguments ) { + checkInstantiable(); @SuppressWarnings( "unchecked" ) // type driven by beanClass Constructor constructor = (Constructor) constructorRegistry.get( exact, beanClass, @@ -125,6 +116,35 @@ final class DefaultClassAccessor return new DefaultBeanAccessor( bean ); } + /** + * Checks if {@code beanClass} is instantiable and throws a {@link BeanInstantiationException} with an appropriate + * message otherwise. + */ + private void checkInstantiable() + { + if ( beanClass.isInterface() ) + { + throw new BeanInstantiationException( beanClass, "Type is an interface." ); + } + if ( beanClass.isArray() ) + { + throw new BeanInstantiationException( beanClass, "Type is an array class." ); + } + if ( beanClass.isPrimitive() ) + { + throw new BeanInstantiationException( beanClass, "Type is primitive." ); + } + if ( beanClass.equals( Void.TYPE ) ) + { + throw new BeanInstantiationException( beanClass, "Type represents void." ); + } + // has to be the last check because primitives and array types are also abstract + if ( isAbstract( beanClass.getModifiers() ) ) + { + throw new BeanInstantiationException( beanClass, "Type is abstract." ); + } + } + private B doInvokeConstructor( Constructor constructor, Object[] parameterObjects ) { try Modified: commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/ConstructorsTestCase.java URL: http://svn.apache.org/viewvc/commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/ConstructorsTestCase.java?rev=1445335&r1=1445334&r2=1445335&view=diff ============================================================================== --- commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/ConstructorsTestCase.java (original) +++ commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/ConstructorsTestCase.java Tue Feb 12 20:22:00 2013 @@ -27,7 +27,9 @@ import static org.junit.Assert.assertNot import org.apache.commons.beanutils2.testbeans.AbstractTestBean; import org.apache.commons.beanutils2.testbeans.TestBean; import org.apache.commons.beanutils2.testbeans.ThrowingExceptionBean; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; /** *

@@ -36,6 +38,10 @@ import org.junit.Test; */ public class ConstructorsTestCase { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + // ------------------------------------------------ Individual Test Methods @Test @@ -250,11 +256,64 @@ public class ConstructorsTestCase on( ThrowingExceptionBean.class ).invokeConstructor( argument( Byte.class, Byte.valueOf( (byte) 4711 ) ) ); } - @Test( expected = BeanInstantiationException.class ) + @Test public void invokeConstructorOnAbstract() throws Exception { + thrown.expect( BeanInstantiationException.class ); + thrown.expectMessage( "abstract" ); on( AbstractTestBean.class ).invokeConstructor(); } + @Test + public void invokeConstructorOnInterface() + throws Exception + { + thrown.expect( BeanInstantiationException.class ); + thrown.expectMessage( "interface" ); + on( ClassAccessor.class ).invokeConstructor(); + } + + @Test + public void invokeConstructorOnArray() + throws Exception + { + thrown.expect( BeanInstantiationException.class ); + thrown.expectMessage( "array" ); + on( String[].class ).invokeConstructor(); + } + + @Test + public void invokeConstructorOnPrimitive() + throws Exception + { + thrown.expect( BeanInstantiationException.class ); + thrown.expectMessage( "primitive" ); + on( int.class ).invokeConstructor(); + } + + @Test + public void invokeConstructorOnVoid() + throws Exception + { + thrown.expect( BeanInstantiationException.class ); + thrown.expectMessage( "void" ); + on( void.class ).invokeConstructor(); + } + + @Test( expected = NoSuchConstructorException.class ) + public void newInstanceWithoutDefaultConstructor() + { + on( NoDefaultConstructor.class ).newInstance(); + } + + public static class NoDefaultConstructor + { + + NoDefaultConstructor( int i ) + { + // do nothing here + } + } + }