src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java
branchJDK-8200758-branch
changeset 58670 6fb9e12d5595
parent 58647 2c43b89b1679
child 58888 d802578912f3
equal deleted inserted replaced
58648:3bf53ffa9ae7 58670:6fb9e12d5595
    46 import java.util.Optional;
    46 import java.util.Optional;
    47 import java.util.ResourceBundle;
    47 import java.util.ResourceBundle;
    48 import java.util.Set;
    48 import java.util.Set;
    49 import java.util.concurrent.atomic.AtomicReference;
    49 import java.util.concurrent.atomic.AtomicReference;
    50 import java.util.function.Consumer;
    50 import java.util.function.Consumer;
       
    51 import java.util.stream.Stream;
    51 import javax.xml.parsers.DocumentBuilder;
    52 import javax.xml.parsers.DocumentBuilder;
    52 import javax.xml.parsers.DocumentBuilderFactory;
    53 import javax.xml.parsers.DocumentBuilderFactory;
    53 import javax.xml.xpath.XPath;
    54 import javax.xml.xpath.XPath;
    54 import javax.xml.xpath.XPathConstants;
    55 import javax.xml.xpath.XPathConstants;
    55 import javax.xml.xpath.XPathFactory;
    56 import javax.xml.xpath.XPathFactory;
   745         AtomicReference<IOException> toThrow = new AtomicReference<>();
   746         AtomicReference<IOException> toThrow = new AtomicReference<>();
   746         String appExecutable = "/Contents/MacOS/" + APP_NAME.fetchFrom(params);
   747         String appExecutable = "/Contents/MacOS/" + APP_NAME.fetchFrom(params);
   747         String keyChain = SIGNING_KEYCHAIN.fetchFrom(params);
   748         String keyChain = SIGNING_KEYCHAIN.fetchFrom(params);
   748 
   749 
   749         // sign all dylibs and jars
   750         // sign all dylibs and jars
   750         Files.walk(appLocation).peek(path -> { // fix permissions
   751         try (Stream<Path> stream = Files.walk(appLocation)) {
   751                     try {
   752             stream.peek(path -> { // fix permissions
   752                         Set<PosixFilePermission> pfp =
   753                 try {
   753                                 Files.getPosixFilePermissions(path);
   754                     Set<PosixFilePermission> pfp =
   754                         if (!pfp.contains(PosixFilePermission.OWNER_WRITE)) {
   755                             Files.getPosixFilePermissions(path);
   755                             pfp = EnumSet.copyOf(pfp);
   756                     if (!pfp.contains(PosixFilePermission.OWNER_WRITE)) {
   756                             pfp.add(PosixFilePermission.OWNER_WRITE);
   757                         pfp = EnumSet.copyOf(pfp);
   757                             Files.setPosixFilePermissions(path, pfp);
   758                         pfp.add(PosixFilePermission.OWNER_WRITE);
   758                         }
   759                         Files.setPosixFilePermissions(path, pfp);
   759                     } catch (IOException e) {
       
   760                         Log.verbose(e);
       
   761                     }
   760                     }
   762                 }).filter(p -> Files.isRegularFile(p)
   761                 } catch (IOException e) {
   763                           && !(p.toString().contains("/Contents/MacOS/libjli.dylib")
   762                     Log.verbose(e);
   764                           || p.toString().endsWith(appExecutable)
   763                 }
   765                           || p.toString().contains("/Contents/runtime")
   764             }).filter(p -> Files.isRegularFile(p)
   766                           || p.toString().contains("/Contents/Frameworks"))).forEach(p -> {
   765                       && !(p.toString().contains("/Contents/MacOS/libjli.dylib")
   767                     //noinspection ThrowableResultOfMethodCallIgnored
   766                       || p.toString().endsWith(appExecutable)
   768                     if (toThrow.get() != null) return;
   767                       || p.toString().contains("/Contents/runtime")
   769 
   768                       || p.toString().contains("/Contents/Frameworks"))).forEach(p -> {
   770                     // If p is a symlink then skip the signing process.
   769                 //noinspection ThrowableResultOfMethodCallIgnored
   771                     if (Files.isSymbolicLink(p)) {
   770                 if (toThrow.get() != null) return;
   772                         if (VERBOSE.fetchFrom(params)) {
   771 
   773                             Log.verbose(MessageFormat.format(I18N.getString(
   772                 // If p is a symlink then skip the signing process.
   774                                     "message.ignoring.symlink"), p.toString()));
   773                 if (Files.isSymbolicLink(p)) {
   775                         }
   774                     if (VERBOSE.fetchFrom(params)) {
   776                     } else {
   775                         Log.verbose(MessageFormat.format(I18N.getString(
   777                         if (p.toString().endsWith(LIBRARY_NAME)) {
   776                                 "message.ignoring.symlink"), p.toString()));
   778                             if (isFileSigned(p)) {
   777                     }
   779                                 return;
   778                 } else {
   780                             }
   779                     if (p.toString().endsWith(LIBRARY_NAME)) {
   781                         }
   780                         if (isFileSigned(p)) {
   782 
   781                             return;
   783                         List<String> args = new ArrayList<>();
       
   784                         args.addAll(Arrays.asList("codesign",
       
   785                                 "-s", signingIdentity, // sign with this key
       
   786                                 "--prefix", identifierPrefix,
       
   787                                 // use the identifier as a prefix
       
   788                                 "-vvvv"));
       
   789                         if (entitlementsFile != null &&
       
   790                                 (p.toString().endsWith(".jar")
       
   791                                 || p.toString().endsWith(".dylib"))) {
       
   792                             args.add("--entitlements");
       
   793                             args.add(entitlementsFile); // entitlements
       
   794                         } else if (inheritedEntitlements != null &&
       
   795                                 Files.isExecutable(p)) {
       
   796                             args.add("--entitlements");
       
   797                             args.add(inheritedEntitlements);
       
   798                             // inherited entitlements for executable processes
       
   799                         }
       
   800                         if (keyChain != null && !keyChain.isEmpty()) {
       
   801                             args.add("--keychain");
       
   802                             args.add(keyChain);
       
   803                         }
       
   804                         args.add(p.toString());
       
   805 
       
   806                         try {
       
   807                             Set<PosixFilePermission> oldPermissions =
       
   808                                     Files.getPosixFilePermissions(p);
       
   809                             File f = p.toFile();
       
   810                             f.setWritable(true, true);
       
   811 
       
   812                             ProcessBuilder pb = new ProcessBuilder(args);
       
   813                             IOUtils.exec(pb);
       
   814 
       
   815                             Files.setPosixFilePermissions(p, oldPermissions);
       
   816                         } catch (IOException ioe) {
       
   817                             toThrow.set(ioe);
       
   818                         }
   782                         }
   819                     }
   783                     }
   820                 });
   784 
   821 
   785                     List<String> args = new ArrayList<>();
       
   786                     args.addAll(Arrays.asList("codesign",
       
   787                             "-s", signingIdentity, // sign with this key
       
   788                             "--prefix", identifierPrefix,
       
   789                             // use the identifier as a prefix
       
   790                             "-vvvv"));
       
   791                     if (entitlementsFile != null &&
       
   792                             (p.toString().endsWith(".jar")
       
   793                             || p.toString().endsWith(".dylib"))) {
       
   794                         args.add("--entitlements");
       
   795                         args.add(entitlementsFile); // entitlements
       
   796                     } else if (inheritedEntitlements != null &&
       
   797                             Files.isExecutable(p)) {
       
   798                         args.add("--entitlements");
       
   799                         args.add(inheritedEntitlements);
       
   800                         // inherited entitlements for executable processes
       
   801                     }
       
   802                     if (keyChain != null && !keyChain.isEmpty()) {
       
   803                         args.add("--keychain");
       
   804                         args.add(keyChain);
       
   805                     }
       
   806                     args.add(p.toString());
       
   807 
       
   808                     try {
       
   809                         Set<PosixFilePermission> oldPermissions =
       
   810                                 Files.getPosixFilePermissions(p);
       
   811                         File f = p.toFile();
       
   812                         f.setWritable(true, true);
       
   813 
       
   814                         ProcessBuilder pb = new ProcessBuilder(args);
       
   815                         IOUtils.exec(pb);
       
   816 
       
   817                         Files.setPosixFilePermissions(p, oldPermissions);
       
   818                     } catch (IOException ioe) {
       
   819                         toThrow.set(ioe);
       
   820                     }
       
   821                 }
       
   822             });
       
   823         }
   822         IOException ioe = toThrow.get();
   824         IOException ioe = toThrow.get();
   823         if (ioe != null) {
   825         if (ioe != null) {
   824             throw ioe;
   826             throw ioe;
   825         }
   827         }
   826 
   828