Define a Package in EE11 WebAppClassLoader (#12028)

Define a Package in EE11 WebAppClassLoader
This commit is contained in:
Greg Wilkins 2024-07-15 09:36:28 +10:00 committed by GitHub
parent f5d6d8d076
commit b0b204cb35
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 64 additions and 0 deletions

View File

@ -18,6 +18,7 @@ import java.io.InputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Path;
@ -32,12 +33,14 @@ import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.jar.Manifest;
import org.eclipse.jetty.util.ClassVisibilityChecker;
import org.eclipse.jetty.util.FileID;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceCollators;
import org.eclipse.jetty.util.resource.ResourceFactory;
@ -563,6 +566,8 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility
bytes = tmp;
}
definePackageIfNecessary(name, url);
return defineClass(name, bytes, 0, bytes.length);
}
catch (IOException | IllegalClassFormatException e)
@ -575,6 +580,41 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility
}
}
private void definePackageIfNecessary(String className, URL url) throws IOException
{
int lastDotIndex = className.lastIndexOf('.');
if (lastDotIndex < 0)
return;
String packageName = className.substring(0, lastDotIndex);
if (getDefinedPackage(packageName) == null)
{
try
{
String externalForm = url.toExternalForm();
if (externalForm.startsWith("jar:file:") && externalForm.contains("!/"))
{
URI jarURI = URIUtil.unwrapContainer(new URI(externalForm));
Resource manifestResource = getContext().newResource(URIUtil.uriJarPrefix(jarURI, "!/META-INF/MANIFEST.MF").toASCIIString());
if (manifestResource.exists())
{
try (InputStream is = manifestResource.newInputStream())
{
Manifest manifest = new Manifest(is);
definePackage(packageName, manifest, jarURI.toURL());
return;
}
}
}
}
catch (Throwable t)
{
LOG.trace("could not read manifest of {}", url, t);
}
definePackage(packageName, null, null, null, null, null, null, null);
}
}
@Override
public void close() throws IOException
{

View File

@ -139,6 +139,7 @@ public class WebAppClassLoaderTest
Class<?> clazzA = _loader.loadClass("org.acme.webapp.ClassInJarA");
assertThrows(NoSuchFieldException.class, () ->
clazzA.getField("FROM_PARENT"));
assertThat(clazzA.getPackage().getName(), is("org.acme.webapp"));
}
@Test
@ -190,6 +191,29 @@ public class WebAppClassLoaderTest
"org.acme.webapp.ClassInJarB",
_loader,
"org.acme.other.ClassInClassesC"));
Class<?> classInJarA = _loader.loadClass("org.acme.webapp.ClassInJarA");
Class<?> classInJarB = _loader.loadClass("org.acme.webapp.ClassInJarB");
Class<?> classInClassesC = _loader.loadClass("org.acme.other.ClassInClassesC");
assertThat(classInJarA.getPackage().getName(), is("org.acme.webapp"));
assertThat(classInJarB.getPackage().getName(), is("org.acme.webapp"));
assertThat(classInClassesC.getPackage().getName(), is("org.acme.other"));
assertThat(classInJarA.getPackage().getSpecificationTitle(), is("Test Package"));
assertThat(classInJarA.getPackage().getSpecificationVersion(), is("3.2.1"));
assertThat(classInJarA.getPackage().getImplementationTitle(), is("Testing 123"));
assertThat(classInJarA.getPackage().getImplementationVersion(), is("1.2.3"));
assertThat(classInJarB.getPackage().getSpecificationTitle(), is("Test Package"));
assertThat(classInJarB.getPackage().getSpecificationVersion(), is("3.2.1"));
assertThat(classInJarB.getPackage().getImplementationTitle(), is("Testing 123"));
assertThat(classInJarB.getPackage().getImplementationVersion(), is("1.2.3"));
assertThat(classInClassesC.getPackage().getSpecificationTitle(), nullValue());
assertThat(classInClassesC.getPackage().getSpecificationVersion(), nullValue());
assertThat(classInClassesC.getPackage().getImplementationTitle(), nullValue());
assertThat(classInClassesC.getPackage().getImplementationVersion(), nullValue());
}
@Test