Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 90742 invoked from network); 20 Jan 2006 14:27:15 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 20 Jan 2006 14:27:15 -0000 Received: (qmail 23813 invoked by uid 500); 20 Jan 2006 14:27:15 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 23737 invoked by uid 500); 20 Jan 2006 14:27:14 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 23725 invoked by uid 99); 20 Jan 2006 14:27:14 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Jan 2006 06:27:14 -0800 X-ASF-Spam-Status: No, hits=-8.6 required=10.0 tests=ALL_TRUSTED,INFO_TLD,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Fri, 20 Jan 2006 06:27:11 -0800 Received: (qmail 90237 invoked by uid 65534); 20 Jan 2006 14:26:51 -0000 Message-ID: <20060120142651.90230.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r370815 [2/2] - in /db/derby/code/trunk: ./ java/build/org/apache/derbyBuild/ java/client/org/apache/derby/client/am/ java/client/org/apache/derby/loc/ java/engine/org/apache/derby/iapi/error/ java/engine/org/apache/derby/iapi/reference/ ja... Date: Fri, 20 Jan 2006 14:26:12 -0000 To: derby-commits@db.apache.org From: davidvc@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Added: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/i18n/MessageUtil.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/i18n/MessageUtil.java?rev=370815&view=auto ============================================================================== --- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/i18n/MessageUtil.java (added) +++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/i18n/MessageUtil.java Fri Jan 20 06:25:53 2006 @@ -0,0 +1,291 @@ +/* + Derby - Class org.apache.derby.common.i18n.MessageUtil + + Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + */ +package org.apache.derby.shared.common.i18n; + +import org.apache.derby.shared.common.error.ExceptionSeverity; +import java.util.Locale; +import java.util.ResourceBundle; +import java.util.MissingResourceException; +import java.text.MessageFormat; + +/** + * Class comments here + */ +public class MessageUtil +{ + public static final Locale US = new Locale("en", "US"); + + /** + * The name of the resource bundle we are using to load + * messages + */ + private String resourceBundleName; + + /** + * Create an instance of MessageUtil with a specific resource + * bundle. This assumes the default locale, which is just fine for + * users of this class other than the engine (which potentially has + * a different locale and a different resource bundle for each + * invocation of getCompleteMessage(). + * + * @param resourceBundleName + * The base name of the resource bundle to use. + */ + public MessageUtil(String resourceBundleName) + { + this.resourceBundleName = resourceBundleName; + } + + /** Get a message with default locale - no arguments */ + public String getTextMessage(String messageID) + { + return getCompleteMessage(messageID, (Object[]) null); + } + + /** Get a message with default locale - one argument */ + public String getTextMessage(String messageID, Object a1) + { + return getCompleteMessage(messageID, new Object[]{a1}); + } + + /** Get a message with default locale - two arguments */ + public String getTextMessage(String messageID, Object a1, Object a2) + { + return getCompleteMessage(messageID, new Object[]{a1, a2}); + } + + /** Get a message with default locale - three arguments */ + public String getTextMessage(String messageID, Object a1, Object a2, + Object a3) + { + return getCompleteMessage(messageID, new Object[]{a1, a2, a3}); + } + + /** Get a message with default locale - four arguments */ + public String getTextMessage(String messageID, Object a1, Object a2, + Object a3, Object a4) + { + return getCompleteMessage(messageID, new Object[]{a1, a2, a3, a4}); + } + + /** + * Instance method to get the complete message, using the + * provided resource bundle name as specified when this + * instance was constructed + * + * If for some reason the message could not be found, we return a + * default message using the message arguments + */ + public String getCompleteMessage(String messageID, Object[] args) + { + return getCompleteMessage(messageID, resourceBundleName, args); + } + + /** + * Generic routine to get a message with any number of arguments. + * + * Looks in the provided resource bundle for the message, using the + * specified locale and then the US locale. + * + * @param locale + * The locale to use when looking for the message. If the message + * is not found using this locale, we attempt to find it using the + * US locale (our default). + * + * @param resourceBundleName + * The base name for the resource bundle to use. + * + * @param messageId + * The message identifier for this message + * + * @param arguments + * The arguments for the message + * + * @param composeDefault + * If this is true, this method will compose a default message if + * the message could not be found in the + * provided resource bundles. If it is false, this method will + * throw a MissingResourceException if the message could not be + * found. + * + * @return + * The message for the given message id, with arguments + * substituted. + * + * @throw MissingResourceException + * If the message could not be found and the + * composeDefault parameter was set to false. + */ + public static String getCompleteMessage(Locale locale, + String resourceBundleName, String messageId, Object[] arguments, + boolean composeDefault) throws MissingResourceException + { + try + { + return formatMessage( + ResourceBundle.getBundle(resourceBundleName, locale), messageId, + arguments, false); + } + catch ( MissingResourceException mre ) + { + // Try the US locale. Use composeDefault to indicate whether + // we should compose a default message or throw an exception if + // the message still is not found. + return formatMessage( + ResourceBundle.getBundle(resourceBundleName, US), + messageId, arguments, composeDefault); + } + } + + /** + * This is a wrapper for the getCompleteMessage workhorse routine + * using some obvious defaults, particularly for non-engine subsystems + * that only ever use the default locale. + * + * Get a message using the default locale. If the message is not found + * with the default locale, use the US locale. Do this both for the + * common bundle and the parent bundle. + * + * If the message is not found in common or in the parent resource + * bundle, return a default message composed of the message arguments. + * + * @param messageId + * The id to use to look up the message + * + * @param resourceBundleName + * The base name of the resource bundle to use. + * + * @param arguments + * The arguments to the message + */ + public static String getCompleteMessage(String messageId, + String resourceBundleName, Object[] arguments) + throws MissingResourceException + { + return getCompleteMessage(Locale.getDefault(), resourceBundleName, + messageId, arguments, true); + } + + /** + * Format a message given a resource bundle and a message id. + *

+ * The arguments to the messages are passed via an object array. The objects + * in the array WILL be changed by this class. The caller should NOT get the + * object back from this array. + * + * @param bundle + * The resource bundle to use to look for the message + * + * @param messageId + * The message id to use for the message + * + * @param arguments + * The arguments for the message + * + * @param composeDefault + * Indicates whether a default message should be composed if + * the message can't be found in the resource bundle. + *

+ * If composeDefault is false, this method will + * throw a MissingResourceException if the message could not be + * found. + *

+ * If composeDefault is true, then if the message id is not found in + * the given bundle, this method composes and returns as helpful a + * message as possible in the format "UNKNOWN : [arg1], [arg2], ..." + */ + public static String formatMessage(ResourceBundle bundle, String messageId, + Object[] arguments, boolean composeDefault) { + + String message = null; + + if (arguments == null) + arguments = new Object[0]; + + if (bundle != null) { + + try { + message = bundle.getString(messageId); + + try { + return MessageFormat.format(message, arguments); + } + catch (IllegalArgumentException iae) { + } + catch (NullPointerException npe) { + // + //null arguments cause a NullPointerException. + //This improves reporting. + } + + } catch (MissingResourceException mre) { + // caller will try and handle the last chance + if (!composeDefault) + throw mre; + } + } + + return composeDefaultMessage(messageId, arguments); + } + + /** + * Compose a default message so that the user at least gets + * *something* useful rather than just a MissingResourceException, + * which is particularly unhelpful + * + * @param message + * The message to start with, which often is null + * + * @param arguments + * The arguments to the message. + */ + public static String composeDefaultMessage(String message, Object[] arguments) + { + if (message == null) + { + message = "UNKNOWN"; + } + + StringBuffer sb = new StringBuffer(message); + + if ( arguments == null ) + { + return sb.toString(); + } + + sb.append(" : "); + int len = arguments.length; + + for (int i=0; i < len; i++) { + // prepend a comma to all but the first + if (i > 0) + sb.append(", "); + + sb.append('['); + sb.append(i); + sb.append("] "); + if (arguments[i] == null) + sb.append("null"); + else + sb.append(arguments[i].toString()); + } + + return sb.toString(); + } +} Propchange: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/i18n/MessageUtil.java ------------------------------------------------------------------------------ svn:eol-style = native Added: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/info/JVMInfo.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/info/JVMInfo.java?rev=370815&view=auto ============================================================================== --- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/info/JVMInfo.java (added) +++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/info/JVMInfo.java Fri Jan 20 06:25:53 2006 @@ -0,0 +1,178 @@ +/* + + Derby - Class org.apache.derby.shared.common.info.JVMInfo + + Copyright 1999, 2004 The Apache Software Foundation or its licensors, as applicable. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + */ + +package org.apache.derby.shared.common.info; + +import org.apache.derby.shared.common.reference.JDBC20Translation; +import org.apache.derby.shared.common.reference.JDBC30Translation; + + +/** + * This is a COPY of org.apache.derby.iapi.services.info.JVMInfo. + * + * TODO - have the engine code start using this class once the shared + * infrastructure is in place. + */ +public abstract class JVMInfo +{ + /** + The JVM's runtime environment. +

    +
  • 1 - not used was JDK 1.1 +
  • 2 - J2SE_13- JDK 1.2, 1.3 +
  • 4 - J2SE_14 - JDK 1.4.0 or 1.4.1 +
  • 5 - J2SE_142 - JDK 1.4.2 +
  • 6 - J2SE_15 - JDK 1.5 +
+ @return The JVM's runtime environment. + */ + public static final int JDK_ID; + + public static final int J2SE_13 = 2; + public static final int J2SE_14 = 4; + public static final int J2SE_142 = 5; + public static final int J2SE_15 = 6; // aka J2SE 5.0 + public static final int J2SE_16 = 7; + + public static final boolean J2ME; + + /** + JDBC Boolean type - Types.BIT in JDK1.1 & 1.2 & 1.3, Types.BOOLEAN in JDK1.4 + */ + public static final int JAVA_SQL_TYPES_BOOLEAN; + + static + { + int id; + + // + // If the property java.specification.version is set, then try to parse + // that. Anything we don't recognize, default to Java 2 platform + // because java.specification.version is a property that is introduced + // in Java 2. We hope that JVM vendors don't implement Java 1 and + // set a Java 2 system property. + // + // Otherwise, see if we recognize what is set in java.version. + // If we don't recoginze that, or if the property is not set, assume + // version 1.3. + // + String javaVersion; + String javaSpec; + boolean isJ2ME; + + try { + javaSpec = System.getProperty("java.specification.name"); + } catch (SecurityException se) { + // some vms do not know about this property so they + // throw a security exception when access is restricted. + javaSpec = null; + } + + try { + javaVersion = System.getProperty("java.specification.version", "1.3"); + + } catch (SecurityException se) { + // some vms do not know about this property so they + // throw a security exception when access is restricted. + javaVersion = "1.3"; + } + + if (javaSpec != null && javaSpec.startsWith("J2ME")) + { + // IBM's WCTME 5.7 returns these values for CDC 1.0 profiles. + // "J2ME Foundation Specification" + // + + // Foundation 1.0 and Personal Profile 1.0 based + // upon CDC 1.0 which is JDK 1.3 based + id = J2SE_13; + isJ2ME = true; + } + else + { + // J2SE/J2EE + isJ2ME = false; + + if (javaVersion.equals("1.2") || javaVersion.equals("1.3")) + { + id = J2SE_13; //jdk1.3 is still Java2 platform with the same API + } + else if (javaVersion.equals("1.4")) + { + String vmVersion = System.getProperty("java.version", "1.4.0"); + + if (JVMInfo.vmCheck(vmVersion, "1.4.0") || JVMInfo.vmCheck(vmVersion, "1.4.1")) + id = J2SE_14; + else + id = J2SE_142; + } + else if (javaVersion.equals("1.5")) + { + id = J2SE_15; + } + else if (javaVersion.equals("1.6")) + { + id = J2SE_16; + } + else + { + // aussme our lowest support unless the java spec + // is greater than our highest level. + id = J2SE_13; + + try { + + if (Float.valueOf(javaVersion).floatValue() > 1.4f) + id = 5; + } catch (NumberFormatException nfe) { + } + } + } + + JDK_ID = id; + J2ME = isJ2ME; + JAVA_SQL_TYPES_BOOLEAN = (isJ2ME || id >= J2SE_14) ? + JDBC30Translation.SQL_TYPES_BOOLEAN :java.sql.Types.BIT; + } + + /** + Check the vmVersion against a speciifc value. + Sun jvms are of the form + */ + private static boolean vmCheck(String vmVersion, String id) + { + return vmVersion.equals(id) || vmVersion.startsWith(id + "_"); + } + + /** + Return Derby's understanding of the virtual machine's environment. + */ + public static String derbyVMLevel() + { + switch (JDK_ID) + { + case J2SE_13: return J2ME ? "J2ME - JDBC for CDC/FP 1.0" : "J2SE 1.3 - JDBC 2.1"; + case J2SE_14: return "J2SE 1.4 - JDBC 3.0"; + case J2SE_142: return "J2SE 1.4.2 - JDBC 3.0"; + case J2SE_15: return "J2SE 5.0 - JDBC 3.0"; + default: return "?-?"; + } + } +} Propchange: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/info/JVMInfo.java ------------------------------------------------------------------------------ svn:eol-style = native Copied: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/JDBC20Translation.java (from r370178, db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/JDBC20Translation.java) URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/JDBC20Translation.java?p2=db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/JDBC20Translation.java&p1=db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/JDBC20Translation.java&r1=370178&r2=370815&rev=370815&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/JDBC20Translation.java (original) +++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/JDBC20Translation.java Fri Jan 20 06:25:53 2006 @@ -1,6 +1,6 @@ /* - Derby - Class org.apache.derby.iapi.reference.JDBC20Translation + Derby - Class org.apache.derby.shared.common.reference.JDBC20Translation Copyright 1999, 2004 The Apache Software Foundation or its licensors, as applicable. @@ -18,7 +18,7 @@ */ -package org.apache.derby.iapi.reference; +package org.apache.derby.shared.common.reference; import java.sql.ResultSet; import javax.transaction.xa.XAResource; Copied: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/JDBC30Translation.java (from r370178, db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/JDBC30Translation.java) URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/JDBC30Translation.java?p2=db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/JDBC30Translation.java&p1=db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/JDBC30Translation.java&r1=370178&r2=370815&rev=370815&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/JDBC30Translation.java (original) +++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/JDBC30Translation.java Fri Jan 20 06:25:53 2006 @@ -1,6 +1,6 @@ /* - Derby - Class org.apache.derby.iapi.reference.JDBC30Translation + Derby - Class org.apache.derby.shared.common.reference.JDBC30Translation Copyright 2001, 2004 The Apache Software Foundation or its licensors, as applicable. @@ -18,7 +18,7 @@ */ -package org.apache.derby.iapi.reference; +package org.apache.derby.shared.common.reference; import java.sql.DatabaseMetaData; import java.sql.ParameterMetaData; import java.sql.ResultSet; Copied: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (from r370178, db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/SQLState.java) URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?p2=db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java&p1=db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/SQLState.java&r1=370178&r2=370815&rev=370815&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/SQLState.java (original) +++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Fri Jan 20 06:25:53 2006 @@ -1,8 +1,8 @@ /* - Derby - Class org.apache.derby.iapi.reference.SQLState + Derby - Class org.apache.derby.shared.common.reference.SQLState - Copyright 1999, 2004 The Apache Software Foundation or its licensors, as applicable. + Copyright 2006 The Apache Software Foundation or its licensors, as applicable. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ */ -package org.apache.derby.iapi.reference; +package org.apache.derby.shared.common.reference; /** @@ -357,7 +357,7 @@ String RAWSTORE_CANNOT_CHANGE_LOGDEVICE = "XSRS8.S"; String RAWSTORE_RECORD_VANISHED = "XSRS9.S"; String BACKUP_BLOCKING_OPERATIONS_IN_PROGRESS = "XSRSA.S"; - String BACKUP_OPERATIONS_NOT_ALLOWED_IN_ACTIVE_XACT = "XSRSB.S"; + String BACKUP_OPERATIONS_NOT_ALLOWED = "XSRSB.S"; /* @@ -1479,6 +1479,25 @@ String UNSERIALIZABLE_CONNECTION = "XJ038.U"; String NO_UPGRADE = "XJ050.U"; + /** + * Client-specific JDBC messages + * We use the class XN to distinguish these from engine-specific or + * shared message ids + * + * I don't try to organize by severity because it's just too hard + * to keep track of the numbers to ensure we don't duplicate the + * SQL State + */ + String NOGETCONN_ON_CLOSED_POOLED_CONNECTION = "XN001.C"; + String INVALID_BLOB_OFFSET = "XN003.S"; + String WASNULL_INVALID = "XN004.S"; + String INVALID_PARAM_USE_GETINT = "XN005.S"; + String CALENDAR_IS_NULL = "XN006.S"; + String JDBC2_METHOD_NOT_IMPLEMENTED = "XN007.S"; + String JDBC3_METHOD_NOT_SUPPORTED = "XN008.S"; + String PARAM_NOT_OUT_OR_INOUT = "XN009.S"; + String RETURN_PARAM_MUST_BE_INT = "XN010.S"; + /* ** org.apache.derby.database.UserUtility */ Added: db/derby/code/trunk/java/shared/org/apache/derby/shared/package.html URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/shared/org/apache/derby/shared/package.html?rev=370815&view=auto ============================================================================== --- db/derby/code/trunk/java/shared/org/apache/derby/shared/package.html (added) +++ db/derby/code/trunk/java/shared/org/apache/derby/shared/package.html Fri Jan 20 06:25:53 2006 @@ -0,0 +1,186 @@ + + + + + + + + +

This package and its sub-packages provides functionality that is +shared between top-level Derby jar files. +

+NOTE - at this time, this code is not yet shared, but is used solely +by derbyclient.jar. The code placed here was to enable internationalization +of the client. It is put under the shared package because we expect +a framework to be put into place soon that will allow sharing across +jar files. +

+

List of Available Shared Components

+Shared code is provided through one or more shared components. +This section lists each shared component, providing essential information for +the consumers of these components. +

+When you create a shared component, you need to add a section here to describe +it for your consumers. +

+NOTE: Introducing a new shared component requires a vote with +consensus approval. Adding a new package within an existing shared component +requires a vote with lazy consensus. This is to help ensure that +what we are sharing makes sense and does not accidentally paint us into +some kind of architectural corner. Adding new classes or methods to an +existing shared package does not need to be put up for a vote but should be +reviewed using the standard patch review mechanism. +

Common

+Description: +
+This shared component is for code that is (or could be) used across all +Derby jar files. This is a good place for utility routines and services +such as logging/tracing, internationalization, error handling, etc. +

+Packages: +
+The Common shared component contains the following packages, all under +org.apache.derby.shared +
+

    +
  • common.error - utility code for error and exception handling +
  • common.i18n - utility code for internationlization +
  • common.reference - contains classes with shared constants +
  • common.info - utility code that provides runtime information +
+

+Consumers +
+The only jar file currently using (and thus including) the packages in this +component is derbyclient.jar but it is intended to be used by other jar +files once we have a working shared component infrastructure in place. +

Terms and Definitions

+

+Shared Component +
+A shared component is a collection of one or more packages under +org.apache.derby.shared that is used by code in more than one +Derby jar file (for example, between derbyclient.jar and derby.jar, or between +derbynet.jar and derbytools.jar). +

+There need only be one shared component +in the system (e.g. the shared package and all its subpackages), but in some +cases it may be desirable or necessary to split out some of these packages into +a separate shared component. For example, if there are packages that only need +to be shared between the network client and the network server, there is no need +to put these classes into derby.jar, and thus these should probably be +pulled out as a separate shared component. +

+Backward Compatibility +
+A consumer built against version X of a shared component should +work with version X' of a module where X' > X. This is called +backward compatibility. +

+Forward Compatibility +
+A consumer built against version X of a shared component should +work with version X' of a module where X' < X. This is called +forward compatibility. +

+Mixed Version Environment +
+If it is possible for two or more versions of Derby to be available to +the same classloader, this is called a mixed version environment. +It is a requirement that Derby continue to function correctly even in a +mixed version environment. In particular, a Derby class that consumes +a shared component must continue to run without failure, regardless of +the ordering of the search path of the classloader or any other factors. +

+Any shared code infrastructure that we implement must meet this +requirement. +

+

Issues with Compatibility

+Using backward and forward compatibility can allow Derby to run +fairly well in a mixed version environment. However, there +are a couple of significant issues with this approach. +

+First of all, maintaining compatibility, particularly forward compatibility, +places a huge burden of responsibility on Derby engineers, and can also +create some ugly code. Basically, for forward compatibility, you are required +to check to see if any new feature exists in the current runtime environment +before actually using that feature. This can get pretty ugly. +

+Maintaining backward and forward compatibility also does +not solve the issue of +shadowing. Shadowing occurs when a particular application is upgraded +to use the new behavior of an existing +shared component, but this behavior is not available because it is shadowed by +an older version of the component. +

+For example, say Application A and Application B are both deployed in the +same application container. The jar files for A (including Derby jars) are +placed in directory A and the jar files for B (including Derby jars) are +placed in directory B. In this container environment, the jars for A are +loaded before the jars for B. +

+B is running at version 10.4 of Derby and A is running at 10.3. The Derby +code for B depends upon functionality provided in a new shared package that +does not exist in version 10.3. B then upgrades to 10.4.1 to get a bug fix, +and are quite happy. Then A upgrades to 10.4.0, which includes the new +shared package. The shared package in A shadows the shared package in B, +and all of a sudden B's bugfix disappears and regresses. +

+For these reasons, we need another approach that guarantees that the +correct version of a shared class +is loaded for each consumer. We need to guarantee that Application B +use 10.3 shared classes, and Application C uses 10.4 shared classes. +

+This can be solved in one of two ways. Which approach we use has yet to +be decided. +

+

    +
  • Derby classloader - in this approach a specialized classloader is +written that loads only from the correct jar file. This approach is +currently under investigation and implementation by David Van Couvering. +

    +

  • Code copying - in this approach, at build time every shared class +copied and given a different package name for each jar file that uses it. +For example, +org.apache.derby.shared.common.i18n.MessageUtil would be +copied as +org.apache.derby.shared.engine.common.i18n.MessageUtil +for use by derby.jar and as +org.apache.derby.shared.client.common.i18n.MessageUtil +for use by derbyclient.jar. In this way there is no chance of clashing +or shadowing in a mixed version environment. +

    +The problem with this approach is that developers must use discipline +to modify the original source file and not the generated +version. For this reason, this approach will only be used if the +classloader approach ends up being unfeasible. +

+

+Note that these solutions do not allow complete flexibility +in terms of mixed version environments. In particular, the application +programmer or runtime administrator can not run two different versions of +the embedded driver within the same classloader. As a matter of fact, +that exact configuration is currently not allowed. The proposed solutions +only guarantee that if you do have a mixed version environment +(even by accident), nothing strange or unexpected will happen. It also +allows the network driver to run at +a different version from the embedded driver within the same classloader. +

Location +and Distribution of Shared Components

+

All shared components should comprise of one or more packages +under the package org.apache.derby.shared +(stored in the source tree under +java/common/org/apache/derby/shared). +

+

Although it would be conceptually nice to have a separate JAR file +for each shared component, it is a priority for us to keep a very +simple user experience. For this reason, the classes of a shared +components will be merged into the appropriate subset of the existing +jar files. +

+

User Visible +Impact and Restrictions

+The intent is that the shared component infrastructure and code will have +minimal to no visible impact to users. + + Propchange: db/derby/code/trunk/java/shared/org/apache/derby/shared/package.html ------------------------------------------------------------------------------ svn:eol-style = native Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/blobclob4BLOB.out URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/blobclob4BLOB.out?rev=370815&r1=370814&r2=370815&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/blobclob4BLOB.out (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/blobclob4BLOB.out Fri Jan 20 06:25:53 2006 @@ -712,10 +712,10 @@ START: blobTest54 EXPECTED SQLSTATE(XCL12): An attempt was made to put a data value of type 'byte[]' into a data value of type 'INTEGER'. START: blobTest6 -EXPECTED SQLSTATE(null): Invalid position 0 or length 5 -EXPECTED SQLSTATE(null): Invalid position 1 or length -76 -EXPECTED SQLSTATE(null): Search pattern cannot be null. -EXPECTED SQLSTATE(null): Search pattern cannot be null. +EXPECTED SQLSTATE(XJ070): Negative or zero position argument '0' passed in a Blob or Clob method. +EXPECTED SQLSTATE(XJ071): Zero or negative length argument '-76' passed in a BLOB or CLOB method. +EXPECTED SQLSTATE(XJ072): Null pattern or searchStr passed in to a BLOB or CLOB position method. +EXPECTED SQLSTATE(XJ072): Null pattern or searchStr passed in to a BLOB or CLOB position method. blobTest6 finished START: blobTest7 blobTest7 finished Modified: db/derby/code/trunk/tools/ant/properties/dirs.properties URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/tools/ant/properties/dirs.properties?rev=370815&r1=370814&r2=370815&view=diff ============================================================================== --- db/derby/code/trunk/tools/ant/properties/dirs.properties (original) +++ db/derby/code/trunk/tools/ant/properties/dirs.properties Fri Jan 20 06:25:53 2006 @@ -35,6 +35,7 @@ derby.engine.src.dir=${derbysrc.dir}/engine derby.drda.src.dir=${derbysrc.dir}/drda derby.client.src.dir=${derbysrc.dir}/client +derby.shared.src.dir=${derbysrc.dir}/shared derby.tools.src.dir=${derbysrc.dir}/tools derby.build.src.dir=${derbysrc.dir}/build derby.demo.src.dir=${derbysrc.dir}/demo @@ -43,12 +44,14 @@ derby.engine.dir=${derby.engine.src.dir}/${derby.dir} derby.drda.dir=${derby.drda.src.dir}/${derby.dir} -derby.client.dir=${derby.client.src.dir}/{derby.dir} +derby.client.dir=${derby.client.src.dir}/${derby.dir} +derby.shared.dir=${derby.shared.src.dir}/${derby.dir} derby.tools.dir=${derby.tools.src.dir}/${derby.dir} derby.build.dir=${derby.build.src.dir}/org/apache/derbyBuild derby.locales.dir=${derby.engine.dir}/loc derby.drda.locales.dir=${derby.drda.dir}/loc/drda derby.tools.locales.dir=${derby.tools.dir}/loc +derby.client.locales.dir=${derby.client.dir}/loc sanity.dir=${derby.engine.dir}/iapi/services/sanity sanity.out.dir=${out.dir}/${derby.dir}/iapi/services/sanity