|
28 | 28 | import net.bytebuddy.pool.TypePool;
|
29 | 29 | import net.bytebuddy.utility.CompoundList;
|
30 | 30 | import net.bytebuddy.utility.FileSystem;
|
| 31 | +import net.bytebuddy.utility.StreamDrainer; |
31 | 32 | import net.bytebuddy.utility.nullability.AlwaysNull;
|
32 | 33 | import net.bytebuddy.utility.nullability.MaybeNull;
|
33 | 34 |
|
@@ -2959,7 +2960,7 @@ public static Source ofTypes(Collection<? extends Class<?>> types) {
|
2959 | 2960 | /**
|
2960 | 2961 | * Represents a collection of types as an in-memory source.
|
2961 | 2962 | *
|
2962 |
| - * @param types The types to represent. |
| 2963 | + * @param types The types to represent. |
2963 | 2964 | * @param versionedTypes A versioned mapping of types to represent.
|
2964 | 2965 | * @return A source representing the supplied types.
|
2965 | 2966 | */
|
@@ -4884,16 +4885,20 @@ public Summary apply(Source source, Target target, List<? extends Plugin.Factory
|
4884 | 4885 | while (name.startsWith("/")) {
|
4885 | 4886 | name = name.substring(1);
|
4886 | 4887 | }
|
4887 |
| - if (name.endsWith(ClassFileLocator.CLASS_FILE_EXTENSION) && !name.endsWith(PACKAGE_INFO) && !name.equals(MODULE_INFO)) { |
| 4888 | + if (name.endsWith(ClassFileLocator.CLASS_FILE_EXTENSION) |
| 4889 | + && (!name.startsWith("META-INF") && name.startsWith(ClassFileLocator.META_INF_VERSIONS)) |
| 4890 | + && !name.endsWith(PACKAGE_INFO) |
| 4891 | + && !name.endsWith(MODULE_INFO)) { |
4888 | 4892 | try {
|
| 4893 | + String typeName = name.substring(name.startsWith(ClassFileLocator.META_INF_VERSIONS) |
| 4894 | + ? name.indexOf('/', ClassFileLocator.META_INF_VERSIONS.length()) + 1 |
| 4895 | + : 0, name.length() - ClassFileLocator.CLASS_FILE_EXTENSION.length()).replace('/', '.'); |
4889 | 4896 | dispatcher.accept(new Preprocessor(element,
|
4890 |
| - name.substring(name.startsWith(ClassFileLocator.META_INF_VERSIONS) |
4891 |
| - ? name.indexOf('/', ClassFileLocator.META_INF_VERSIONS.length()) + 1 |
4892 |
| - : 0, name.length() - ClassFileLocator.CLASS_FILE_EXTENSION.length()).replace('/', '.'), |
| 4897 | + typeName, |
4893 | 4898 | name.startsWith(ClassFileLocator.META_INF_VERSIONS)
|
4894 | 4899 | ? Integer.parseInt(name.substring(ClassFileLocator.META_INF_VERSIONS.length(), name.indexOf('/', ClassFileLocator.META_INF_VERSIONS.length())))
|
4895 | 4900 | : 0,
|
4896 |
| - classFileLocator, |
| 4901 | + new SourceEntryPrependingClassFileLocator(typeName, element, classFileLocator), |
4897 | 4902 | typePool,
|
4898 | 4903 | listener,
|
4899 | 4904 | plugins,
|
@@ -4946,6 +4951,65 @@ public Summary apply(Source source, Target target, List<? extends Plugin.Factory
|
4946 | 4951 | }
|
4947 | 4952 | }
|
4948 | 4953 |
|
| 4954 | + /** |
| 4955 | + * A class file locator that shadows a given {@link Source.Element}'s type with the explicit element. |
| 4956 | + * This avoids that caching yields the wrong class file in case of multi-release jars. |
| 4957 | + */ |
| 4958 | + @HashCodeAndEqualsPlugin.Enhance |
| 4959 | + protected static class SourceEntryPrependingClassFileLocator implements ClassFileLocator { |
| 4960 | + |
| 4961 | + /** |
| 4962 | + * The name of the represented type. |
| 4963 | + */ |
| 4964 | + private final String name; |
| 4965 | + |
| 4966 | + /** |
| 4967 | + * The corresponding source element. |
| 4968 | + */ |
| 4969 | + private final Source.Element element; |
| 4970 | + |
| 4971 | + /** |
| 4972 | + * The actual class file locator to query for all other types. |
| 4973 | + */ |
| 4974 | + private final ClassFileLocator delegate; |
| 4975 | + |
| 4976 | + /** |
| 4977 | + * Creates a class file locator that prepends a {@link Source.Element}. |
| 4978 | + * |
| 4979 | + * @param name The name of the represented type. |
| 4980 | + * @param element The corresponding source element. |
| 4981 | + * @param delegate The actual class file locator to query for all other types. |
| 4982 | + */ |
| 4983 | + protected SourceEntryPrependingClassFileLocator(String name, Source.Element element, ClassFileLocator delegate) { |
| 4984 | + this.name = name; |
| 4985 | + this.element = element; |
| 4986 | + this.delegate = delegate; |
| 4987 | + } |
| 4988 | + |
| 4989 | + /** |
| 4990 | + * {@inheritDoc} |
| 4991 | + */ |
| 4992 | + public Resolution locate(String name) throws IOException { |
| 4993 | + if (name.endsWith(this.name)) { |
| 4994 | + InputStream inputStream = element.getInputStream(); |
| 4995 | + try { |
| 4996 | + return new Resolution.Explicit(StreamDrainer.DEFAULT.drain(inputStream)); |
| 4997 | + } finally { |
| 4998 | + inputStream.close(); |
| 4999 | + } |
| 5000 | + } else { |
| 5001 | + return delegate.locate(name); |
| 5002 | + } |
| 5003 | + } |
| 5004 | + |
| 5005 | + /** |
| 5006 | + * {@inheritDoc} |
| 5007 | + */ |
| 5008 | + public void close() throws IOException { |
| 5009 | + delegate.close(); |
| 5010 | + } |
| 5011 | + } |
| 5012 | + |
4949 | 5013 | /**
|
4950 | 5014 | * A preprocessor for a parallel plugin engine.
|
4951 | 5015 | */
|
|
0 commit comments