8199871: Deprecate pack200 and unpack200 tools

Reviewed-by: mchung, psandoz, abuckley
This commit is contained in:
Henry Jen 2018-06-15 17:34:01 -07:00
parent db61a602f6
commit b026102163
17 changed files with 273 additions and 28 deletions

View File

@ -54,6 +54,7 @@ import java.util.LinkedList;
* Define the structure and ordering of "bands" in a packed file.
* @author John Rose
*/
@SuppressWarnings({"removal"})
abstract
class BandStructure {
static final int MAX_EFFORT = 9;

View File

@ -56,9 +56,12 @@ import java.util.zip.GZIPOutputStream;
/** Command line interface for Pack200.
*/
@SuppressWarnings({"removal"})
class Driver {
private static final ResourceBundle RESOURCE =
ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource");
private static final ResourceBundle RESOURCE =
ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource");
private static boolean suppressDeprecateMsg = false;
public static void main(String[] ava) throws IOException {
List<String> av = new ArrayList<>(Arrays.asList(ava));
@ -67,6 +70,7 @@ class Driver {
boolean doUnpack = false;
boolean doRepack = false;
boolean doZip = true;
suppressDeprecateMsg = av.remove("-XDsuppress-tool-removal-message");
String logFile = null;
String verboseProp = Utils.DEBUG_VERBOSE;
@ -85,6 +89,10 @@ class Driver {
}
}
if (!suppressDeprecateMsg) {
printDeprecateWarning(doPack, System.out);
}
// Collect engine properties here:
Map<String,String> engProps = new HashMap<>();
engProps.put(verboseProp, System.getProperty(verboseProp));
@ -394,6 +402,12 @@ class Driver {
return tmpfile.toFile();
}
private static
void printDeprecateWarning(boolean doPack, PrintStream out) {
String prog = doPack ? "pack200" : "unpack200";
out.println(MessageFormat.format(RESOURCE.getString(DriverResource.DEPRECATED), prog));
}
private static
void printUsage(boolean doPack, boolean full, PrintStream out) {
String prog = doPack ? "pack200" : "unpack200";
@ -407,6 +421,11 @@ class Driver {
break;
}
}
// Print a warning at the end
// The full help page is long, the beginning warning could be out of sight
if (full && !suppressDeprecateMsg) {
printDeprecateWarning(doPack, out);
}
}
private static

View File

@ -42,6 +42,7 @@ public class DriverResource extends ListResourceBundle {
public static final String MORE_INFO = "MORE_INFO";
public static final String DUPLICATE_OPTION = "DUPLICATE_OPTION";
public static final String BAD_SPEC = "BAD_SPEC";
public static final String DEPRECATED = "DEPRECATED";
/*
* The following are the output of 'pack200' and 'unpack200' commands.
@ -126,6 +127,7 @@ public class DriverResource extends ListResourceBundle {
{MORE_INFO, "(For more information, run {0} --help .)"}, // parameter 0:command name
{DUPLICATE_OPTION, "duplicate option: {0}"}, // parameter 0:option
{BAD_SPEC, "bad spec for {0}: {1}"}, // parameter 0:option;parameter 1:specifier
{DEPRECATED, "\nWarning: The {0} tool is deprecated, and is planned for removal in a future JDK release.\n"} // parameter 0:command name
};
protected Object[][] getContents() {

View File

@ -39,6 +39,7 @@ import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@SuppressWarnings({"removal"})
class NativeUnpack {
// Pointer to the native unpacker obj
private long unpackerPtr;

View File

@ -55,7 +55,7 @@ import java.util.jar.Pack200;
* @author Kumar Srinivasan
*/
@SuppressWarnings({"removal"})
public class PackerImpl extends TLGlobals implements Pack200.Packer {
/**

View File

@ -47,6 +47,7 @@ import java.util.jar.Pack200;
* Control block for publishing Pack200 options to the other classes.
*/
@SuppressWarnings({"removal"})
final class PropMap implements SortedMap<String, String> {
private final TreeMap<String, String> theMap = new TreeMap<>();;

View File

@ -53,6 +53,7 @@ import java.util.zip.ZipEntry;
*/
@SuppressWarnings({"removal"})
public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
public UnpackerImpl() {}

View File

@ -101,7 +101,10 @@ import sun.security.action.GetPropertyAction;
* @author John Rose
* @author Kumar Srinivasan
* @since 1.5
* @deprecated This class is deprecated, and is planned for removal in a future
* release.
*/
@Deprecated(since="11", forRemoval=true)
public abstract class Pack200 {
private Pack200() {} //prevent instantiation
@ -225,7 +228,10 @@ public abstract class Pack200 {
* to be thrown.
*
* @since 1.5
* @deprecated This interface is deprecated, and is planned for removal in a
* future release.
*/
@Deprecated(since="11", forRemoval=true)
public interface Packer {
/**
* This property is a numeral giving the estimated target size N
@ -584,7 +590,10 @@ public abstract class Pack200 {
* <p>
* This version of the unpacker is compatible with all previous versions.
* @since 1.5
* @deprecated This interface is deprecated, and is planned for removal in a
* future release.
*/
@Deprecated(since="11", forRemoval=true)
public interface Unpacker {
/** The string "keep", a possible value for certain properties.

View File

@ -26,15 +26,12 @@
package sun.tools.jar;
import java.io.File;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleDescriptor.Version;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import jdk.internal.module.ModulePath;
import jdk.internal.module.ModuleResolution;
@ -292,6 +289,10 @@ class GNUStyleOptions {
break;
String name = args[count];
if (name.equals("-XDsuppress-tool-removal-message")) {
jartool.suppressDeprecateMsg = true;
continue;
}
Option option = getOption(name);
String param = null;
if (option.hasArg) {

View File

@ -31,33 +31,34 @@ import java.lang.module.FindException;
import java.lang.module.InvalidModuleDescriptorException;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleDescriptor.Exports;
import java.lang.module.ModuleDescriptor.Provides;
import java.lang.module.ModuleDescriptor.Opens;
import java.lang.module.ModuleDescriptor.Requires;
import java.lang.module.ModuleDescriptor.Provides;
import java.lang.module.ModuleDescriptor.Version;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReader;
import java.lang.module.ModuleReference;
import java.lang.module.ResolutionException;
import java.lang.module.ResolvedModule;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.MessageFormat;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.*;
import java.util.jar.*;
import java.util.jar.Pack200.*;
import java.util.jar.Manifest;
import java.text.MessageFormat;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import jdk.internal.module.Checks;
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModuleHashesBuilder;
@ -67,10 +68,10 @@ import jdk.internal.module.ModuleResolution;
import jdk.internal.module.ModuleTarget;
import jdk.internal.util.jar.JarIndex;
import static jdk.internal.util.jar.JarIndex.INDEX_NAME;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.util.jar.JarFile.MANIFEST_NAME;
import static java.util.stream.Collectors.joining;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static jdk.internal.util.jar.JarIndex.INDEX_NAME;
/**
* This class implements a simple utility for creating files in the JAR
@ -151,6 +152,8 @@ public class Main {
*/
boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag, pflag, dflag;
boolean suppressDeprecateMsg = false;
/* To support additional GNU Style informational options */
Consumer<PrintWriter> info;
@ -238,6 +241,7 @@ public class Main {
/**
* Starts main program with the specified arguments.
*/
@SuppressWarnings({"removal"})
public synchronized boolean run(String args[]) {
ok = true;
if (!parseArgs(args)) {
@ -315,11 +319,14 @@ public class Main {
create(new BufferedOutputStream(out, 4096), manifest);
}
if (nflag) {
if (!suppressDeprecateMsg) {
warn(formatMsg("warn.flag.is.deprecated", "-n"));
}
File packFile = createTemporaryFile(tmpbase, ".pack");
try {
Packer packer = Pack200.newPacker();
java.util.jar.Pack200.Packer packer = java.util.jar.Pack200.newPacker();
Map<String, String> p = packer.properties();
p.put(Packer.EFFORT, "1"); // Minimal effort to conserve CPU
p.put(java.util.jar.Pack200.Packer.EFFORT, "1"); // Minimal effort to conserve CPU
try (JarFile jarFile = new JarFile(tmpFile.getCanonicalPath());
OutputStream pack = new FileOutputStream(packFile))
{
@ -332,7 +339,7 @@ public class Main {
try (OutputStream out = new FileOutputStream(tmpFile);
JarOutputStream jos = new JarOutputStream(out))
{
Unpacker unpacker = Pack200.newUnpacker();
java.util.jar.Pack200.Unpacker unpacker = java.util.jar.Pack200.newUnpacker();
unpacker.unpack(packFile, jos);
}
} finally {

View File

@ -131,6 +131,8 @@ warn.validator.concealed.public.class=\
in incompatible public interfaces
warn.release.unexpected.versioned.entry=\
unexpected versioned entry {0}
warn.flag.is.deprecated=\
Warning: The {0} option is deprecated, and is planned for removal in a future JDK release\n
out.added.manifest=\
added manifest
out.added.module-info=\
@ -170,7 +172,8 @@ Options:\n\
\ \ -v generate verbose output on standard output\n\
\ \ -f specify archive file name\n\
\ \ -m include manifest information from specified manifest file\n\
\ \ -n perform Pack200 normalization after creating a new archive\n\
\ \ -n perform Pack200 normalization after creating a new archive,\n\
\ \ this option is deprecated, and is planned for removal in a future JDK release\n\
\ \ -e specify application entry point for stand-alone application \n\
\ \ bundled into an executable jar file\n\
\ \ -0 store only; use no ZIP compression\n\
@ -250,7 +253,8 @@ main.help.opt.create=\
\ Operation modifiers valid only in create mode:\n
main.help.opt.create.normalize=\
\ -n, --normalize Normalize information in the new jar archive\n\
\ after creation
\ after creation. This option is deprecated, and is\n\
\ planned for removal in a future JDK release
main.help.opt.create.update=\
\ Operation modifiers valid only in create and update mode:\n
main.help.opt.create.update.main-class=\

View File

@ -36,7 +36,10 @@
* </dl>
*
* @moduleGraph
* @deprecated This module is deprecated, and is planned for removal in a
* future release.
* @since 9
*/
@Deprecated(since="11", forRemoval=true)
module jdk.pack {
}

View File

@ -118,6 +118,7 @@ typedef DWORDLONG julong;
#define tempname _tempname
#define sleep Sleep
#define snprintf _snprintf
#define PATH_SEPARATOR '\\'
#else
typedef signed char byte;
#ifdef _LP64
@ -128,6 +129,7 @@ typedef long long jlong;
typedef long long unsigned julong;
#endif
#define MKDIR(dir) mkdir(dir, 0777);
#define PATH_SEPARATOR '/'
#endif
#ifdef OLDCC

View File

@ -139,7 +139,7 @@ static void setup_gzin(unpacker* u) {
}
static const char* nbasename(const char* progname) {
const char* slash = strrchr(progname, '/');
const char* slash = strrchr(progname, PATH_SEPARATOR);
if (slash != null) progname = ++slash;
return progname;
}
@ -161,6 +161,13 @@ static const char* nbasename(const char* progname) {
"Exit Status:\n" \
" 0 if successful, >0 if an error occurred\n"
#define DEPRECATE_WARNING \
"\nWarning: The %s tool is deprecated, and is planned for removal in a future JDK release.\n\n"
#define SUPPRESS_DEPRECATE_MSG "-XDsuppress-tool-removal-message"
static bool suppress_warning = false;
static void usage(unpacker* u, const char* progname, bool full = false) {
// WinMain does not set argv[0] to the progrname
progname = (progname != null) ? nbasename(progname) : "unpack200";
@ -182,7 +189,11 @@ static char** init_args(int argc, char** argv, int &envargc) {
char* buf = (char*) strdup(env);
const char* delim = "\n\t ";
for (char* p = strtok(buf, delim); p != null; p = strtok(null, delim)) {
envargs.add(p);
if (!strcmp(p, SUPPRESS_DEPRECATE_MSG)) {
suppress_warning = true;
} else {
envargs.add(p);
}
}
}
// allocate extra margin at both head and tail
@ -194,7 +205,11 @@ static char** init_args(int argc, char** argv, int &envargc) {
}
for (i = 1; i < argc; i++) {
// note: skip argv[0] (program name)
*argp++ = (char*) strdup(argv[i]); // make a scratch copy
if (!strcmp(argv[i], SUPPRESS_DEPRECATE_MSG)) {
suppress_warning = true;
} else {
*argp++ = (char*) strdup(argv[i]); // make a scratch copy
}
}
*argp = null; // sentinel
envargc = envargs.length(); // report this count to next_arg
@ -293,6 +308,10 @@ int unpacker::run(int argc, char **argv) {
int verbose = 0;
char* logfile = null;
if (!suppress_warning) {
fprintf(u.errstrm, DEPRECATE_WARNING, nbasename(argv[0]));
}
for (;;) {
const char* arg = (*argp == null)? "": u.saveStr(*argp);
bool isenvarg = (argp < arg0);

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8199871
* @modules jdk.jartool
* @summary jar -n should print out deprecation warning
* @run testng DeprecateOptionN
*/
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.spi.ToolProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
public class DeprecateOptionN {
private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
.orElseThrow(() ->
new RuntimeException("jar tool not found")
);
protected static String jar(String... options) {
StringWriter writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
JAR_TOOL.run(pw, pw, options);
String output = writer.toString();
System.err.println(output);
return output;
}
@Test
public void helpCompatWithWarning() {
String output = jar("--help:compat");
assertTrue(output.contains("this option is deprecated, and is planned for removal in a future JDK release"));
}
@Test
public void helpExtraWithWarning() {
String output = jar("--help-extra");
assertTrue(output.contains("This option is deprecated, and is"));
assertTrue(output.contains("planned for removal in a future JDK release"));
}
@Test
public void normalizeWithWarning() throws IOException {
File tmp = File.createTempFile("test", null);
String output = jar("cnf", "test.jar", tmp.getAbsolutePath());
tmp.delete();
assertTrue(output.contains("Warning: The -n option is deprecated, and is planned for removal in a future JDK release"));
}
@Test
public void NoWarningWithoutN() throws IOException {
File tmp = File.createTempFile("test", null);
String output = jar("cf", "test.jar", tmp.getAbsolutePath());
tmp.delete();
assertFalse(output.contains("Warning: The -n option is deprecated, and is planned for removal in a future JDK release"));
}
@Test
public void SuppressWarning() throws IOException {
File tmp = File.createTempFile("test", null);
String output = jar("-c", "-n", "-XDsuppress-tool-removal-message",
"-f", "test.jar", tmp.getAbsolutePath());
tmp.delete();
assertFalse(output.contains("Warning: The -n option is deprecated, and is planned for removal in a future JDK release"));
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8199871
* @summary pack200 and unpack200 should print out deprecate warning
* @modules jdk.pack
* @compile -XDignore.symbol.file Utils.java
* @run testng DeprecatePack200
*/
import java.util.List;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
public class DeprecatePack200 {
final static String PACK200_CMD = Utils.getPack200Cmd();
final static String UNPACK200_CMD = Utils.getUnpack200Cmd();
final static Predicate<String> PACK200_MSG = Pattern.compile(
"Warning: The pack200(\\.exe)?? tool is deprecated, and is planned for removal in a future JDK release.")
.asMatchPredicate();
final static Predicate<String> UNPACK200_MSG = Pattern.compile(
"Warning: The unpack200(\\.exe)?? tool is deprecated, and is planned for removal in a future JDK release.")
.asMatchPredicate();
@DataProvider(name="tools")
public static final Object[][] provide() { return cases; }
private static final Object[][] cases = {
{ PACK200_MSG, 1, List.of(PACK200_CMD) },
{ PACK200_MSG, 1, List.of(PACK200_CMD, "-V") },
{ PACK200_MSG, 2, List.of(PACK200_CMD, "--help") },
{ PACK200_MSG, 0, List.of(PACK200_CMD, "-XDsuppress-tool-removal-message") },
{ PACK200_MSG, 0, List.of(PACK200_CMD, "--version", "-XDsuppress-tool-removal-message") },
{ PACK200_MSG, 0, List.of(PACK200_CMD, "-h", "-XDsuppress-tool-removal-message") },
{ UNPACK200_MSG, 1, List.of(UNPACK200_CMD) },
{ UNPACK200_MSG, 1, List.of(UNPACK200_CMD, "-V") },
{ UNPACK200_MSG, 1, List.of(UNPACK200_CMD, "--help") },
{ UNPACK200_MSG, 0, List.of(UNPACK200_CMD, "-XDsuppress-tool-removal-message") },
{ UNPACK200_MSG, 0, List.of(UNPACK200_CMD, "--version", "-XDsuppress-tool-removal-message") },
{ UNPACK200_MSG, 0, List.of(UNPACK200_CMD, "-h", "-XDsuppress-tool-removal-message") }
};
@Test(dataProvider = "tools")
public void CheckWarnings(Predicate<String> msg, long count, List<String> cmd) {
List<String> output = Utils.runExec(cmd, null, true);
assertEquals(output.stream().filter(msg).count(), count);
}
}

View File

@ -497,6 +497,10 @@ class Utils {
}
static List<String> runExec(List<String> cmdsList, Map<String, String> penv) {
return runExec(cmdsList, penv, false);
}
static List<String> runExec(List<String> cmdsList, Map<String, String> penv, boolean ignoreReturnValue) {
ArrayList<String> alist = new ArrayList<String>();
ProcessBuilder pb =
new ProcessBuilder(cmdsList);
@ -529,7 +533,7 @@ class Utils {
in = rd.readLine();
}
retval = p.waitFor();
if (retval != 0) {
if (!ignoreReturnValue && retval != 0) {
throw new RuntimeException("process failed with non-zero exit");
}
} catch (Exception ex) {