Skip to content

Commit

Permalink
Issue #23892 Fixed rules for overriding resources by deployed applica…
Browse files Browse the repository at this point in the history
…tions
  • Loading branch information
dmatej committed May 22, 2022
1 parent bd6a439 commit ecfa738
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 115 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Contributors to Eclipse Foundation.
* Copyright (c) 2021, 2022 Contributors to Eclipse Foundation.
* Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022 Contributors to the Eclipse Foundation
*
Expand All @@ -18,6 +18,8 @@

package org.glassfish.appclient.client.acc;

import com.sun.enterprise.loader.ResourceLocator;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
Expand All @@ -31,6 +33,7 @@
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.function.Consumer;

Expand All @@ -40,6 +43,7 @@
import static java.security.AccessController.doPrivileged;

/**
* Application client classloader
*
* @author tjquinn
*/
Expand Down Expand Up @@ -156,7 +160,7 @@ public ACCClassLoader run() {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if (!shouldTransform) {
return super.findClass(name);
return findClassUnshadowed(name);
}

return copyClass(shadow().findClassUnshadowed(name));
Expand Down Expand Up @@ -227,4 +231,17 @@ public void processDeclaredPermissions() throws IOException {
}
}

@Override
public Enumeration<URL> getResources(String name) throws IOException {
final ResourceLocator locator = new ResourceLocator(this, getParentClassLoader(), true);
return locator.getResources(name);
}

