1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.io.File;
  25 import java.io.IOException;
  26 import java.nio.file.Files;
  27 import java.nio.file.Path;
  28 import java.nio.file.Paths;
  29 import java.util.ArrayList;
  30 import java.util.Collections;
  31 import java.util.HashMap;
  32 import java.util.HashSet;
  33 import java.util.List;
  34 import java.util.Map;
  35 import java.util.Set;
  36 import jdk.tools.jlink.internal.ImagePluginProviderRepository;
  37 import jdk.tools.jlink.plugins.CmdPluginProvider;
  38 import jdk.tools.jlink.plugins.ImageFilePlugin;
  39 import jdk.tools.jlink.plugins.ImageFilePluginProvider;
  40 import jdk.tools.jlink.plugins.ImageFilePool;
  41 import jdk.tools.jlink.plugins.Jlink;
  42 import jdk.tools.jlink.plugins.Jlink.JlinkConfiguration;
  43 import jdk.tools.jlink.plugins.Jlink.PluginConfiguration;
  44 import jdk.tools.jlink.plugins.Jlink.PluginsConfiguration;
  45 import jdk.tools.jlink.plugins.Jlink.StackedPluginConfiguration;
  46 import jdk.tools.jlink.plugins.PluginProvider;
  47 import jdk.tools.jlink.plugins.PostProcessingPlugin;
  48 import jdk.tools.jlink.plugins.PostProcessingPluginProvider;
  49 import jdk.tools.jlink.plugins.ProcessingManager;
  50 
  51 import tests.Helper;
  52 import tests.JImageGenerator;
  53 
  54 /*
  55  * @test
  56  * @summary Test integration API
  57  * @author Jean-Francois Denise
  58  * @library ../lib
  59  * @modules java.base/jdk.internal.jimage
  60  *          jdk.jdeps/com.sun.tools.classfile
  61  *          jdk.jlink/jdk.tools.jlink
  62  *          jdk.jlink/jdk.tools.jlink.internal
  63  *          jdk.jlink/jdk.tools.jmod
  64  *          jdk.jlink/jdk.tools.jimage
  65  *          jdk.compiler
  66  * @build tests.*
  67  * @run main IntegrationTest
  68  */
  69 public class IntegrationTest {
  70 
  71     static {
  72         ImagePluginProviderRepository.registerPluginProvider(new MyProvider(MyProvider.NAME + "0"));
  73         ImagePluginProviderRepository.registerPluginProvider(new MyProvider(MyProvider.NAME + "1"));
  74         ImagePluginProviderRepository.registerPluginProvider(new MyProvider(MyProvider.NAME + "2"));
  75         ImagePluginProviderRepository.registerPluginProvider(new MyProvider(MyProvider.NAME + "3"));
  76         ImagePluginProviderRepository.registerPluginProvider(new MyProvider(MyProvider.NAME + "4"));
  77         ImagePluginProviderRepository.registerPluginProvider(new MyPostProcessorProvider());
  78     }
  79 
  80     private static final List<Integer> ordered = new ArrayList<>();
  81 
  82     public static class MyPostProcessorProvider extends PostProcessingPluginProvider {
  83 
  84         public class MyPostProcessor implements PostProcessingPlugin {
  85 
  86             @Override
  87             public List<String> process(ProcessingManager manager) throws Exception {
  88                 Files.createFile(manager.getImage().getHome().resolve("toto.txt"));
  89                 return null;
  90             }
  91 
  92             @Override
  93             public String getName() {
  94                 return NAME;
  95             }
  96 
  97         }
  98 
  99         public static final String NAME = "mypostprocessor";
 100 
 101         public MyPostProcessorProvider() {
 102             super(NAME, "");
 103         }
 104 
 105         @Override
 106         public PostProcessingPlugin[] newPlugins(Map<String, Object> config) throws IOException {
 107             return new PostProcessingPlugin[]{new MyPostProcessor()};
 108         }
 109 
 110         @Override
 111         public String getCategory() {
 112             return PROCESSOR;
 113         }
 114 
 115     }
 116 
 117     public static class MyProvider extends ImageFilePluginProvider {
 118         public class MyPlugin1 implements ImageFilePlugin {
 119 
 120             Integer index;
 121 
 122             private MyPlugin1(Integer index) {
 123                 this.index = index;
 124             }
 125 
 126             @Override
 127             public void visit(ImageFilePool inFiles, ImageFilePool outFiles) throws Exception {
 128                 System.err.println(NAME + index);
 129                 ordered.add(index);
 130                 inFiles.visit((ImageFilePool.ImageFile file) -> {
 131                     return file;
 132                 }, outFiles);
 133             }
 134 
 135             @Override
 136             public String getName() {
 137                 return NAME;
 138             }
 139 
 140         }
 141         static final String NAME = "myprovider";
 142         static final String INDEX = "INDEX";
 143 
 144         public MyProvider(String name) {
 145             super(name, "");
 146         }
 147 
 148         @Override
 149         public ImageFilePlugin[] newPlugins(Map<String, Object> config) throws IOException {
 150             return new ImageFilePlugin[]{new MyPlugin1((Integer) config.get(INDEX))};
 151         }
 152 
 153         @Override
 154         public String getCategory() {
 155             return PluginProvider.TRANSFORMER;
 156         }
 157     }
 158 
 159     public static void main(String[] args) throws Exception {
 160 
 161         Helper helper = Helper.newHelper();
 162         if (helper == null) {
 163             System.err.println("Test not run");
 164             return;
 165         }
 166         apitest();
 167         test();
 168         testOrder();
 169         testNegativeOrder();
 170     }
 171 
 172     private static void apitest() throws Exception {
 173         boolean failed = false;
 174         Jlink jl = new Jlink();
 175 
 176         try {
 177             jl.build(null);
 178             failed = true;
 179         } catch (Exception ex) {
 180             // XXX OK
 181         }
 182         if (failed) {
 183             throw new Exception("Should have failed");
 184         }
 185         System.out.println(jl);
 186 
 187         JlinkConfiguration config
 188                 = new JlinkConfiguration(null, null, null, null, null);
 189 
 190         System.out.println(config);
 191 
 192         try {
 193             PluginConfiguration pc = new PluginConfiguration(null, null);
 194             failed = true;
 195         } catch (Exception ex) {
 196             // XXX OK
 197         }
 198         if (failed) {
 199             throw new Exception("Should have failed");
 200         }
 201         System.out.println(new PluginConfiguration("toto", null));
 202 
 203         try {
 204             StackedPluginConfiguration spc = new StackedPluginConfiguration(null, 0, failed, null);
 205             failed = true;
 206         } catch (Exception ex) {
 207             // XXX OK
 208         }
 209         if (failed) {
 210             throw new Exception("Should have failed");
 211         }
 212         System.out.println(new StackedPluginConfiguration("toto", 0, failed, null));
 213 
 214         try {
 215             StackedPluginConfiguration spc = new StackedPluginConfiguration("toto", -1, failed, null);
 216             failed = true;
 217         } catch (Exception ex) {
 218             // XXX OK
 219         }
 220         if (failed) {
 221             throw new Exception("Should have failed");
 222         }
 223     }
 224 
 225     private static void test() throws Exception {
 226         Jlink jlink = new Jlink();
 227         Path output = Paths.get("integrationout");
 228         List<Path> modulePaths = new ArrayList<>();
 229         File jmods
 230                 = JImageGenerator.getJModsDir(new File(System.getProperty("test.jdk")));
 231         modulePaths.add(jmods.toPath());
 232         Set<String> mods = new HashSet<>();
 233         mods.add("java.management");
 234         Set<String> limits = new HashSet<>();
 235         limits.add("java.management");
 236         JlinkConfiguration config = new Jlink.JlinkConfiguration(output,
 237                 modulePaths, mods, limits, null);
 238 
 239         List<Jlink.StackedPluginConfiguration> lst = new ArrayList<>();
 240         List<Jlink.StackedPluginConfiguration> post = new ArrayList<>();
 241 
 242         //Strip debug
 243         {
 244             Map<String, Object> config1 = new HashMap<>();
 245             config1.put(CmdPluginProvider.TOOL_ARGUMENT_PROPERTY, "on");
 246             StackedPluginConfiguration strip
 247                     = new StackedPluginConfiguration("strip-java-debug", 0, false, config1);
 248             lst.add(strip);
 249         }
 250         // compress
 251         {
 252             Map<String, Object> config1 = new HashMap<>();
 253             config1.put(CmdPluginProvider.TOOL_ARGUMENT_PROPERTY, "on");
 254             config1.put("compress-resources-level", "0");
 255             StackedPluginConfiguration compress
 256                     = new StackedPluginConfiguration("compress-resources", 0, false, config1);
 257             lst.add(compress);
 258         }
 259         // Post processor
 260         {
 261             Map<String, Object> config1 = new HashMap<>();
 262             StackedPluginConfiguration postprocessor
 263                     = new StackedPluginConfiguration(MyPostProcessorProvider.NAME, 0, false, config1);
 264             post.add(postprocessor);
 265         }
 266         // Image builder
 267         Map<String, Object> config1 = new HashMap<>();
 268         config1.put("genbom", "true");
 269         PluginConfiguration imgBuilder
 270                 = new Jlink.PluginConfiguration("default-image-builder", config1);
 271         PluginsConfiguration plugins
 272                 = new Jlink.PluginsConfiguration(lst, post, imgBuilder);
 273 
 274         jlink.build(config, plugins);
 275 
 276         if (!Files.exists(output)) {
 277             throw new AssertionError("Directory not created");
 278         }
 279         File jimage = new File(output.toString(), "lib" + File.separator
 280                 + "modules" + File.separator + "bootmodules.jimage");
 281         if (!jimage.exists()) {
 282             throw new AssertionError("jimage not generated");
 283         }
 284         File bom = new File(output.toString(), "bom");
 285         if (!bom.exists()) {
 286             throw new AssertionError("bom not generated");
 287         }
 288         File release = new File(output.toString(), "release");
 289         if (!release.exists()) {
 290             throw new AssertionError("release not generated");
 291         }
 292 
 293         if (!Files.exists(output.resolve("toto.txt"))) {
 294             throw new AssertionError("Post processing not called");
 295         }
 296 
 297     }
 298 
 299     private static void testOrder() throws Exception {
 300         Jlink jlink = new Jlink();
 301         Path output = Paths.get("integrationout2");
 302         List<Path> modulePaths = new ArrayList<>();
 303         File jmods
 304                 = JImageGenerator.getJModsDir(new File(System.getProperty("test.jdk")));
 305         modulePaths.add(jmods.toPath());
 306         Set<String> mods = new HashSet<>();
 307         mods.add("java.management");
 308         Set<String> limits = new HashSet<>();
 309         limits.add("java.management");
 310         JlinkConfiguration config = new Jlink.JlinkConfiguration(output,
 311                 modulePaths, mods, limits, null);
 312 
 313         List<Jlink.StackedPluginConfiguration> lst = new ArrayList<>();
 314 
 315         // packager 1
 316         {
 317             Map<String, Object> config1 = new HashMap<>();
 318             config1.put(MyProvider.INDEX, 2);
 319             StackedPluginConfiguration compress
 320                     = new StackedPluginConfiguration(MyProvider.NAME + "0", 0, false, config1);
 321             lst.add(compress);
 322         }
 323 
 324         // packager 2
 325         {
 326             Map<String, Object> config1 = new HashMap<>();
 327             config1.put(MyProvider.INDEX, 0);
 328             StackedPluginConfiguration compress
 329                     = new StackedPluginConfiguration(MyProvider.NAME + "1", 0, true, config1);
 330             lst.add(compress);
 331         }
 332 
 333         // packager 3
 334         {
 335             Map<String, Object> config1 = new HashMap<>();
 336             config1.put(MyProvider.INDEX, 1);
 337             StackedPluginConfiguration compress
 338                     = new StackedPluginConfiguration(MyProvider.NAME + "2", 1, true, config1);
 339             lst.add(compress);
 340         }
 341 
 342         // packager 4
 343         {
 344             Map<String, Object> config1 = new HashMap<>();
 345             config1.put(MyProvider.INDEX, 3);
 346             StackedPluginConfiguration compress
 347                     = new StackedPluginConfiguration(MyProvider.NAME + "3", 1, false, config1);
 348             lst.add(compress);
 349         }
 350 
 351         // Image builder
 352         Map<String, Object> config1 = new HashMap<>();
 353         PluginConfiguration imgBuilder
 354                 = new Jlink.PluginConfiguration("default-image-builder", config1);
 355         PluginsConfiguration plugins
 356                 = new Jlink.PluginsConfiguration(lst, Collections.emptyList(), imgBuilder);
 357 
 358         jlink.build(config, plugins);
 359 
 360         if (ordered.isEmpty()) {
 361             throw new AssertionError("Plugins not called");
 362         }
 363         List<Integer> clone = new ArrayList<>();
 364         clone.addAll(ordered);
 365         Collections.sort(clone);
 366         if (!clone.equals(ordered)) {
 367             throw new AssertionError("Ordered is not properly sorted" + ordered);
 368         }
 369     }
 370 
 371     private static void testNegativeOrder() throws Exception {
 372         Jlink jlink = new Jlink();
 373         Path output = Paths.get("integrationout3");
 374         List<Path> modulePaths = new ArrayList<>();
 375         File jmods
 376                 = JImageGenerator.getJModsDir(new File(System.getProperty("test.jdk")));
 377         modulePaths.add(jmods.toPath());
 378         Set<String> mods = new HashSet<>();
 379         mods.add("java.management");
 380         Set<String> limits = new HashSet<>();
 381         limits.add("java.management");
 382         JlinkConfiguration config = new Jlink.JlinkConfiguration(output,
 383                 modulePaths, mods, limits, null);
 384 
 385         List<Jlink.StackedPluginConfiguration> lst = new ArrayList<>();
 386 
 387         // packager 1
 388         {
 389             Map<String, Object> config1 = new HashMap<>();
 390             config1.put(MyProvider.INDEX, 2);
 391             StackedPluginConfiguration compress
 392                     = new StackedPluginConfiguration(MyProvider.NAME, 0, false, config1);
 393             lst.add(compress);
 394         }
 395 
 396         // packager 2
 397         {
 398             Map<String, Object> config1 = new HashMap<>();
 399             config1.put(MyProvider.INDEX, 0);
 400             StackedPluginConfiguration compress
 401                     = new StackedPluginConfiguration(MyProvider.NAME, 0, false, config1);
 402             lst.add(compress);
 403         }
 404 
 405         // Image builder
 406         Map<String, Object> config1 = new HashMap<>();
 407         PluginConfiguration imgBuilder
 408                 = new Jlink.PluginConfiguration("default-image-builder", config1);
 409         PluginsConfiguration plugins
 410                 = new Jlink.PluginsConfiguration(lst, Collections.emptyList(), imgBuilder);
 411         boolean failed = false;
 412         try {
 413             jlink.build(config, plugins);
 414             failed = true;
 415         } catch (Exception ex) {
 416             // XXX OK
 417         }
 418         if (failed) {
 419             throw new AssertionError("Should have failed");
 420         }
 421     }
 422 }