Path: blob/master/test/jdk/tools/jlink/plugins/StripJavaDebugAttributesPluginTest.java
41149 views
/*1* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @summary Test StripJavaDebugAttributesPlugin26* @author Jean-Francois Denise27* @library ../../lib28* @build tests.*29* @modules java.base/jdk.internal.jimage30* jdk.jlink/jdk.tools.jlink.internal31* jdk.jlink/jdk.tools.jlink.internal.plugins32* jdk.jlink/jdk.tools.jlink.plugin33* jdk.jlink/jdk.tools.jimage34* jdk.jlink/jdk.tools.jmod35* jdk.jdeps/com.sun.tools.classfile36* jdk.compiler37* @run main StripJavaDebugAttributesPluginTest38*/3940import java.io.ByteArrayInputStream;41import java.io.IOException;42import java.nio.file.Files;43import java.nio.file.Path;44import java.util.ArrayList;45import java.util.Arrays;46import java.util.HashMap;47import java.util.Iterator;48import java.util.List;49import java.util.stream.Stream;5051import com.sun.tools.classfile.Attribute;52import com.sun.tools.classfile.ClassFile;53import com.sun.tools.classfile.Code_attribute;54import com.sun.tools.classfile.ConstantPoolException;55import com.sun.tools.classfile.Method;5657import jdk.tools.jlink.internal.ResourcePoolManager;58import jdk.tools.jlink.internal.plugins.StripJavaDebugAttributesPlugin;59import jdk.tools.jlink.plugin.Plugin;60import jdk.tools.jlink.plugin.ResourcePool;61import jdk.tools.jlink.plugin.ResourcePoolEntry;62import tests.Helper;6364public class StripJavaDebugAttributesPluginTest {65public static void main(String[] args) throws Exception {66new StripJavaDebugAttributesPluginTest().test();67}6869public void test() throws Exception {70Helper helper = Helper.newHelper();71if (helper == null) {72// Skip test if the jmods directory is missing (e.g. exploded image)73System.err.println("Test not run, NO jmods directory");74return;75}7677List<String> classes = Arrays.asList("toto.Main", "toto.com.foo.bar.X");78Path moduleFile = helper.generateModuleCompiledClasses(79helper.getJmodSrcDir(), helper.getJmodClassesDir(), "leaf1", classes);80Path moduleInfo = moduleFile.resolve("module-info.class");8182// Classes have been compiled in debug.83List<Path> covered = new ArrayList<>();84byte[] infoContent = Files.readAllBytes(moduleInfo);85try (Stream<Path> stream = Files.walk(moduleFile)) {86for (Iterator<Path> iterator = stream.iterator(); iterator.hasNext(); ) {87Path p = iterator.next();88if (Files.isRegularFile(p) && p.toString().endsWith(".class")) {89byte[] content = Files.readAllBytes(p);90String path = "/" + helper.getJmodClassesDir().relativize(p).toString();91String moduleInfoPath = path + "/module-info.class";92check(path, content, moduleInfoPath, infoContent);93covered.add(p);94}95}96}97if (covered.isEmpty()) {98throw new AssertionError("No class to compress");99} else {100System.err.println("removed debug attributes from "101+ covered.size() + " classes");102}103}104105private void check(String path, byte[] content, String infoPath, byte[] moduleInfo) throws Exception {106path = path.replace('\\', '/');107StripJavaDebugAttributesPlugin debug = new StripJavaDebugAttributesPlugin();108debug.configure(new HashMap<>());109ResourcePoolEntry result1 = stripDebug(debug, ResourcePoolEntry.create(path,content), path, infoPath, moduleInfo);110111if (!path.endsWith("module-info.class")) {112if (result1.contentLength() >= content.length) {113throw new AssertionError("Class size not reduced, debug info not "114+ "removed for " + path);115}116checkDebugAttributes(result1.contentBytes());117}118119ResourcePoolEntry result2 = stripDebug(debug, result1, path, infoPath, moduleInfo);120if (result1.contentLength() != result2.contentLength()) {121throw new AssertionError("removing debug info twice reduces class size of "122+ path);123}124checkDebugAttributes(result1.contentBytes());125}126127private ResourcePoolEntry stripDebug(Plugin debug, ResourcePoolEntry classResource,128String path, String infoPath, byte[] moduleInfo) throws Exception {129ResourcePoolManager resources = new ResourcePoolManager();130resources.add(classResource);131if (!path.endsWith("module-info.class")) {132ResourcePoolEntry res2 = ResourcePoolEntry.create(infoPath, moduleInfo);133resources.add(res2);134}135ResourcePoolManager results = new ResourcePoolManager();136ResourcePool resPool = debug.transform(resources.resourcePool(),137results.resourcePoolBuilder());138System.out.println(classResource.path());139140return resPool.findEntry(classResource.path()).get();141}142143private void checkDebugAttributes(byte[] strippedClassFile) throws IOException, ConstantPoolException {144ClassFile classFile = ClassFile.read(new ByteArrayInputStream(strippedClassFile));145String[] debugAttributes = new String[]{146Attribute.LineNumberTable,147Attribute.LocalVariableTable,148Attribute.LocalVariableTypeTable149};150for (Method method : classFile.methods) {151String methodName = method.getName(classFile.constant_pool);152Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code);153for (String attr : debugAttributes) {154if (code.attributes.get(attr) != null) {155throw new AssertionError("Debug attribute was not removed: " + attr +156" from method " + classFile.getName() + "#" + methodName);157}158}159}160}161}162163164