You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2012/05/07 15:23:17 UTC

svn commit: r1335010 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/jdbc/authentication/ engine/org/apache/derby/loc/ testing/org/apache/derbyTesting/functionTests/tests/lang/

Author: rhillegas
Date: Mon May  7 13:23:17 2012
New Revision: 1335010

URL: http://svn.apache.org/viewvc?rev=1335010&view=rev
Log:
DERBY-5741: Improve error reporting for missing UserAuthenticators.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/SpecificAuthenticationServiceImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/SpecificAuthenticationServiceImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/SpecificAuthenticationServiceImpl.java?rev=1335010&r1=1335009&r2=1335010&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/SpecificAuthenticationServiceImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/SpecificAuthenticationServiceImpl.java Mon May  7 13:23:17 2012
@@ -138,7 +138,9 @@ public class SpecificAuthenticationServi
 		} catch (IllegalAccessException iae) {
 			t = iae;
 		}
-		throw StandardException.newException(SQLState.AUTHENTICATION_SCHEME_ERROR, t,
-					specificAuthenticationScheme);
+        
+        String  detail = t.getClass().getName() + ": " + t.getMessage();
+		throw StandardException.newException
+            ( SQLState.AUTHENTICATION_SCHEME_ERROR, specificAuthenticationScheme, detail );
 	}
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=1335010&r1=1335009&r2=1335010&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Mon May  7 13:23:17 2012
@@ -3826,8 +3826,9 @@ Guide.
 
             <msg>
                 <name>XBM0M.D</name>
-                <text>Error creating instance of authentication scheme class {0}.</text>
+                <text>Error creating an instance of a class named '{0}'. This class name was the value of the derby.authentication.provider property and was expected to be the name of an application-supplied implementation of org.apache.derby.authentication.UserAuthenticator. The underlying problem was: {1}</text>
                 <arg>className</arg>
+                <arg>detail</arg>
             </msg>
 
             <msg>

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java?rev=1335010&r1=1335009&r2=1335010&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java Mon May  7 13:23:17 2012
@@ -178,7 +178,7 @@ public final class ErrorCodeTest extends
         		{"XBM0J","Directory {0} already exists.","45000"},
         		{"XBM0K","Unknown sub-protocol for database name {0}.","45000"},
         		{"XBM0L","Specified authentication scheme class {0} does implement the authentication interface {1}.","45000"},
-        		{"XBM0M","Error creating instance of authentication scheme class {0}.","45000"},
+        		{"XBM0M","Error creating an instance of a class named '{0}'. This class name was the value of the derby.authentication.provider property and was expected to be the name of an application-supplied implementation of org.apache.derby.authentication.UserAuthenticator. The underlying problem was: {1}","45000"},
         		{"XBM0N","JDBC Driver registration with java.sql.DriverManager failed. See next exception for details. ","45000"},
         		{"XBM0P","Service provider is read-only. Operation not permitted. ","45000"},
         		{"XBM0Q","File {0} not found. Please make sure that backup copy is the correct one and it is not corrupted.","45000"},

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java?rev=1335010&r1=1335009&r2=1335010&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java Mon May  7 13:23:17 2012
@@ -102,6 +102,7 @@ public class NativeAuthenticationService
     private static  final   String  TWELTH_DB = "twelthDB";
     private static  final   String  THIRTEENTH_DB = "thirteenthDB";
     private static  final   String  FOURTEENTH_DB = "fourteenthDB";
+    private static  final   String  FIFTEENTH_DB = "fifteenthDB";
 
     private static  final   String  NAST1_JAR_FILE = "nast1.jar";
     private static  final   String  NAST2_JAR_FILE = "nast2.jar";
@@ -135,6 +136,7 @@ public class NativeAuthenticationService
     private static  final   String  SQL_AUTHORIZATION_NOT_ON = "42Z60";
     private static  final   String  CANT_BOOT_DATABASE = "XJ040";
     private static  final   String  MISSING_USER = "XK001";
+    private static  final   String  BAD_USER_AUTHENTICATOR_CLASS = "XBM0M";
 
     private static  final   String      WEAK_AUTHENTICATION = "4251G";
     private static  final   String      HASHING_FORMAT_10_9 = "3b62";
