Skip to content

Commit

Permalink
Adjust class file handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
raphw committed Sep 26, 2024
1 parent 0bc0178 commit 1e38dd0
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 47 deletions.
102 changes: 57 additions & 45 deletions byte-buddy-dep/src/main/java/net/bytebuddy/build/Plugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -3399,12 +3399,12 @@ interface Sink extends Closeable {
/**
* Stores the supplied binary representation of types in this sink.
*
* @param version The version of the multi-release jar file, which should at least be {@code 8} as previous
* @param classFileVersion The version of the multi-release jar file, which should at least be {@code 8} as previous
* versions are not recognized by regular class loaders.
* @param binaryRepresentations The binary representations to store.
* @throws IOException If an I/O error occurs.
*/
void store(int version, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException;
void store(ClassFileVersion classFileVersion, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException;

/**
* Retains the supplied element in its original form.
Expand Down Expand Up @@ -3447,9 +3447,13 @@ public void store(Map<TypeDescription, byte[]> binaryRepresentations) throws IOE
/**
* {@inheritDoc}
*/
public void store(int version, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
public void store(ClassFileVersion classFileVersion, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
for (Map.Entry<TypeDescription, byte[]> entry : binaryRepresentations.entrySet()) {
outputStream.putNextEntry(new JarEntry(ClassFileLocator.META_INF_VERSIONS + version + "/" + entry.getKey().getInternalName() + ClassFileLocator.CLASS_FILE_EXTENSION));
outputStream.putNextEntry(new JarEntry(ClassFileLocator.META_INF_VERSIONS
+ classFileVersion.getJavaVersion()
+ "/"
+ entry.getKey().getInternalName()
+ ClassFileLocator.CLASS_FILE_EXTENSION));
outputStream.write(entry.getValue());
outputStream.closeEntry();
}
Expand Down Expand Up @@ -3512,7 +3516,7 @@ public void store(Map<TypeDescription, byte[]> binaryRepresentations) {
/**
* {@inheritDoc}
*/
public void store(int version, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
public void store(ClassFileVersion classFileVersion, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
/* do nothing */
}

Expand Down Expand Up @@ -3585,9 +3589,13 @@ public void store(Map<TypeDescription, byte[]> binaryRepresentations) {
/**
* {@inheritDoc}
*/
public void store(int version, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
public void store(ClassFileVersion classFileVersion, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
for (Map.Entry<TypeDescription, byte[]> entry : binaryRepresentations.entrySet()) {
storage.put(ClassFileLocator.META_INF_VERSIONS + version + "/" + entry.getKey().getInternalName() + ClassFileLocator.CLASS_FILE_EXTENSION, entry.getValue());
storage.put(ClassFileLocator.META_INF_VERSIONS
+ classFileVersion.getJavaVersion()
+ "/"
+ entry.getKey().getInternalName()
+ ClassFileLocator.CLASS_FILE_EXTENSION, entry.getValue());
}
}

Expand Down Expand Up @@ -3761,8 +3769,8 @@ public void store(Map<TypeDescription, byte[]> binaryRepresentations) throws IOE
/**
* {@inheritDoc}
*/
public void store(int version, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
doStore(new File(folder, ClassFileLocator.META_INF_VERSIONS + version), binaryRepresentations);
public void store(ClassFileVersion classFileVersion, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
doStore(new File(folder, ClassFileLocator.META_INF_VERSIONS + classFileVersion.getJavaVersion()), binaryRepresentations);
}

/**
Expand Down Expand Up @@ -3877,7 +3885,7 @@ interface Materializable {
void materialize(Target.Sink sink,
List<TypeDescription> transformed,
Map<TypeDescription,
List<Throwable>> failed,
List<Throwable>> failed,
List<String> unresolved) throws IOException;

/**
Expand All @@ -3886,9 +3894,10 @@ void materialize(Target.Sink sink,
class ForTransformedElement implements Materializable {

/**
* The multi-release Java version number or {@code 0}.
* The multi-release class file version number or {@code null} if a regular class.
*/
private final int version;
@MaybeNull
private final ClassFileVersion classFileVersion;

/**
* The type that has been transformed.
Expand All @@ -3898,11 +3907,11 @@ class ForTransformedElement implements Materializable {
/**
* Creates a new materializable for a successfully transformed type.
*
* @param version The multi-release Java version number or {@code 0}.
* @param dynamicType The type that has been transformed.
* @param classFileVersion The multi-release class file version number or {@code null} if a regular class.
* @param dynamicType The type that has been transformed.
*/
protected ForTransformedElement(int version, DynamicType dynamicType) {
this.version = version;
protected ForTransformedElement(@MaybeNull ClassFileVersion classFileVersion, DynamicType dynamicType) {
this.classFileVersion = classFileVersion;
this.dynamicType = dynamicType;
}

Expand All @@ -3912,12 +3921,12 @@ protected ForTransformedElement(int version, DynamicType dynamicType) {
public void materialize(Target.Sink sink,
List<TypeDescription> transformed,
Map<TypeDescription,
List<Throwable>> failed,
List<Throwable>> failed,
List<String> unresolved) throws IOException {
if (version == 0) {
if (classFileVersion == null) {
sink.store(dynamicType.getAllTypes());
} else {
sink.store(version, dynamicType.getAllTypes());
sink.store(classFileVersion, dynamicType.getAllTypes());
}
transformed.add(dynamicType.getTypeDescription());
}
Expand Down Expand Up @@ -3948,7 +3957,7 @@ protected ForRetainedElement(Source.Element element) {
public void materialize(Target.Sink sink,
List<TypeDescription> transformed,
Map<TypeDescription,
List<Throwable>> failed,
List<Throwable>> failed,
List<String> unresolved) throws IOException {
sink.retain(element);
}
Expand Down Expand Up @@ -3993,7 +4002,7 @@ protected ForFailedElement(Source.Element element, TypeDescription typeDescripti
public void materialize(Target.Sink sink,
List<TypeDescription> transformed,
Map<TypeDescription,
List<Throwable>> failed,
List<Throwable>> failed,
List<String> unresolved) throws IOException {
sink.retain(element);
failed.put(typeDescription, errored);
Expand Down Expand Up @@ -4032,7 +4041,7 @@ protected ForUnresolvedElement(Source.Element element, String typeName) {
public void materialize(Target.Sink sink,
List<TypeDescription> transformed,
Map<TypeDescription,
List<Throwable>> failed,
List<Throwable>> failed,
List<String> unresolved) throws IOException {
sink.retain(element);
unresolved.add(typeName);
Expand Down Expand Up @@ -4951,20 +4960,20 @@ public Summary apply(Source source, Target target, List<? extends Plugin.Factory
&& !name.endsWith(PACKAGE_INFO)
&& !name.endsWith(MODULE_INFO)) {
try {
int version = name.startsWith(ClassFileLocator.META_INF_VERSIONS)
? Math.max(7, Integer.parseInt(name.substring(ClassFileLocator.META_INF_VERSIONS.length(), name.indexOf('/', ClassFileLocator.META_INF_VERSIONS.length()))))
: 0;
if (version == 0 || version > 7
&& classFileVersion != null
&& classFileVersion.isAtLeast(ClassFileVersion.JAVA_V9)
&& version <= classFileVersion.getJavaVersion()) {
ClassFileVersion classFileVersion = name.startsWith(ClassFileLocator.META_INF_VERSIONS)
? ClassFileVersion.ofJavaVersion(Integer.parseInt(name.substring(ClassFileLocator.META_INF_VERSIONS.length(), name.indexOf('/', ClassFileLocator.META_INF_VERSIONS.length()))))
: null;
if (classFileVersion == null || classFileVersion.isAtLeast(ClassFileVersion.JAVA_V8)
&& this.classFileVersion != null
&& this.classFileVersion.isAtLeast(ClassFileVersion.JAVA_V9)
&& classFileVersion.isAtMost(this.classFileVersion)) {
String typeName = name.substring(name.startsWith(ClassFileLocator.META_INF_VERSIONS)
? name.indexOf('/', ClassFileLocator.META_INF_VERSIONS.length()) + 1
: 0, name.length() - ClassFileLocator.CLASS_FILE_EXTENSION.length()).replace('/', '.');
dispatcher.accept(new Preprocessor(element,
typeName,
version,
new SourceEntryPrependingClassFileLocator(typeName, element, classFileLocator),
classFileVersion,
typePool,
listener,
plugins,
Expand Down Expand Up @@ -5096,14 +5105,16 @@ private class Preprocessor implements Callable<Callable<? extends Dispatcher.Mat
private final String typeName;

/**
* The multi-release Java version number or {@code 0}.
* The class file locator to use.
*/
private final int version;
private final ClassFileLocator classFileLocator;

/**
* The class file locator to use.
* The multi-release class file version or {@code null} for a regular class.
*/
private final ClassFileLocator classFileLocator;
@MaybeNull
@HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
private final ClassFileVersion classFileVersion;

/**
* The type pool to use.
Expand All @@ -5130,25 +5141,25 @@ private class Preprocessor implements Callable<Callable<? extends Dispatcher.Mat
*
* @param element The processed element.
* @param typeName The name of the processed type.
* @param version The multi-release Java version number or {@code 0}.
* @param classFileLocator The class file locator to use.
* @param classFileVersion The multi-release class file version or {@code null} for a regular class.
* @param typePool The type pool to use.
* @param listener The listener to notify.
* @param plugins The plugins to apply.
* @param preprocessors The plugins with preprocessors to preprocess.
*/
private Preprocessor(Source.Element element,
String typeName,
int version,
ClassFileLocator classFileLocator,
@MaybeNull ClassFileVersion classFileVersion,
TypePool typePool,
Listener listener,
List<Plugin> plugins,
List<WithPreprocessor> preprocessors) {
this.element = element;
this.typeName = typeName;
this.version = version;
this.classFileLocator = classFileLocator;
this.classFileVersion = classFileVersion;
this.typePool = typePool;
this.listener = listener;
this.plugins = plugins;
Expand All @@ -5168,7 +5179,7 @@ public Callable<Dispatcher.Materializable> call() throws Exception {
for (WithPreprocessor preprocessor : preprocessors) {
preprocessor.onPreprocess(typeDescription, classFileLocator);
}
return new Resolved(version, typeDescription);
return new Resolved(classFileVersion, typeDescription);
} else {
return new Ignored(typeDescription);
}
Expand All @@ -5193,9 +5204,10 @@ public Callable<Dispatcher.Materializable> call() throws Exception {
private class Resolved implements Callable<Dispatcher.Materializable> {

/**
* The multi-release Java version number or {@code 0}.
* The multi-release Java version number or {@code null} if a regular class.
*/
private final int version;
@MaybeNull
private final ClassFileVersion classFileVersion;

/**
* A description of the resolved type.
Expand All @@ -5205,11 +5217,11 @@ private class Resolved implements Callable<Dispatcher.Materializable> {
/**
* Creates a new resolved materializable.
*
* @param version The multi-release Java version number or {@code 0}.
* @param typeDescription A description of the resolved type.
* @param classFileVersion The multi-release Java version number or {@code null} if a regular class.
* @param typeDescription A description of the resolved type.
*/
private Resolved(int version, TypeDescription typeDescription) {
this.version = version;
private Resolved(@MaybeNull ClassFileVersion classFileVersion, TypeDescription typeDescription) {
this.classFileVersion = classFileVersion;
this.typeDescription = typeDescription;
}

Expand Down Expand Up @@ -5248,7 +5260,7 @@ public Dispatcher.Materializable call() {
listener.onLiveInitializer(typeDescription, entry.getKey());
}
}
return new Dispatcher.Materializable.ForTransformedElement(version, dynamicType);
return new Dispatcher.Materializable.ForTransformedElement(classFileVersion, dynamicType);
} catch (Throwable throwable) {
errored.add(throwable);
listener.onError(typeDescription, errored);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ public void testMultiVersion() throws Exception {
Plugin.Engine.Target.InMemory target = new Plugin.Engine.Target.InMemory();
Plugin.Engine.Target.Sink sink = target.write(Plugin.Engine.Source.Origin.NO_MANIFEST);
sink.store(Collections.singletonMap(TypeDescription.ForLoadedType.of(Object.class), new byte[]{1, 2, 3}));
sink.store(11, Collections.singletonMap(TypeDescription.ForLoadedType.of(Object.class), new byte[]{4, 5, 6}));
sink.store(17, Collections.singletonMap(TypeDescription.ForLoadedType.of(Object.class), new byte[]{7, 8, 9}));
sink.store(ClassFileVersion.JAVA_V11, Collections.singletonMap(TypeDescription.ForLoadedType.of(Object.class), new byte[]{4, 5, 6}));
sink.store(ClassFileVersion.JAVA_V17, Collections.singletonMap(TypeDescription.ForLoadedType.of(Object.class), new byte[]{7, 8, 9}));
sink.close();
assertThat(target.getStorage().size(), is(3));
assertThat(target.getStorage().get(TypeDescription.ForLoadedType.of(Object.class).getInternalName() + ClassFileLocator.CLASS_FILE_EXTENSION), is(new byte[]{1, 2, 3}));
Expand Down

0 comments on commit 1e38dd0

Please sign in to comment.