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  * @build tests.*
  66  * @run main IntegrationTest
  67  */
  68 public class IntegrationTest {
  69 
  70     static {
  71         ImagePluginProviderRepository.registerPluginProvider(new MyProvider(MyProvider.NAME + "0"));
  72         ImagePluginProviderRepository.registerPluginProvider(new MyProvider(MyProvider.NAME + "1"));
  73         ImagePluginProviderRepository.registerPluginProvider(new MyProvider(MyProvider.NAME + "2"));
  74         ImagePluginProviderRepository.registerPluginProvider(new MyProvider(MyProvider.NAME + "3"));
  75         ImagePluginProviderRepository.registerPluginProvider(new MyProvider(MyProvider.NAME + "4"));
  76         ImagePluginProviderRepository.registerPluginProvider(new MyPostProcessorProvider());
  77     }
  78 
  79     private static final List<Integer> ordered = new ArrayList<>();
  80 
  81     public static class MyPostProcessorProvider extends PostProcessingPluginProvider {
  82 
  83         public class MyPostProcessor implements PostProcessingPlugin {
  84 
  85             @Override
  86             public List<String> process(ProcessingManager manager) throws Exception {
  87                 Files.createFile(manager.getImage().getHome().resolve("toto.txt"));
  88                 return null;
  89             }
  90 
  91             @Override
  92             public String getName() {
  93                 return NAME;
  94             }
  95 
  96         }
  97 
  98         public static final String NAME = "mypostprocessor";
  99 
 100         public MyPostProcessorProvider() {
 101             super(NAME, "");
 102         }
 103 
 104         @Override
 105         public PostProcessingPlugin[] newPlugins(Map<String, Object> config) throws IOException {
 106             return new PostProcessingPlugin[]{new MyPostProcessor()};
 107         }
 108 
 109         @Override
 110         public String getCategory() {
 111             return PROCESSOR;
 112         }
 113 
 114     }
 115 
 116     public static class MyProvider extends ImageFilePluginProvider {
 117         public class MyPlugin1 implements ImageFilePlugin {
 118 
 119             Integer index;
 120 
 121             private MyPlugin1(Integer index) {
 122                 this.index = index;
 123             }
 124 
 125             @Override
 126             public void visit(ImageFilePool inFiles, ImageFilePool outFiles) throws Exception {
 127                 System.err.println(NAME + index);
 128                 ordered.add(index);
 129                 inFiles.visit((ImageFilePool.ImageFile file) -> {
 130                     return file;
 131                 }, outFiles);
 132             }
 133 
 134             @Override
 135             public String getName() {
 136                 return NAME;
 137             }
 138 
 139         }
 140         static final String NAME = "myprovider";
 141         static final String INDEX = "INDEX";
 142 
 143         public MyProvider(String name) {
 144             super(name, "");
 145         }
 146 
 147         @Override
 148         public ImageFilePlugin[] newPlugins(Map<String, Object> config) throws IOException {
 149             return new ImageFilePlugin[]{new MyPlugin1((Integer) config.get(INDEX))};
 150         }
 151 
 152         @Override
 153         public String getCategory() {
 154             return PluginProvider.TRANSFORMER;
 155         }
 156     }
 157 
 158     public static void main(String[] args) throws Exception {
 159 
 160         Helper helper = Helper.newHelper();
 161         if (helper == null) {
 162             System.err.println("Test not run");
 163             return;
 164         }
 165         apitest();
 166         test();
 167         testOrder();
 168         testNegativeOrder();
 169     }
 170 
 171     private static void apitest() throws Exception {
 172         boolean failed = false;
 173         Jlink jl = new Jlink();
 174 
 175         try {
 176             jl.build(null);
 177             failed = true;
 178         } catch (Exception ex) {
 179             // XXX OK
 180         }
 181         if (failed) {
 182             throw new Exception("Should have failed");
 183         }
 184         System.out.println(jl);
 185 
 186         JlinkConfiguration config
 187                 = new JlinkConfiguration(null, null, null, null, null);
 188 
 189         System.out.println(config);
 190 
 191         try {
 192             PluginConfiguration pc = new PluginConfiguration(null, null);
 193             failed = true;
 194         } catch (Exception ex) {
 195             // XXX OK
 196         }
 197         if (failed) {
 198             throw new Exception("Should have failed");
 199         }
 200         System.out.println(new PluginConfiguration("toto", null));
 201 
 202         try {
 203             StackedPluginConfiguration spc = new StackedPluginConfiguration(null, 0, failed, null);
 204             failed = true;
 205         } catch (Exception ex) {
 206             // XXX OK
 207         }
 208         if (failed) {
 209             throw new Exception("Should have failed");
 210         }
 211         System.out.println(new StackedPluginConfiguration("toto", 0, failed, null));
 212 
 213         try {
 214             StackedPluginConfiguration spc = new StackedPluginConfiguration("toto", -1, failed, null);
 215             failed = true;
 216         } catch (Exception ex) {
 217             // XXX OK
 218         }
 219         if (failed) {
 220             throw new Exception("Should have failed");
 221         }
 222     }
 223 
 224     private static void test() throws Exception {
 225         Jlink jlink = new Jlink();
 226         Path output = Paths.get("integrationout");
 227         List<Path> modulePaths = new ArrayList<>();
 228         File jmods
 229                 = JImageGenerator.getJModsDir(new File(System.getProperty("test.jdk")));
 230         modulePaths.add(jmods.toPath());
 231         Set<String> mods = new HashSet<>();
 232         mods.add("java.management");
 233         Set<String> limits = new HashSet<>();
 234         limits.add("java.management");
 235         JlinkConfiguration config = new Jlink.JlinkConfiguration(output,
 236                 modulePaths, mods, limits, null);
 237 
 238         List<Jlink.StackedPluginConfiguration> lst = new ArrayList<>();
 239         List<Jlink.StackedPluginConfiguration> post = new ArrayList<>();
 240 
 241         //Strip debug
 242         {
 243             Map<String, Object> config1 = new HashMap<>();
 244             config1.put(CmdPluginProvider.TOOL_ARGUMENT_PROPERTY, "on");
 245             StackedPluginConfiguration strip
 246                     = new StackedPluginConfiguration("strip-java-debug", 0, false, config1);
 247             lst.add(strip);
 248         }
 249         // compress
 250         {
 251             Map<String, Object> config1 = new HashMap<>();
 252             config1.put(CmdPluginProvider.TOOL_ARGUMENT_PROPERTY, "on");
 253             config1.put("compress-resources-level", "0");
 254             StackedPluginConfiguration compress
 255                     = new StackedPluginConfiguration("compress-resources", 0, false, config1);
 256             lst.add(compress);
 257         }
 258         // Post processor
 259         {
 260             Map<String, Object> config1 = new HashMap<>();
 261             StackedPluginConfiguration postprocessor
 262                     = new StackedPluginConfiguration(MyPostProcessorProvider.NAME, 0, false, config1);
 263             post.add(postprocessor);
 264         }
 265         // Image builder
 266         Map<String, Object> config1 = new HashMap<>();
 267         config1.put("genbom", "true");
 268         PluginConfiguration imgBuilder
 269                 = new Jlink.PluginConfiguration("default-image-builder", config1);
 270         PluginsConfiguration plugins
 271                 = new Jlink.PluginsConfiguration(lst, post, imgBuilder);
 272 
 273         jlink.build(config, plugins);
 274 
 275         if (!Files.exists(output)) {
 276             throw new AssertionError("Directory not created");
 277         }
 278         File jimage = new File(output.toString(), "lib" + File.separator
 279                 + "modules" + File.separator + "bootmodules.jimage");
 280         if (!jimage.exists()) {
 281             throw new AssertionError("jimage not generated");
 282         }
 283         File bom = new File(output.toString(), "bom");
 284         if (!bom.exists()) {
 285             throw new AssertionError("bom not generated");
 286         }
 287         File release = new File(output.toString(), "release");
 288         if (!release.exists()) {
 289             throw new AssertionError("release not generated");
 290         }
 291 
 292         if (!Files.exists(output.resolve("toto.txt"))) {
 293             throw new AssertionError("Post processing not called");
 294         }
 295 
 296     }
 297 
 298     private static void testOrder() throws Exception {
 299         Jlink jlink = new Jlink();
 300         Path output = Paths.get("integrationout2");
 301         List<Path> modulePaths = new ArrayList<>();
 302         File jmods
 303                 = JImageGenerator.getJModsDir(new File(System.getProperty("test.jdk")));
 304         modulePaths.add(jmods.toPath());
 305         Set<String> mods = new HashSet<>();
 306         mods.add("java.management");
 307         Set<String> limits = new HashSet<>();
 308         limits.add("java.management");
 309         JlinkConfiguration config = new Jlink.JlinkConfiguration(output,
 310                 modulePaths, mods, limits, null);
 311 
 312         List<Jlink.StackedPluginConfiguration> lst = new ArrayList<>();
 313 
 314         // packager 1
 315         {
 316             Map<String, Object> config1 = new HashMap<>();
 317             config1.put(MyProvider.INDEX, 2);
 318             StackedPluginConfiguration compress
 319                     = new StackedPluginConfiguration(MyProvider.NAME + "0", 0, false, config1);
 320             lst.add(compress);
 321         }
 322 
 323         // packager 2
 324         {
 325             Map<String, Object> config1 = new HashMap<>();
 326             config1.put(MyProvider.INDEX, 0);
 327             StackedPluginConfiguration compress
 328                     = new StackedPluginConfiguration(MyProvider.NAME + "1", 0, true, config1);
 329             lst.add(compress);
 330         }
 331 
 332         // packager 3
 333         {
 334             Map<String, Object> config1 = new HashMap<>();
 335             config1.put(MyProvider.INDEX, 1);
 336             StackedPluginConfiguration compress
 337                     = new StackedPluginConfiguration(MyProvider.NAME + "2", 1, true, config1);
 338             lst.add(compress);
 339         }
 340 
 341         // packager 4
 342         {
 343             Map<String, Object> config1 = new HashMap<>();
 344             config1.put(MyProvider.INDEX, 3);
 345             StackedPluginConfiguration compress
 346                     = new StackedPluginConfiguration(MyProvider.NAME + "3", 1, false, config1);
 347             lst.add(compress);
 348         }
 349 
 350         // Image builder
 351         Map<String, Object> config1 = new HashMap<>();
 352         PluginConfiguration imgBuilder
 353                 = new Jlink.PluginConfiguration("default-image-builder", config1);
 354         PluginsConfiguration plugins
 355                 = new Jlink.PluginsConfiguration(lst, Collections.emptyList(), imgBuilder);
 356 
 357         jlink.build(config, plugins);
 358 
 359         if (ordered.isEmpty()) {
 360             throw new AssertionError("Plugins not called");
 361         }
 362         List<Integer> clone = new ArrayList<>();
 363         clone.addAll(ordered);
 364         Collections.sort(clone);
 365         if (!clone.equals(ordered)) {
 366             throw new AssertionError("Ordered is not properly sorted" + ordered);
 367         }
 368     }
 369 
 370     private static void testNegativeOrder() throws Exception {
 371         Jlink jlink = new Jlink();
 372         Path output = Paths.get("integrationout3");
 373         List<Path> modulePaths = new ArrayList<>();
 374         File jmods
 375                 = JImageGenerator.getJModsDir(new File(System.getProperty("test.jdk")));
 376         modulePaths.add(jmods.toPath());
 377         Set<String> mods = new HashSet<>();
 378         mods.add("java.management");
 379         Set<String> limits = new HashSet<>();
 380         limits.add("java.management");
 381         JlinkConfiguration config = new Jlink.JlinkConfiguration(output,
 382                 modulePaths, mods, limits, null);
 383 
 384         List<Jlink.StackedPluginConfiguration> lst = new ArrayList<>();
 385 
 386         // packager 1
 387         {
 388             Map<String, Object> config1 = new HashMap<>();
 389             config1.put(MyProvider.INDEX, 2);
 390             StackedPluginConfiguration compress
 391                     = new StackedPluginConfiguration(MyProvider.NAME, 0, false, config1);
 392             lst.add(compress);
 393         }
 394 
 395         // packager 2
 396         {
 397             Map<String, Object> config1 = new HashMap<>();
 398             config1.put(MyProvider.INDEX, 0);
 399             StackedPluginConfiguration compress
 400                     = new StackedPluginConfiguration(MyProvider.NAME, 0, false, config1);
 401             lst.add(compress);
 402         }
 403 
 404         // Image builder
 405         Map<String, Object> config1 = new HashMap<>();
 406         PluginConfiguration imgBuilder
 407                 = new Jlink.PluginConfiguration("default-image-builder", config1);
 408         PluginsConfiguration plugins
 409                 = new Jlink.PluginsConfiguration(lst, Collections.emptyList(), imgBuilder);
 410         boolean failed = false;
 411         try {
 412             jlink.build(config, plugins);
 413             failed = true;
 414         } catch (Exception ex) {
 415             // XXX OK
 416         }
 417         if (failed) {
 418             throw new AssertionError("Should have failed");
 419         }
 420     }
 421 }