@@ -160,6 +162,7 @@ public class NativeAuthenticationService
     private DatabaseChangeSetup _seventhDBSetup;
     private DatabaseChangeSetup _eighthDBSetup;
     private DatabaseChangeSetup _ninthDBSetup;
+    private DatabaseChangeSetup _fifteenthDBSetup;
 
     private String  _derbySystemHome;
     private String  _fullBackupDir;
@@ -562,6 +565,7 @@ public class NativeAuthenticationService
         result = TestConfiguration.additionalDatabaseDecoratorNoShutdown( result, TWELTH_DB );
         result = TestConfiguration.additionalDatabaseDecoratorNoShutdown( result, THIRTEENTH_DB );
         result = TestConfiguration.additionalDatabaseDecoratorNoShutdown( result, FOURTEENTH_DB );
+        result = _fifteenthDBSetup = TestConfiguration.additionalDatabaseDecoratorNoShutdown( result, FIFTEENTH_DB, true );
 
         result = TestConfiguration.changeUserDecorator( result, DBO, getPassword( DBO ) );
         
@@ -1200,7 +1204,23 @@ public class NativeAuthenticationService
         // and from trying to view the credentials table
         expectExecutionError( pearConn, NO_COLUMN_PERMISSION, "select * from " + dbo + ".t" );
         expectCompilationError( pearConn, DBO_ONLY_OPERATION, "select username from sys.sysusers" );
-        
+
+        // verify a sensible error if you try to set the authentication provider
+        // to the missing classname NATIVE. we only check this for the embedded
+        // case because the network scrunches exceptions together and we lose
+        // the structure which allows us to look for nested SQLStates.
+        if ( isEmbedded() )
+        {
+            Connection  fifteenthConn = openConnection( FIFTEENTH_DB, dbo, true, null );
+        
+            goodStatement
+                ( fifteenthConn, "call syscs_util.syscs_set_database_property( 'derby.connection.requireAuthentication', 'true' )" );
+            goodStatement
+                ( fifteenthConn, "call syscs_util.syscs_set_database_property( 'derby.authentication.provider', 'NATIVE' )" );
+            _fifteenthDBSetup.getTestConfiguration().shutdownDatabase();
+
+            getConnection( true, true, FIFTEENTH_DB, DBO, BAD_USER_AUTHENTICATOR_CLASS );
+        }
     }
     
     /**
@@ -1441,7 +1461,7 @@ public class NativeAuthenticationService
         {
             if ( shouldFail && (t instanceof SQLException) )
             {
-                String          actualSQLState = ((SQLException) t).getSQLState();
+                SQLException se = (SQLException) t;
                 StringBuffer    buffer = new StringBuffer();
 
                 //  ok if the sqlstate is one of the expected ones
@@ -1449,9 +1469,9 @@ public class NativeAuthenticationService
                 {
                     String  expected = expectedSQLStates[ i ];
                     buffer.append( " " + expected );
-                    if ( expected.equals( actualSQLState ) ) { return null; }
+                    if ( vetSQLState( se, expected ) ) { return null; }
                 }
-                fail( tagError( "SQLState " + actualSQLState + " not in expected list: " + buffer.toString() ) );
+                fail( tagError( "SQLState not in expected list: " + buffer.toString() ) );
             }
             else
             {
@@ -1462,6 +1482,22 @@ public class NativeAuthenticationService
 
         return conn;
     }
+    // look for a sql state in a SQLException and its chained exceptions. returns true if found
+    private boolean    vetSQLState( SQLException actual, String expectedSQLState )
+        throws Exception
+    {
+        if ( actual == null ) { return false; }
+
+        if ( expectedSQLState.equals( actual.getSQLState() ) ) { return true; }
+
+        Throwable   t = actual.getCause();
+        if ( t instanceof SQLException )
+        {
+            if ( vetSQLState( (SQLException) t, expectedSQLState ) ) { return true; }
+        }
+
+        return vetSQLState( actual.getNextException(), expectedSQLState );
+    }
 
     // connect but expect a warning that the password is about to expire
     private Connection  passwordExpiring( boolean expiring, String dbName, String user )