001: /*
002:
003: Derby - Class org.apache.derbyTesting.functionTests.tests.lang.AggregateClassLoading
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.functionTests.tests.lang;
023:
024: import java.net.URL;
025: import java.net.URLClassLoader;
026: import java.sql.Connection;
027: import java.sql.ResultSet;
028: import java.sql.SQLException;
029: import java.sql.Statement;
030:
031: import org.apache.derby.tools.ij;
032:
033: /**
034: * Test for ensuring the aggregate implementation classes are loaded
035: * correctly, even when the context class loader loads Derby engine
036: * classes as well. This is a typical situation we have seen with
037: * J2EE servers where Derby may be in the application WAR and provided
038: * as a system service by the container.
039: * <BR>
040: * Jira issue DERBY-997
041: * <BR>
042: * Assumes embedded and only needs to be run in embedded, since
043: * all class loading happens on the engine side.
044: *
045: */
046: public class AggregateClassLoading {
047:
048: public static void main(String[] args) throws Exception {
049:
050: System.out.println("Test AggregateClassLoading starting");
051:
052: // use the ij utility to read the property file and
053: // make the initial connection.
054: ij.getPropertyArg(args);
055: Connection conn = ij.startJBMS();
056:
057: // Find the location of the code for the Derby connection.
058: // The rest of the engine will be at the same location!
059: URL derbyURL = conn.getClass().getProtectionDomain()
060: .getCodeSource().getLocation();
061:
062: // Create a new loader that loads from the same location as the engine.
063: // Create it without a parent, otherwise the parent
064: // will be the class loader of this class which is most likely
065: // the same as the engine. Since the class loader delegates to
066: // its parent first the bug would not show, as all the derby
067: // engine classes would be from a single loader.
068: URLClassLoader cl = new URLClassLoader(new URL[] { derbyURL },
069: null);
070: Thread.currentThread().setContextClassLoader(cl);
071:
072: Statement s = conn.createStatement();
073:
074: s.execute("create table t (i int)");
075: s
076: .execute("insert into t values 1,2,3,4,5,6,null,4,5,456,2,4,6,7,2144,44,2,-2,4");
077: System.out.println(s.getUpdateCount() + " rows inserted");
078:
079: // Test some aggregates, their generated class will attempt
080: // to load the internal aggregate through the context loader
081: // first, and then any remaining loader.
082: testAggregate(s, "select MAX(i) from t");
083: testAggregate(s, "select MIN(i) from t");
084: testAggregate(s, "select AVG(i) from t");
085: testAggregate(s, "select COUNT(i) from t");
086: testAggregate(s, "select COUNT(*) from t");
087:
088: s.execute("drop table t");
089: s.close();
090: conn.close();
091:
092: Thread.currentThread().setContextClassLoader(null);
093: }
094:
095: /**
096: * Just run and display the aggregates result.
097: */
098: private static void testAggregate(Statement s, String query) {
099: try {
100: ResultSet rs = s.executeQuery(query);
101: rs.next();
102: System.out.println("query = " + rs.getInt(1));
103: rs.close();
104: } catch (SQLException e) {
105: System.out.println("FAIL " + e.getSQLState() + " "
106: + e.getMessage());
107: // TODO Auto-generated catch block
108: e.printStackTrace(System.out);
109: }
110: }
111: }
|