| /* |
| |
| Derby - Class org.apache.derbyTesting.functionTests.tests.upgradeTests.UpgradeClassLoader |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You 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.derbyTesting.functionTests.tests.upgradeTests; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.net.URLClassLoader; |
| import java.security.AccessController; |
| import java.security.PrivilegedAction; |
| |
| import junit.framework.Assert; |
| |
| import org.apache.derbyTesting.junit.BaseTestCase; |
| |
| /** |
| * <p> |
| * This class factors out the machinery needed to wrap a class loader around |
| * the jar files for an old release. |
| * </p> |
| */ |
| public class UpgradeClassLoader |
| { |
| private static final String[] jarFiles = { |
| "derby.jar", |
| //"derbynet.jar", |
| //"derbyclient.jar", |
| //"derbytools.jar" |
| }; |
| |
| static final String oldVersionsPath = |
| getSystemProperty(_Suite.OLD_VERSIONS_PATH_PROPERTY); |
| static final String jarPath = |
| getSystemProperty(_Suite.OLD_RELEASE_PATH_PROPERTY); |
| |
| private static String getSystemProperty(final String key) { |
| return AccessController.doPrivileged(new PrivilegedAction<String>() { |
| public String run() { |
| return System.getProperty(key); |
| } |
| }); |
| } |
| |
| protected static String getTextVersion(int[] iv) |
| { |
| String version = iv[0] + "." + iv[1] + |
| "." + iv[2] + "." + iv[3]; |
| return version; |
| } |
| |
| /** |
| * <p> |
| * Wrap a class loader around the given version. |
| * </p> |
| */ |
| public static ClassLoader makeClassLoader( final int[] version ) |
| { |
| ClassLoader oldLoader = AccessController.doPrivileged( |
| new PrivilegedAction<ClassLoader>() { |
| public ClassLoader run() { |
| return createClassLoader(version); |
| } |
| }); |
| |
| if (oldLoader == null) |
| { |
| BaseTestCase.traceit("Empty: Skip upgrade Tests (no jars) for " + getTextVersion(version)); |
| } |
| |
| return oldLoader; |
| } |
| |
| /** |
| * Get the location of jars of old release. The location is specified |
| * in the property derbyTesting.oldReleasePath. If derbyTesting.oldReleasePath |
| * is set to the empty string it is ignored. |
| * |
| * @return location of jars of old release |
| */ |
| private static String getOldJarLocation(int[] oldVersion) { |
| |
| if (jarPath == null || jarPath.length() == 0) |
| return null; |
| |
| String version = getTextVersion(oldVersion); |
| String jarLocation = jarPath + File.separator + version; |
| |
| return jarLocation; |
| } |
| |
| /** |
| * Get the location of jars of old release, using the url for svn at apache. |
| * |
| * @return location of jars of old release |
| */ |
| private static String getOldJarURLLocation(int[] oldVersion) { |
| |
| String oldJarUrl = _Suite.OLD_JAR_URL; |
| |
| String version = getTextVersion(oldVersion); |
| String jarLocation = oldJarUrl + "/" + version; |
| |
| return jarLocation; |
| } |
| |
| /** |
| * Create a class loader using jars in the specified location. Add all jars |
| * specified in jarFiles and the testing jar. |
| * |
| * @param version the Derby version to create a classloader for. |
| * @return class loader |
| */ |
| private static ClassLoader createClassLoader(int[] version) |
| { |
| URL[] url = new URL[jarFiles.length]; |
| |
| String jarLocation = getOldJarLocation(version); |
| |
| if (jarLocation != null) |
| { |
| File lib = new File(jarLocation); |
| |
| // If the jars do not exist then return null |
| // and the caller will set up to skip this. |
| if (!lib.exists()){ |
| BaseTestCase.alarm("Non-existing location for jar files: '" |
| + jarLocation + "'. Upgrade tests can NOT be run!"); |
| return null; |
| } |
| |
| for (int i=0; i < jarFiles.length; i++) { |
| try { |
| url[i] = new File(lib, jarFiles[i]).toURI().toURL(); |
| } catch (MalformedURLException e) { |
| Assert.fail(e.toString()); |
| } |
| } |
| } |
| else |
| |
| // if the property was not set, attempt to access the jars from |
| // the saved svn location. |
| // Note, this means the test fails if there is no network connection |
| // (or the server at apache is down) unless the property is set |
| // to a valid location |
| { |
| String oldURLJarLocation = getOldJarURLLocation(version); |
| for (int i=0; i < jarFiles.length; i++) { |
| try { |
| url[i] = new URL(oldURLJarLocation + "/" + jarFiles[i]); |
| Object dummy = url[i].getContent(); // IOException if not available. |
| } catch (MalformedURLException e) { |
| Assert.fail(e.toString()); |
| } catch (IOException e) { |
| BaseTestCase.alarm("IOException connecting to location: " + oldURLJarLocation + ", msg: '" + e.getMessage() + "'." |
| + " Upgrade tests can NOT be run!"); |
| e.printStackTrace(); |
| return null; |
| } |
| |
| } |
| } |
| |
| // Create a class loader which loads Derby classes from the specified |
| // URL, and JDBC classes and other system classes from the platform |
| // class loader. |
| ClassLoader oldVersionLoader = |
| new URLClassLoader(url, java.sql.Connection.class.getClassLoader()); |
| |
| // DERBY-5316: We need to unload the JDBC driver when done with it, |
| // but that can only be done if the DriverUnloader class lives in a |
| // class-loader which is able to load the driver class. |
| return new ClassLoader(oldVersionLoader) { |
| protected Class findClass(String name) |
| throws ClassNotFoundException { |
| if (name.equals(DriverUnloader.class.getName())) { |
| try { |
| byte[] b = fetchDriverUnloaderBytes(); |
| return defineClass(name, b, 0, b.length); |
| } catch (IOException ioe) { |
| throw new ClassNotFoundException(name, ioe); |
| } |
| } |
| throw new ClassNotFoundException(name); |
| } |
| }; |
| } |
| |
| /** |
| * Get a byte array with the contents of the class file for the |
| * {@code DriverUnloader} class. |
| */ |
| private static byte[] fetchDriverUnloaderBytes() throws IOException { |
| InputStream in = |
| DriverUnloader.class.getResourceAsStream("DriverUnloader.class"); |
| try { |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| byte[] buf = new byte[4096]; |
| int len; |
| while ((len = in.read(buf)) > 0) { |
| out.write(buf, 0, len); |
| } |
| return out.toByteArray(); |
| } finally { |
| in.close(); |
| } |
| } |
| } |
| |
| |
| |