blob: 075f1d64dec10a41e332303d39cadb86818643a5 [file] [log] [blame]
/*
* 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.ignite.spi.deployment.uri;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.jetbrains.annotations.Nullable;
/**
* Loads classes and resources from "unpacked" deployment archives.
* <p>
* Class loader scans package directory first and then if
* class/resource was not found scans all JAR files.
*/
class GridUriDeploymentClassLoader extends URLClassLoader {
/**
* Creates new instance of class loader.
*
* @param urls The URLs from which to load classes and resources.
* @param parent The parent class loader for delegation.
*/
GridUriDeploymentClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
}
/** {@inheritDoc} */
@Override protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
// First, check if the class has already been loaded.
Class cls = findLoadedClass(name);
if (cls == null) {
try {
try {
// Search classes in a deployment unit.
// NOTE: findClass(String) is not overridden since it is always called after
// findLoadedClass(String) in exclusive synchronization block.
cls = findClass(name);
}
catch (ClassNotFoundException ignored) {
// If still not found, then invoke parent class loader in order
// to find the class.
cls = super.loadClass(name, resolve);
}
}
catch (ClassNotFoundException e) {
throw e;
}
// Catch Throwable to secure against any errors resulted from
// corrupted class definitions or other user errors.
catch (Exception e) {
throw new ClassNotFoundException("Failed to load class due to unexpected error: " + name, e);
}
}
return cls;
}
/**
* Load class from a deployment unit.
*
* @param name Class name.
* @return Loaded class.
* @throws ClassNotFoundException If no class found.
*/
public synchronized Class<?> loadClassIsolated(String name) throws ClassNotFoundException {
// First, check if the class has already been loaded.
Class<?> cls = findLoadedClass(name);
if (cls == null) {
try {
// Search classes in deployment unit.
// NOTE: findClass(String) is not overridden since it is always called after
// findLoadedClass(String) in exclusive synchronization block.
cls = findClass(name);
}
catch (ClassNotFoundException e) {
throw e;
}
// Catch Throwable to secure against any errors resulted from
// corrupted class definitions or other user errors.
catch (Exception e) {
throw new ClassNotFoundException("Failed to load class due to unexpected error: " + name, e);
}
}
return cls;
}
/**
* Load class from GAR file.
*
* @param name Class name.
* @return Loaded class.
* @throws ClassNotFoundException If no class found.
* @deprecated Use {@link GridUriDeploymentClassLoader#loadClassIsolated(String)} instead.
*/
@Deprecated
public synchronized Class<?> loadClassGarOnly(String name) throws ClassNotFoundException {
return loadClassIsolated(name);
}
/** {@inheritDoc} */
@Override public URL getResource(String name) {
URL url = findResource(name);
if (url == null)
url = ClassLoader.getSystemResource(name);
if (url == null)
url = super.getResource(name);
return url;
}
/** {@inheritDoc} */
@Override public InputStream getResourceAsStream(String name) {
// Find resource in a deployment unit first.
InputStream in = getResourceAsStreamIsolated(name);
// Find resource in parent class loader.
if (in == null)
in = ClassLoader.getSystemResourceAsStream(name);
if (in == null)
in = super.getResourceAsStream(name);
return in;
}
/**
* Returns an input stream for reading the specified resource from a deployment unit only.
*
* @param name Resource name.
* @return An input stream for reading the resource, or {@code null}
* if the resource could not be found.
*/
@Nullable public InputStream getResourceAsStreamIsolated(String name) {
URL url = findResource(name);
try {
return url != null ? url.openStream() : null;
}
catch (IOException ignored) {
return null;
}
}
/**
* Returns an input stream for reading the specified resource from GAR file only.
*
* @param name Resource name.
* @return An input stream for reading the resource, or {@code null}
* if the resource could not be found.
*
* @deprecated Use {@link GridUriDeploymentClassLoader#getResourceAsStreamIsolated(String)} instead.
*/
@Deprecated
@Nullable public InputStream getResourceAsStreamGarOnly(String name) {
return getResourceAsStreamIsolated(name);
}
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(GridUriDeploymentClassLoader.class, this, "urls", Arrays.toString(getURLs()));
}
}