diff options
author | Andreas Beeker <kiwiwings@apache.org> | 2020-12-28 00:47:23 +0000 |
---|---|---|
committer | Andreas Beeker <kiwiwings@apache.org> | 2020-12-28 00:47:23 +0000 |
commit | 07ba96f02340d4674714bf445f4c23bd5664524d (patch) | |
tree | ff29cfade6fa494b171fc92b8d620f39c9aabc7b | |
parent | b0830f9d941d6d1235fbe3a4194dfe8c0fb1ab26 (diff) | |
download | poi-07ba96f02340d4674714bf445f4c23bd5664524d.tar.gz poi-07ba96f02340d4674714bf445f4c23bd5664524d.zip |
gather necessary .xsb for ooxml-lite jar via intercepting the calls to SchemaTypeSystemImpl.XsbReader
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1884850 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | build.xml | 60 | ||||
-rw-r--r-- | src/multimodule/ooxml-lite-agent/java9/module-info.class | bin | 188 -> 219 bytes | |||
-rw-r--r-- | src/multimodule/ooxml-lite-agent/java9/module-info.java | 1 | ||||
-rw-r--r-- | src/ooxml/testcases/org/apache/poi/ooxml/lite/OOXMLLiteAgent.java | 112 |
4 files changed, 99 insertions, 74 deletions
@@ -157,7 +157,7 @@ under the License. <property name="ooxml.testokfile" location="build/ooxml-testokfile.txt"/> <property name="ooxml.lite.agent" location="lib/ooxml-tests/ooxml-lite-agent.jar"/> - <property name="ooxml.lite.report" location="build/ooxml-lite-report.txt"/> + <property name="ooxml.lite.report" location="build/ooxml-lite-report"/> <property name="ooxml.lite.jar" location="build/dist/maven/poi-ooxml-lite/poi-ooxml-lite-${version.id}.jar"/> <property name="ooxml.lite.includes" value="^(com/microsoft/schemas|org/(etsi|openxmlformats|w3/)|org/apache/poi/schemas)"/> @@ -1157,6 +1157,7 @@ under the License. destdir="${basedir}/src/multimodule/ooxml-lite-agent/java9" includeantruntime="false" fork="true" + modulepath="${basedir}/lib/main-tests" unless:true="${isJava8}"> <compilerarg line="--patch-module org.apache.poi.ooxml_lite=${ooxml.output.test.dir}"/> </javac> @@ -1168,6 +1169,7 @@ under the License. <attribute name="Multi-Release" value="true"/> <attribute name="Automatic-Module-Name" value="org.apache.poi.ooxml_lite"/> <attribute name="Premain-Class" value="org.apache.poi.ooxml.lite.OOXMLLiteAgent"/> + <!-- attribute name="Can-Retransform-Classes" value="true"/ --> </manifest> </jar> </target> @@ -1711,7 +1713,7 @@ under the License. <echo message="Create ooxml-lite schemas"/> <local name="lite.exports"/> <loadresource property="lite.exports"> - <file file="${ooxml.lite.report}"/> + <file file="${ooxml.lite.report}.clazz"/> <filterchain> <tokenfilter> <replaceregex pattern="[/\\][^/\\]+$" replace=""/> @@ -1750,7 +1752,7 @@ under the License. </modulepath> </javac> - <copy file="${ooxml.lite.report}" tofile="build/ooxml-lite-classes.txt" overwrite="true"> + <copy file="${ooxml.lite.report}.clazz" tofile="${ooxml.lite.report}.clazz2" overwrite="true"> <filterchain> <tokenfilter> <replaceregex pattern="(.*)" replace="\1.class${line.separator}\1$*.class "/> @@ -1758,62 +1760,22 @@ under the License. </filterchain> </copy> - <local name="ooxml.lite.xsbs"/> - <loadresource property="ooxml.lite.xsbs"> - <file file="${ooxml.lite.report}"/> + <copy file="${ooxml.lite.report}.xsb" tofile="${ooxml.lite.report}.xsb2" overwrite="true"> <filterchain> - <linecontains negate="true" matchany="true"> - <contains value="$"/> - <contains value="TypeSystemHolder"/> - </linecontains> - <suffixlines suffix=".java"/> + <prefixlines prefix="org/apache/poi/schemas/ooxml/system/ooxml/"/> + <suffixlines suffix=".xsb"/> </filterchain> - </loadresource> - - <concat dest="build/ooxml-lite-classes.txt" append="true"> - <filelist dir="build/xmlbean-sources" files="${ooxml.lite.xsbs}"/> - <filterchain> - <linecontains> - <contains value="resolveHandle"/> - </linecontains> - <replaceregex pattern='.*"([^"]+)".*' replace="org/apache/poi/schemas/ooxml/system/ooxml/\1.xsb"/> - </filterchain> - </concat> - - <!-- the following xsb files aren't detected, i.e. not directly loaded by XmlBeans interface classes --> - <echo file="build/ooxml-lite-classes.txt" append="true"> -org/apache/poi/schemas/ooxml/system/ooxml/index.xsb -org/apache/poi/schemas/ooxml/system/ooxml/picelement.xsb -org/apache/poi/schemas/ooxml/system/ooxml/groupelement.xsb -org/apache/poi/schemas/ooxml/system/ooxml/group7d3fdoctype.xsb -org/apache/poi/schemas/ooxml/system/ooxml/shapelayoutelement.xsb -org/apache/poi/schemas/ooxml/system/ooxml/shapetypeelement.xsb -org/apache/poi/schemas/ooxml/system/ooxml/shapetypeb89bdoctype.xsb -org/apache/poi/schemas/ooxml/system/ooxml/shapeelement.xsb -org/apache/poi/schemas/ooxml/system/ooxml/shapeaee1doctype.xsb -org/apache/poi/schemas/ooxml/system/ooxml/tblelement.xsb -org/apache/poi/schemas/ooxml/system/ooxml/tbleb1bdoctype.xsb -org/apache/poi/schemas/ooxml/system/ooxml/relationshipreferenceelement.xsb -org/apache/poi/schemas/ooxml/system/ooxml/qualifyingpropertieselement.xsb -org/apache/poi/schemas/ooxml/system/ooxml/oleobjelement.xsb -org/apache/poi/schemas/ooxml/system/ooxml/oleobj8482doctype.xsb -org/apache/poi/schemas/ooxml/system/ooxml/stcellspans60f6type.xsb -org/apache/poi/schemas/ooxml/system/ooxml/stcellspanf3a5type.xsb -org/apache/poi/schemas/ooxml/system/ooxml/alternatecontentelement.xsb -org/apache/poi/schemas/ooxml/system/ooxml/chartelement.xsb -org/apache/poi/schemas/ooxml/system/ooxml/chartf85cdoctype.xsb -org/apache/poi/schemas/ooxml/system/ooxml/rectelement.xsb -org/apache/poi/schemas/ooxml/system/ooxml/rectaf36doctype.xsb - </echo> + </copy> <mkdir dir="build/dist/maven/poi-ooxml-lite"/> <jar destfile="${ooxml.lite.jar}" duplicate="preserve"> <zipfileset dir="${basedir}/src/multimodule/ooxml-lite/java9" prefix="META-INF/versions/9" excludes="*.java"/> <zipfileset src="${ooxml.xsds.jar}"> - <patternset includesfile="build/ooxml-lite-classes.txt"> + <patternset includesfile="${ooxml.lite.report}.clazz2"> <include name="org/apache/poi/schemas/ooxml/element/**/*.xsb"/> </patternset> + <patternset includesfile="${ooxml.lite.report}.xsb2"/> </zipfileset> <zipfileset dir="src/multimodule/ooxml-full/java9" prefix="META-INF/versions/9" excludes="*.java"/> <manifest> diff --git a/src/multimodule/ooxml-lite-agent/java9/module-info.class b/src/multimodule/ooxml-lite-agent/java9/module-info.class Binary files differindex 45ff2cad38..51e4e32994 100644 --- a/src/multimodule/ooxml-lite-agent/java9/module-info.class +++ b/src/multimodule/ooxml-lite-agent/java9/module-info.class diff --git a/src/multimodule/ooxml-lite-agent/java9/module-info.java b/src/multimodule/ooxml-lite-agent/java9/module-info.java index 04058f1cfc..85184ca2b2 100644 --- a/src/multimodule/ooxml-lite-agent/java9/module-info.java +++ b/src/multimodule/ooxml-lite-agent/java9/module-info.java @@ -17,6 +17,7 @@ module org.apache.poi.ooxml_lite { requires java.instrument; + requires static net.bytebuddy.agent; exports org.apache.poi.ooxml.lite; }
\ No newline at end of file diff --git a/src/ooxml/testcases/org/apache/poi/ooxml/lite/OOXMLLiteAgent.java b/src/ooxml/testcases/org/apache/poi/ooxml/lite/OOXMLLiteAgent.java index 21c7f28786..b95e9df7e9 100644 --- a/src/ooxml/testcases/org/apache/poi/ooxml/lite/OOXMLLiteAgent.java +++ b/src/ooxml/testcases/org/apache/poi/ooxml/lite/OOXMLLiteAgent.java @@ -17,6 +17,8 @@ package org.apache.poi.ooxml.lite; +import static net.bytebuddy.matcher.ElementMatchers.named; + import java.io.IOException; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.Instrumentation; @@ -31,48 +33,108 @@ import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Stream; +import net.bytebuddy.agent.builder.AgentBuilder; +import net.bytebuddy.implementation.MethodDelegation; +import net.bytebuddy.implementation.SuperMethodCall; +import net.bytebuddy.matcher.ElementMatchers; +import org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl; + /** * OOXMLLiteAgent is the replacement for the former OOXMLLite, because in Java 12 * it isn't possible to access the privates :) of the ClassLoader */ public class OOXMLLiteAgent { - static class LoggingTransformer implements ClassFileTransformer { - final Path path; - final Pattern includes; - final Set<Integer> fileHashes = new HashSet<>(); + public static void premain(String agentArgs, Instrumentation inst) throws IOException { + String[] args = (agentArgs == null ? "" : agentArgs).split("\\|", 2); + String logBase = args.length >= 1 ? args[0] : "ooxml-lite-report"; - public LoggingTransformer(String agentArgs) { - String[] args = (agentArgs == null ? "" : agentArgs).split("\\|", 2); - path = Paths.get(args.length >= 1 ? args[0] : "ooxml-lite.out"); - includes = Pattern.compile(args.length >= 2 ? args[1] : ".*/schemas/.*"); + XsbLogger.load(logBase+".xsb"); - try { - if (Files.exists(path)) { - try (Stream<String> stream = Files.lines(path)) { - stream.forEach((s) -> fileHashes.add(s.hashCode())); - } - } else { - Files.createFile(path); + ClazzLogger log = new ClazzLogger(); + log.load(logBase+".clazz"); + log.setPattern(args.length >= 2 ? args[1] : ".*/schemas/.*"); + inst.addTransformer(log); + + new AgentBuilder.Default() + // .with(AgentBuilder.Listener.StreamWriting.toSystemOut()) + .type(named("org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl$XsbReader")) + .transform((builder, type, cl, m) -> + builder + .constructor(ElementMatchers.any()) + .intercept(MethodDelegation.to(XsbLogger.class).andThen(SuperMethodCall.INSTANCE)) + ) + .installOn(inst); + } + + /** + * This logger intercepts the loading of XmlBeans .xsb + * + * when ran in the ant junitlauncher, it's not possible to have the interceptor methods as + * instance method of ClazzLogger. the junit test will fail ... though it works ok in IntelliJ + * probably because of classpath vs. modulepath instantiation + */ + public static class XsbLogger { + private static Path logPath; + private static final Set<Integer> hashes = new HashSet<>(); + + static void load(String path) throws IOException { + logPath = Paths.get(path); + if (Files.exists(logPath)) { + try (Stream<String> stream = Files.lines(logPath)) { + stream.forEach((s) -> hashes.add(s.hashCode())); } - } catch (IOException ignored) { } } - public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain domain, byte[] bytes) { - if (path != null && className != null && !fileHashes.contains(className.hashCode()) && includes.matcher(className).find()) { - try { - // TODO: check if this is atomic ... as transform() is probably called synchronized, it doesn't matter anyway - Files.write(path, (className+"\n").getBytes(StandardCharsets.ISO_8859_1), StandardOpenOption.APPEND); - fileHashes.add(className.hashCode()); - } catch (IOException ignroed) { + // SchemaTypeSystemImpl.XsbReader::new is delegated to here - method name doesn't matter + public static void loadXsb(SchemaTypeSystemImpl parent, String handle) { + write(logPath, handle, hashes); + } + + public static void loadXsb(SchemaTypeSystemImpl parent, String handle, int filetype) { + loadXsb(parent, handle); + } + } + + /** + * This logger is used to log the used XmlBeans classes + */ + public static class ClazzLogger implements ClassFileTransformer { + Path logPath; + Pattern includes; + final Set<Integer> hashes = new HashSet<>(); + + public void setPattern(String regex) { + includes = Pattern.compile(regex); + } + + public void load(String path) throws IOException { + this.logPath = Paths.get(path); + if (Files.exists(this.logPath)) { + try (Stream<String> stream = Files.lines(this.logPath)) { + stream.forEach((s) -> hashes.add(s.hashCode())); } } + } + + public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain domain, byte[] bytes) { + if (logPath != null && className != null && includes.matcher(className).find()) { + write(logPath, className, hashes); + } return bytes; } } - public static void premain(String agentArgs, Instrumentation inst) { - inst.addTransformer(new LoggingTransformer(agentArgs)); + + static void write(Path path, String item, Set<Integer> hashes) { + if (!hashes.contains(item.hashCode())) { + try { + // TODO: check if this is atomic ... as transform() is probably called synchronized, it doesn't matter anyway + Files.write(path, (item+"\n").getBytes(StandardCharsets.ISO_8859_1), StandardOpenOption.CREATE, StandardOpenOption.APPEND); + hashes.add(item.hashCode()); + } catch (IOException ignroed) { + } + } } } |