private ClassLoader getParentClassLoader() {
final ClassLoader parent = getParent();
if (parent == null) {
return getSystemClassLoader();
}
return parent;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2022 Contributors to the Eclipse Foundation
* Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
* Copyright 2004 The Apache Software Foundation
* Copyright (c) 2022 Contributors to the Eclipse Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,6 +20,7 @@

import com.sun.appserv.BytecodePreprocessor;
import com.sun.appserv.server.util.PreprocessorUtil;
import com.sun.enterprise.loader.ResourceLocator;
import com.sun.enterprise.util.io.FileUtils;
import org.apache.naming.JndiPermission;
import org.apache.naming.resources.DirContextURLStreamHandler;
Expand Down Expand Up @@ -1215,9 +1216,10 @@ public URL getResource(String name) {
* (1) Delegate to parent if requested, or if the requested resource
* belongs to one of the packages that are part of the Java EE platform
*/
if (isResourceDelegate(name)) {
if (logger.isLoggable(Level.FINER))
if (isDelegateFirstResource(name)) {
if (logger.isLoggable(Level.FINER)) {
logger.log(Level.FINER, " Delegating to parent classloader " + parent);
}
ClassLoader loader = parent;
if (loader == null)
loader = system;
Expand Down Expand Up @@ -1303,9 +1305,10 @@ public InputStream getResourceAsStream(String name) {
* (1) Delegate to parent if requested, or if the requested resource
* belongs to one of the packages that are part of the Java EE platform
*/
if (isResourceDelegate(name)) {
if (logger.isLoggable(Level.FINER))
if (isDelegateFirstResource(name)) {
if (logger.isLoggable(Level.FINER)) {
logger.log(Level.FINER, " Delegating to parent classloader " + parent);
}
ClassLoader loader = parent;
if (loader == null)
loader = system;
Expand Down Expand Up @@ -1361,56 +1364,11 @@ public InputStream getResourceAsStream(String name) {
}


/**
* Finds all the resources with the given name.
*/
@Override
public Enumeration<URL> getResources(String name) throws IOException {

final Enumeration[] enums = new Enumeration[2];

Enumeration<URL> localResources = findResources(name);
Enumeration<URL> parentResources = null;
if (parent != null) {
parentResources = parent.getResources(name);
} else {
parentResources = system.getResources(name);
}

if (delegate) {
enums[0] = parentResources;
enums[1] = localResources;
} else {
enums[0] = localResources;
enums[1] = parentResources;
}

return new Enumeration<URL>() {

int index = 0;

private boolean next() {
while (index < enums.length) {
if (enums[index] != null &&
enums[index].hasMoreElements()) {
return true;
}
index++;
}
return false;
}

public boolean hasMoreElements() {
return next();
}

public URL nextElement() {
if (!next()) {
throw new NoSuchElementException();
}
return (URL)enums[index].nextElement();
}
};
final ClassLoader parentClassLoader = parent == null ? system : parent;
final ResourceLocator locator = new ResourceLocator(this, parentClassLoader, delegate);
return locator.getResources(name);
}


Expand Down Expand Up @@ -1456,14 +1414,11 @@ public Class<?> loadClass(String name) throws ClassNotFoundException {
* @exception ClassNotFoundException if the class was not found
*/
@Override
protected synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {

if (logger.isLoggable(Level.FINER)) {
logger.log(Level.FINER, "loadClass(" + name + ")");
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name == null) {
return null;
}

Class<?> clazz = null;
logger.log(Level.FINER, "loadClass({0})", name);

// Don't load classes if class loader is stopped
if (!started) {
Expand All @@ -1472,7 +1427,7 @@ protected synchronized Class<?> loadClass(String name, boolean resolve)
}

// (0) Check our previously loaded local class cache
clazz = findLoadedClass0(name);
Class<?> clazz = findLoadedClass0(name);
if (clazz != null) {
if (logger.isLoggable(Level.FINER)) {
logger.log(Level.FINER, " Returning class from cache");
Expand Down Expand Up @@ -1514,7 +1469,7 @@ protected synchronized Class<?> loadClass(String name, boolean resolve)
delegateLoader = system;
}

boolean delegateLoad = delegate || filter(name);
boolean delegateLoad = isDelegateFirstClass(name);

// (1) Delegate to our parent if requested
if (delegateLoad) {
Expand Down Expand Up @@ -3027,48 +2982,6 @@ protected void refreshPolicy() {
}


/**
* Filter classes.
*
* @param name class name
* @return true if the class should be filtered
*/
protected boolean filter(String name) {

if (name == null)
return false;

// START PE 4985680
// Special case for performance reason.
if (name.startsWith("java."))
return true;
// END PE 4985680

// Looking up the package
String packageName = null;
int pos = name.lastIndexOf('.');
if (pos != -1)
packageName = name.substring(0, pos);
else
return false;

if (overridablePackages != null){
for (String overridePkg : overridablePackages) {
if (packageName.startsWith(overridePkg))
return false;
}
}

for (int i = 0; i < packageTriggers.length; i++) {
if (packageName.startsWith(packageTriggers[i]))
return true;
}

return false;

}


/**
* Validate a classname. As per SRV.9.7.2, we must restrict loading of
* classes from J2SE (java.*) and classes of the servlet API
Expand Down Expand Up @@ -3316,21 +3229,58 @@ public Void run() {

}

/**
* @return true if the class should be first located by the delegating classloader.
*/
private boolean isDelegateFirstClass(String className) {
if (delegate) {
return true;
}
// Special case for performance reason.
if (className.startsWith("java.")) {
return true;
}
// Looking up the package
int pos = className.lastIndexOf('.');
if (pos == -1) {
return false;
}
String packageName = className.substring(0, pos);
if (overridablePackages != null){
for (String overridePkg : overridablePackages) {
if (packageName.startsWith(overridePkg)) {
return false;
}
}
}
for (String packageTrigger : packageTriggers) {
if (packageName.startsWith(packageTrigger)) {
return true;
}
}
return false;
}

/**
* To determine whether one should delegate to parent for loading
* resource of the given resource name.
*
* @param name
*/
private boolean isResourceDelegate(String name) {
return (delegate
|| (name.startsWith("javax") &&
(!name.startsWith("jakarta.faces") || !useMyFaces))
|| name.startsWith("sun")
|| (name.startsWith("com/sun/faces") &&
!name.startsWith("com/sun/faces/extensions") &&
!useMyFaces)
|| name.startsWith("org/apache/taglibs/standard"));
private boolean isDelegateFirstResource(String name) {
if (delegate) {
return true;
}
if (name.startsWith("javax") || name.startsWith("jakarta")) {
return !useMyFaces && !name.startsWith("jakarta/faces");
}
if (name.startsWith("com/sun/faces")) {
return !useMyFaces && !name.startsWith("com/sun/faces/extensions");
}
if (name.startsWith("org/apache/taglibs/standard")) {
return true;
}
return name.startsWith("sun");
}

private static String getString(String key, Object ... arguments) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2022 Contributors to the Eclipse Foundation
* Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -907,6 +908,20 @@ public InputStream getResourceAsStream(final String name) {
return stream;
}

@Override
public Enumeration<URL> getResources(String name) throws IOException {
final ResourceLocator locator = new ResourceLocator(this, getParentClassLoader(), true);
return locator.getResources(name);
}

private ClassLoader getParentClassLoader() {
final ClassLoader parent = getParent();
if (parent == null) {
return getSystemClassLoader();
}
return parent;
}

/**
* The JarFile objects loaded in the classloader may get exposed to the
* application code (e.g. EJBs) through calls of
Expand Down

0 comments on commit ecfa738

Please sign in to comment.