Remove support for the Java singlejar implementation. Fixes https://github.com/bazelbuild/bazel/issues/7365 PiperOrigin-RevId: 354917951
diff --git a/src/BUILD b/src/BUILD index e561cef..0ac483e 100644 --- a/src/BUILD +++ b/src/BUILD
@@ -602,7 +602,6 @@ "//src/java_tools/buildjar/java/com/google/devtools/build/java/turbine:turbine_direct_binary_deploy.jar", "//src/java_tools/junitrunner/java/com/google/testing/coverage:JacocoCoverage_jarjar_deploy.jar", "//src/java_tools/junitrunner/java/com/google/testing/junit/runner:Runner_deploy.jar", - "//src/java_tools/singlejar/java/com/google/devtools/build/singlejar:bazel-singlejar_deploy.jar", ] release_archive(
diff --git a/src/java_tools/junitrunner/java/com/google/testing/coverage/BUILD b/src/java_tools/junitrunner/java/com/google/testing/coverage/BUILD index efbb13d..398b48b 100644 --- a/src/java_tools/junitrunner/java/com/google/testing/coverage/BUILD +++ b/src/java_tools/junitrunner/java/com/google/testing/coverage/BUILD
@@ -69,13 +69,13 @@ cmd = "\n".join([ "JARJAR=\"$$(mktemp -t bazel.XXXXXXXX)\"", "\"$(JAVA)\" -jar \"$(location //third_party/jarjar:jarjar_command_deploy.jar)\" process \"$(location :JacocoCoverage.jarjar)\" \"$(location :JacocoCoverage_deploy.jar)\" \"$${JARJAR}\"", - "\"$(JAVA)\" -jar \"$(location //src/java_tools/singlejar:SingleJar_deploy.jar)\" --normalize --sources \"$${JARJAR}\" --output \"$@\"", + "\"$(location //src/tools/singlejar:singlejar)\" --normalize --sources \"$${JARJAR}\" --output \"$@\"", "rm -fr \"$${JARJAR}\"", ]), tags = ["manual"], toolchains = ["@bazel_tools//tools/jdk:current_host_java_runtime"], tools = [ - "//src/java_tools/singlejar:SingleJar_deploy.jar", + "//src/tools/singlejar", "//third_party/jarjar:jarjar_command_deploy.jar", "@bazel_tools//tools/jdk:current_host_java_runtime", ],
diff --git a/src/java_tools/singlejar/BUILD b/src/java_tools/singlejar/BUILD index 4eeae88..2f006b9 100644 --- a/src/java_tools/singlejar/BUILD +++ b/src/java_tools/singlejar/BUILD
@@ -27,25 +27,3 @@ actual = "//src/java_tools/singlejar/java/com/google/devtools/build/singlejar:libSingleJar", visibility = ["//visibility:public"], ) - -alias( - name = "SingleJar", - actual = "//src/java_tools/singlejar/java/com/google/devtools/build/singlejar:bazel-singlejar", - visibility = ["//visibility:public"], -) - -alias( - name = "SingleJar_deploy.jar", - actual = "//src/java_tools/singlejar/java/com/google/devtools/build/singlejar:bazel-singlejar_deploy.jar", - visibility = ["//visibility:public"], -) - -alias( - name = "bootstrap", - actual = "//src/java_tools/singlejar/java/com/google/devtools/build/singlejar:bootstrap", -) - -alias( - name = "bootstrap_deploy.jar", - actual = "//src/java_tools/singlejar/java/com/google/devtools/build/singlejar:bootstrap_deploy.jar", -)
diff --git a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/BUILD b/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/BUILD index b634901..0cc5de5 100644 --- a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/BUILD +++ b/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/BUILD
@@ -1,5 +1,4 @@ -load("@rules_java//java:defs.bzl", "java_binary", "java_library") -load("//tools/build_rules:java_rules_skylark.bzl", "bootstrap_java_binary", "bootstrap_java_library") +load("@rules_java//java:defs.bzl", "java_library") # Description: # SingleJar combines multiple zip files and additional files @@ -35,68 +34,3 @@ "//third_party:jsr305", ], ) - -java_library( - name = "libSingleJarMain", - srcs = glob(["**/*.java"]), - # Avoid adding dependencies here - this is a very low-level library and we don't want to pull in - # the world, even including commons. - deps = [ - "//src/java_tools/singlejar/java/com/google/devtools/build/zip", - "//src/main/java/com/google/devtools/build/lib/shell", - "//src/main/protobuf:desugar_deps_java_proto", - "//src/main/protobuf:worker_protocol_java_proto", - "//third_party:jsr305", - "//third_party/protobuf:protobuf_java", - ], -) - -java_binary( - name = "bazel-singlejar", - srcs = glob(["*.java"]), - main_class = "com.google.devtools.build.singlejar.SingleJar", - visibility = [ - "//:__subpackages__", - "//src/java_tools/singlejar:singlejar_package_group", - ], - deps = [ - "//src/java_tools/singlejar/java/com/google/devtools/build/zip", - "//src/main/java/com/google/devtools/build/lib/shell", - "//src/main/protobuf:desugar_deps_java_proto", - "//src/main/protobuf:worker_protocol_java_proto", - "//third_party:jsr305", - "//third_party/protobuf:protobuf_java", - ], -) - -# -# Bootstrapping using Starlark rules -# - -bootstrap_java_library( - name = "starlark-deps", - jars = [ - "//third_party:jsr305-jars", - ], - tags = ["manual"], -) - -bootstrap_java_binary( - name = "bootstrap", - srcs = glob( - ["**/*.java"], - exclude = [ - "Java8DesugarDepsJarEntryFilter.java", - "SingleJarWorker.java", - ], - ) + [ - "//src/java_tools/singlejar/java/com/google/devtools/build/zip:java-srcs", - ], - main_class = "com.google.devtools.build.singlejar.SingleJar", - tags = ["manual"], - visibility = ["//visibility:public"], - deps = [ - ":starlark-deps", - "//src/main/java/com/google/devtools/build/lib/shell:shell-starlark", - ], -)
diff --git a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/Java8DesugarDepsJarEntryFilter.java b/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/Java8DesugarDepsJarEntryFilter.java deleted file mode 100644 index 93c6cc7..0000000 --- a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/Java8DesugarDepsJarEntryFilter.java +++ /dev/null
@@ -1,144 +0,0 @@ -// Copyright 2018 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.singlejar; - -import com.google.devtools.build.android.desugar.proto.DesugarDeps.Dependency; -import com.google.devtools.build.android.desugar.proto.DesugarDeps.DesugarDepsInfo; -import com.google.devtools.build.android.desugar.proto.DesugarDeps.InterfaceDetails; -import com.google.devtools.build.android.desugar.proto.DesugarDeps.InterfaceWithCompanion; -import com.google.devtools.build.android.desugar.proto.DesugarDeps.Type; -import com.google.protobuf.ByteString; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * {@link ZipEntryFilter} that implements consistency checking of {@code META-INF/desugar_deps} - * files emitted by {@link com.google.devtools.build.android.desugar.Desugar}. This is used to - * implement singlejar's {@code --check_desugar_deps} flag. - */ -class Java8DesugarDepsJarEntryFilter - implements ZipEntryFilter, ZipEntryFilter.CustomMergeStrategy { - - private final Map<String, ByteString> neededDeps = new LinkedHashMap<>(); - private final Map<String, ByteString> missingInterfaces = new LinkedHashMap<>(); - private final Map<String, List<String>> extendedInterfaces = new HashMap<>(); - private final Map<String, Boolean> hasDefaultMethods = new HashMap<>(); - private final Set<String> seen = new HashSet<>(); - - private final ZipEntryFilter delegate; - - public Java8DesugarDepsJarEntryFilter(ZipEntryFilter delegate) { - this.delegate = delegate; - } - - @Override - public void accept(String filename, StrategyCallback callback) throws IOException { - if ("META-INF/desugar_deps".equals(filename)) { - callback.customMerge(null, this); - } else if (filename.startsWith("j$/")) { - throw new IOException("Unexpectedly found desugar_jdk_libs file: " + filename); - } else { - seen.add(filename); - delegate.accept(filename, callback); - } - } - - @Override - public void merge(InputStream in, OutputStream out) throws IOException { - DesugarDepsInfo depsInfo = DesugarDepsInfo.parseFrom(in); - for (Dependency assumed : depsInfo.getAssumePresentList()) { - neededDeps.putIfAbsent( - assumed.getTarget().getBinaryName() + ".class", - assumed.getOrigin().getBinaryNameBytes()); - } - for (Dependency missing : depsInfo.getMissingInterfaceList()) { - missingInterfaces.putIfAbsent( - missing.getTarget().getBinaryName(), - missing.getOrigin().getBinaryNameBytes()); - } - for (InterfaceDetails itf : depsInfo.getInterfaceWithSupertypesList()) { - if (itf.getExtendedInterfaceCount() > 0 - && !extendedInterfaces.containsKey(itf.getOrigin().getBinaryName())) { - // Avoid Guava dependency - ArrayList<String> supertypes = new ArrayList<>(itf.getExtendedInterfaceCount()); - for (Type extended : itf.getExtendedInterfaceList()) { - supertypes.add(extended.getBinaryName()); - } - extendedInterfaces.putIfAbsent(itf.getOrigin().getBinaryName(), supertypes); - } - } - for (InterfaceWithCompanion companion : depsInfo.getInterfaceWithCompanionList()) { - if (companion.getNumDefaultMethods() > 0) { - // Only remember interfaces that definitely have default methods for now. - // For all other interfaces we'll transitively check extended interfaces - // in HasDefaultMethods. - hasDefaultMethods.putIfAbsent(companion.getOrigin().getBinaryName(), true); - } - } - // Don't write anything to out, we just want to check these files for consistency - } - - @Override - public void finish(OutputStream out) throws IOException { - for (Map.Entry<String, ByteString> need : neededDeps.entrySet()) { - if (!seen.contains(need.getKey())) { - throw new IOException(need.getKey() + " referenced by " + need.getValue().toStringUtf8() - + " but not found. Is the former defined in a neverlink library?"); - } - } - - for (Map.Entry<String, ByteString> missing : missingInterfaces.entrySet()) { - if (hasDefaultMethods(missing.getKey())) { - throw new IOException(missing.getKey() - + " needed to desugar " - + missing.getValue().toStringUtf8() - + ". Please add a dependency to the former to the library containing the latter."); - } - } - // Don't write anything to out, we just want to check these files for consistency - } - - @Override - public boolean skipEmpty() { - return true; // We never want to write these files into the output Jar - } - - private boolean hasDefaultMethods(String itf) { - Boolean cached = hasDefaultMethods.putIfAbsent(itf, false); - if (cached != null) { - return cached; // Already in the map - } - - List<String> extended = extendedInterfaces.get(itf); - if (extended != null) { - for (String supertype : extended) { - if (hasDefaultMethods(supertype)) { - hasDefaultMethods.put(itf, true); - return true; - } - } - } - // We primed with false above in case of cycles so just return that - return false; - } -}
diff --git a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/JavaIoFileSystem.java b/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/JavaIoFileSystem.java deleted file mode 100644 index 878accd..0000000 --- a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/JavaIoFileSystem.java +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.singlejar; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * An implementation based on java.io. - */ -public final class JavaIoFileSystem implements SimpleFileSystem { - - @Override - public InputStream getInputStream(String filename) throws IOException { - return new FileInputStream(filename); - } - - @Override - public OutputStream getOutputStream(String filename) throws IOException { - return new FileOutputStream(filename); - } - - @Override - public File getFile(String filename) throws IOException { - return new File(filename); - } - - @Override - public boolean delete(String filename) { - return new File(filename).delete(); - } -} \ No newline at end of file
diff --git a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/OptionFileExpander.java b/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/OptionFileExpander.java deleted file mode 100644 index aa396b5..0000000 --- a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/OptionFileExpander.java +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.singlejar; - -import static java.nio.charset.StandardCharsets.ISO_8859_1; - -import com.google.devtools.build.lib.shell.ShellUtils; -import com.google.devtools.build.lib.shell.ShellUtils.TokenizationException; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.concurrent.Immutable; - -/** - * A utility class to parse option files and expand them. - */ -@Immutable -final class OptionFileExpander { - - /** - * An interface that allows injecting different implementations for reading - * files. This is mostly used for testing. - */ - interface OptionFileProvider { - - /** - * Opens a file for reading and returns an input stream. - */ - InputStream getInputStream(String filename) throws IOException; - } - - private final OptionFileProvider fileSystem; - - /** - * Creates an instance with the given option file provider. - */ - public OptionFileExpander(OptionFileProvider fileSystem) { - this.fileSystem = fileSystem; - } - - /** - * Pre-processes an argument list, expanding options of the form &at;filename - * to read in the content of the file and add it to the list of arguments. - * - * @param args the List of arguments to pre-process. - * @return the List of pre-processed arguments. - * @throws IOException if one of the files containing options cannot be read. - */ - public List<String> expandArguments(List<String> args) throws IOException { - List<String> expanded = new ArrayList<>(args.size()); - for (String arg : args) { - expandArgument(arg, expanded); - } - return expanded; - } - - /** - * Expands a single argument, expanding options &at;filename to read in - * the content of the file and add it to the list of processed arguments. - * - * @param arg the argument to pre-process. - * @param expanded the List of pre-processed arguments. - * @throws IOException if one of the files containing options cannot be read. - */ - private void expandArgument(String arg, List<String> expanded) throws IOException { - if (arg.startsWith("@")) { - try (InputStreamReader reader = - new InputStreamReader(fileSystem.getInputStream(arg.substring(1)), ISO_8859_1)) { - // TODO(bazel-team): This code doesn't handle escaped newlines correctly. - // ShellUtils doesn't support them either. - for (String line : readAllLines(reader)) { - List<String> parsedTokens = new ArrayList<>(); - try { - ShellUtils.tokenize(parsedTokens, line); - } catch (TokenizationException e) { - throw new IOException("Could not tokenize parameter file!", e); - } - for (String token : parsedTokens) { - expandArgument(token, expanded); - } - } - } - } else { - expanded.add(arg); - } - } - - private List<String> readAllLines(Reader in) throws IOException { - List<String> result = new ArrayList<>(); - BufferedReader reader = new BufferedReader(in); - String line; - while ((line = reader.readLine()) != null) { - result.add(line); - } - return result; - } -}
diff --git a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/PrefixListPathFilter.java b/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/PrefixListPathFilter.java deleted file mode 100644 index 7a3d661..0000000 --- a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/PrefixListPathFilter.java +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.singlejar; - -import com.google.devtools.build.singlejar.DefaultJarEntryFilter.PathFilter; - -import java.util.List; - -/** - * A predicate used to filter jar entries according to a list of path prefixes. - */ -final class PrefixListPathFilter implements PathFilter { - private final List<String> prefixes; - - public PrefixListPathFilter(List<String> prefixes) { - this.prefixes = prefixes; - } - - @Override - public boolean allowed(String path) { - for (String prefix : prefixes) { - if (path.startsWith(prefix)) { - return true; - } - } - return false; - } -} \ No newline at end of file
diff --git a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/SimpleFileSystem.java b/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/SimpleFileSystem.java deleted file mode 100644 index 300b4f5..0000000 --- a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/SimpleFileSystem.java +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.singlejar; - -import com.google.devtools.build.singlejar.OptionFileExpander.OptionFileProvider; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * A simple virtual file system interface. It's much simpler than the Blaze - * virtual file system and only to be used inside this package. - */ -public interface SimpleFileSystem extends OptionFileProvider { - - @Override - InputStream getInputStream(String filename) throws IOException; - - /** - * Opens a file for output and returns an output stream. If a file of that - * name already exists, it is overwritten. - */ - OutputStream getOutputStream(String filename) throws IOException; - - /** - * Returns the File object for this filename. - */ - File getFile(String filename) throws IOException; - - /** Delete the file with the given name and return whether deleting it was successful. */ - boolean delete(String filename); -} \ No newline at end of file
diff --git a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/SingleJar.java b/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/SingleJar.java deleted file mode 100644 index a9da39e..0000000 --- a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/SingleJar.java +++ /dev/null
@@ -1,469 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.singlejar; - -import static com.google.devtools.build.singlejar.ZipCombiner.DOS_EPOCH; - -import com.google.devtools.build.singlejar.DefaultJarEntryFilter.PathFilter; -import com.google.devtools.build.singlejar.ZipCombiner.OutputMode; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.jar.Attributes; -import java.util.jar.JarFile; -import java.util.jar.Manifest; -import javax.annotation.concurrent.NotThreadSafe; - -/** - * An application that emulates the existing SingleJar tool, using the {@link - * ZipCombiner} class. - */ -@NotThreadSafe -public class SingleJar { - - private static final byte NEWLINE_BYTE = (byte) '\n'; - private static final String MANIFEST_FILENAME = JarFile.MANIFEST_NAME; - private static final String BUILD_DATA_FILENAME = "build-data.properties"; - - private final SimpleFileSystem fileSystem; - - /** The input jar files we want to combine into the output jar. */ - private final List<String> inputJars = new ArrayList<>(); - - /** Additional resources to be added to the output jar. */ - private final List<String> resources = new ArrayList<>(); - - /** Additional class path resources to be added to the output jar. */ - private final List<String> classpathResources = new ArrayList<>(); - - /** The name of the output Jar file. */ - private String outputJar; - - /** A filter for what jar entries to include */ - private PathFilter allowedPaths = DefaultJarEntryFilter.ANY_PATH; - - /** Extra manifest contents. */ - private String extraManifestContent; - /** The main class - this is put into the manifest and also into the build info. */ - private String mainClass; - - /** - * Warn about duplicate resource files, and skip them. Default behavior is to - * give an error message. - */ - private boolean warnDuplicateFiles = false; - - /** Indicates whether to set all timestamps to a fixed value. */ - private boolean normalize = false; - private boolean checkDesugarDeps = false; - private OutputMode outputMode = OutputMode.FORCE_STORED; - - /** Whether to include build-data.properties file */ - protected boolean includeBuildData = true; - - /** List of build information properties files */ - protected List<String> buildInformationFiles = new ArrayList<>(); - - /** Extraneous build informations (key=value) */ - protected List<String> buildInformations = new ArrayList<>(); - - /** The (optional) native executable that will be prepended to this JAR. */ - private String launcherBin = null; - - // Only visible for testing. - protected SingleJar(SimpleFileSystem fileSystem) { - this.fileSystem = fileSystem; - } - - /** - * Creates a manifest and returns an input stream for its contents. - */ - private InputStream createManifest() throws IOException { - Manifest manifest = new Manifest(); - Attributes attributes = manifest.getMainAttributes(); - attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0"); - attributes.put(new Attributes.Name("Created-By"), "blaze-singlejar"); - if (mainClass != null) { - attributes.put(Attributes.Name.MAIN_CLASS, mainClass); - } - if (extraManifestContent != null) { - ByteArrayInputStream in = new ByteArrayInputStream(extraManifestContent.getBytes("UTF8")); - manifest.read(in); - } - ByteArrayOutputStream out = new ByteArrayOutputStream(); - manifest.write(out); - return new ByteArrayInputStream(out.toByteArray()); - } - - private InputStream createBuildData() throws IOException { - Properties properties = mergeBuildData(); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - properties.store(outputStream, null); - byte[] output = outputStream.toByteArray(); - // Properties#store() adds a timestamp comment as first line, delete it. - output = stripFirstLine(output); - return new ByteArrayInputStream(output); - } - - static byte[] stripFirstLine(byte[] output) { - int i = 0; - while (i < output.length && output[i] != NEWLINE_BYTE) { - i++; - } - if (i < output.length) { - output = Arrays.copyOfRange(output, i + 1, output.length); - } else { - output = new byte[0]; - } - return output; - } - - private Properties mergeBuildData() throws IOException { - Properties properties = new Properties(); - for (String fileName : buildInformationFiles) { - InputStream file = fileSystem.getInputStream(fileName); - if (file != null) { - properties.load(file); - } - } - - // extra properties - for (String info : buildInformations) { - String[] split = info.split("=", 2); - String key = split[0]; - String value = ""; - if (split.length > 1) { - value = split[1]; - } - properties.put(key, value); - } - - // finally add generic information - // TODO(b/28294322): do we need to resolve the path to be absolute or canonical? - properties.put("build.target", outputJar); - if (mainClass != null) { - properties.put("main.class", mainClass); - } - return properties; - } - - private String getName(String filename) { - int index = filename.lastIndexOf('/'); - return index < 0 ? filename : filename.substring(index + 1); - } - - // Only visible for testing. - protected int run(List<String> args) throws IOException { - List<String> expandedArgs = new OptionFileExpander(fileSystem).expandArguments(args); - processCommandlineArgs(expandedArgs); - InputStream buildInfo = createBuildData(); - - ZipCombiner combiner = null; - try (OutputStream out = fileSystem.getOutputStream(outputJar)) { - combiner = new ZipCombiner(outputMode, createEntryFilterHelper(), out); - if (launcherBin != null) { - combiner.prependExecutable(fileSystem.getInputStream(launcherBin)); - } - Date date = normalize ? ZipCombiner.DOS_EPOCH : null; - - // Add a manifest file. - JarUtils.addMetaInf(combiner, date); - combiner.addFile(MANIFEST_FILENAME, date, createManifest()); - - if (includeBuildData) { - // Add the build data file. - combiner.addFile(BUILD_DATA_FILENAME, date, buildInfo); - } - - // Copy the resources to the top level of the jar file. - for (String classpathResource : classpathResources) { - String entryName = getName(classpathResource); - if (warnDuplicateFiles && combiner.containsFile(entryName)) { - System.err.println("File " + entryName + " clashes with a previous file"); - continue; - } - combiner.addFile(entryName, date, fileSystem.getInputStream(classpathResource)); - } - - // Copy the resources into the jar file. - for (String resource : resources) { - String from; - String to; - int i = resource.indexOf(':'); - if (i < 0) { - to = from = resource; - } else { - from = resource.substring(0, i); - to = resource.substring(i + 1); - } - if (warnDuplicateFiles && combiner.containsFile(to)) { - System.err.println("File " + from + " at " + to + " clashes with a previous file"); - continue; - } - - // Add parent directory entries. - int idx = to.indexOf('/'); - while (idx != -1) { - String dir = to.substring(0, idx + 1); - if (!combiner.containsFile(dir)) { - combiner.addDirectory(dir, DOS_EPOCH); - } - idx = to.indexOf('/', idx + 1); - } - - combiner.addFile(to, date, fileSystem.getInputStream(from)); - } - - // Copy the jars into the jar file. - for (String inputJar : inputJars) { - File jar = fileSystem.getFile(inputJar); - combiner.addZip(jar); - } - - // Close the output file. If something goes wrong here, delete the file. - combiner.close(); - combiner = null; - } finally { - // This part is only executed if an exception occurred. - if (combiner != null) { - try { - // We may end up calling close twice, but that's ok. - combiner.close(); - } catch (IOException e) { - // There's already an exception in progress - this won't add any - // additional information. - } - // Ignore return value - there's already an exception in progress. - fileSystem.delete(outputJar); - } - } - return 0; - } - - private ZipEntryFilter createEntryFilterHelper() { - ZipEntryFilter result = createEntryFilter(normalize, allowedPaths); - if (checkDesugarDeps) { - // Invocation is done through reflection so that this code will work in bazel open source - // as well. SingleJar is used for bootstrap and thus can not depend on protos (used in - // Java8DesugarDepsJarEntryFilter). - try { - return (ZipEntryFilter) - Class.forName("com.google.devtools.build.singlejar.Java8DesugarDepsJarEntryFilter") - .getConstructor(ZipEntryFilter.class).newInstance(result); - } catch (ReflectiveOperationException e) { - throw new IllegalStateException("Couldn't instantiate desugar deps checker", e); - } - } else { - return (filename, callback) -> { - if ("META-INF/desugar_deps".equals(filename)) { - callback.skip(); // We never want these files in the output - } else { - result.accept(filename, callback); - } - }; - } - - } - - protected ZipEntryFilter createEntryFilter(boolean normalize, PathFilter allowedPaths) { - return new DefaultJarEntryFilter(normalize, allowedPaths); - } - - /** - * Collects the arguments for a command line flag until it finds a flag that - * starts with the terminatorPrefix. - * - * @param args - * @param startIndex the start index in the args to collect the flag arguments - * from - * @param flagArguments the collected flag arguments - * @param terminatorPrefix the terminator prefix to stop collecting of - * argument flags - * @return the index of the first argument that started with the - * terminatorPrefix - */ - private static int collectFlagArguments(List<String> args, int startIndex, - List<String> flagArguments, String terminatorPrefix) { - startIndex++; - while (startIndex < args.size()) { - String name = args.get(startIndex); - if (name.startsWith(terminatorPrefix)) { - return startIndex - 1; - } - flagArguments.add(name); - startIndex++; - } - return startIndex; - } - - /** - * Returns a single argument for a command line option. - * - * @throws IOException if no more arguments are available - */ - private static String getArgument(List<String> args, int i, String arg) throws IOException { - if (i + 1 < args.size()) { - return args.get(i + 1); - } - throw new IOException(arg + ": missing argument"); - } - - /** - * Processes the command line arguments. - * - * @throws IOException if one of the files containing options cannot be read - */ - protected void processCommandlineArgs(List<String> args) throws IOException { - List<String> manifestLines = new ArrayList<>(); - List<String> prefixes = new ArrayList<>(); - for (int i = 0; i < args.size(); i++) { - String arg = args.get(i); - if (arg.equals("--sources")) { - i = collectFlagArguments(args, i, inputJars, "--"); - } else if (arg.equals("--resources")) { - i = collectFlagArguments(args, i, resources, "--"); - } else if (arg.equals("--classpath_resources")) { - i = collectFlagArguments(args, i, classpathResources, "--"); - } else if (arg.equals("--deploy_manifest_lines")) { - i = collectFlagArguments(args, i, manifestLines, "--"); - } else if (arg.equals("--build_info_file")) { - buildInformationFiles.add(getArgument(args, i, arg)); - i++; - } else if (arg.equals("--extra_build_info")) { - buildInformations.add(getArgument(args, i, arg)); - i++; - } else if (arg.equals("--main_class")) { - mainClass = getArgument(args, i, arg); - i++; - } else if (arg.equals("--output")) { - outputJar = getArgument(args, i, arg); - i++; - } else if (arg.equals("--compression")) { - outputMode = OutputMode.FORCE_DEFLATE; - } else if (arg.equals("--dont_change_compression")) { - outputMode = OutputMode.DONT_CARE; - } else if (arg.equals("--normalize")) { - normalize = true; - } else if (arg.equals("--include_prefixes")) { - i = collectFlagArguments(args, i, prefixes, "--"); - } else if (arg.equals("--exclude_build_data")) { - includeBuildData = false; - } else if (arg.equals("--warn_duplicate_resources")) { - warnDuplicateFiles = true; - } else if (arg.equals("--java_launcher")) { - launcherBin = getArgument(args, i, arg); - i++; - } else if (arg.equals("--check_desugar_deps")) { - checkDesugarDeps = true; - } else { - throw new IOException("unknown option : '" + arg + "'"); - } - } - if (!manifestLines.isEmpty()) { - setExtraManifestContent(joinWithNewlines(manifestLines)); - } - if (!prefixes.isEmpty()) { - setPathPrefixes(prefixes); - } - } - - private String joinWithNewlines(Iterable<String> lines) { - StringBuilder result = new StringBuilder(); - Iterator<String> it = lines.iterator(); - if (it.hasNext()) { - result.append(it.next()); - } - while (it.hasNext()) { - result.append('\n'); - result.append(it.next()); - } - return result.toString(); - } - - private void setExtraManifestContent(String extraManifestContent) { - // The manifest content has to be terminated with a newline character - if (!extraManifestContent.endsWith("\n")) { - extraManifestContent = extraManifestContent + '\n'; - } - this.extraManifestContent = extraManifestContent; - } - - private void setPathPrefixes(List<String> prefixes) throws IOException { - if (prefixes.isEmpty()) { - throw new IOException( - "Empty set of path prefixes; cowardly refusing to emit an empty jar file"); - } - allowedPaths = new PrefixListPathFilter(prefixes); - } - - static int singleRun(String[] args) throws IOException { - SingleJar singlejar = new SingleJar(new JavaIoFileSystem()); - return singlejar.run(Arrays.asList(args)); - } - - public static void main(String[] args) { - if (shouldRunInWorker(args)) { - if (!canRunInWorker()) { - System.err.println("Asked to run in a worker, but no worker support"); - System.exit(1); - } - try { - runWorker(args); - } catch (Exception e) { - System.err.println("Error running worker : " + e.getMessage()); - System.exit(1); - } - return; - } - - try { - System.exit(singleRun(args)); - } catch (IOException e) { - System.err.println("SingleJar threw exception : " + e.getMessage()); - System.exit(1); - } - } - - private static void runWorker(String[] args) throws Exception { - // Invocation is done through reflection so that this code will work in bazel open source - // as well. SingleJar is used for bootstrap and thus can not depend on protos (used in - // SingleJarWorker). - Class<?> workerClass = Class.forName("com.google.devtools.build.singlejar.SingleJarWorker"); - workerClass.getMethod("main", String[].class).invoke(null, (Object) args); - } - - protected static boolean shouldRunInWorker(String[] args) { - return Arrays.asList(args).contains("--persistent_worker"); - } - - private static boolean canRunInWorker() { - try { - Class.forName("com.google.devtools.build.singlejar.SingleJarWorker"); - return true; - } catch (ClassNotFoundException e1) { - return false; - } - } - -}
diff --git a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/SingleJarWorker.java b/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/SingleJarWorker.java deleted file mode 100644 index 95554a8..0000000 --- a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/SingleJarWorker.java +++ /dev/null
@@ -1,101 +0,0 @@ -// Copyright 2016 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.singlejar; - -import com.google.devtools.build.lib.worker.WorkerProtocol.WorkRequest; -import com.google.devtools.build.lib.worker.WorkerProtocol.WorkResponse; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.nio.charset.StandardCharsets; - -/** - * A blaze worker to run {@link SingleJar} in a warm JVM process. - */ -public class SingleJarWorker { - - public static void main(String[] args) { - new SingleJarWorker().runWorker(); - } - - private PrintStream originalStdout; - private PrintStream originalSterr; - private ByteArrayOutputStream stdoutAndStderr; - - protected void runWorker() { - trapOutputs(); - - try { - dispatchWorkRequestsForever(); - } catch (IOException e) { - // IOException will only occur if System.in has been closed - // In that case we silently exit our process - } - } - - private void trapOutputs() { - originalStdout = System.out; - originalSterr = System.err; - stdoutAndStderr = new ByteArrayOutputStream(); - System.setErr(new PrintStream(stdoutAndStderr, true)); - System.setOut(new PrintStream(stdoutAndStderr, true)); - } - - private void dispatchWorkRequestsForever() throws IOException { - while (true) { - WorkRequest workRequest = WorkRequest.parseDelimitedFrom(System.in); - - String[] args = workRequest.getArgumentsList().toArray(new String[0]); - - int returnCode = runSingleJar(args); - - outputResult(returnCode); - } - } - - private void outputResult(int returnCode) throws IOException { - WorkResponse.newBuilder() - .setExitCode(returnCode) - .setOutput(new String(stdoutAndStderr.toByteArray(), StandardCharsets.UTF_8)) - .build() - .writeDelimitedTo(originalStdout); - - // Reset output streams, we are not simply calling reset on the BAOS since this will - // still keep the full buffer allocated. - stdoutAndStderr = new ByteArrayOutputStream(); - System.setErr(new PrintStream(stdoutAndStderr, true)); - System.setOut(new PrintStream(stdoutAndStderr, true)); - } - - private int runSingleJar(String[] args) { - try { - return singleRun(args); - } catch (IOException e) { - // Some IO failures are okay no need to quit the worker - System.err.println("SingleJar threw exception : " + e.getMessage()); - return 1; - } catch (Exception e) { - // We had an actual unexpected error, lets quit the worker - originalSterr.println("SingleJar threw an unexpected exception : " + e.getMessage()); - e.printStackTrace(originalSterr); - System.exit(1); - return 1; - } - } - - protected int singleRun(String[] args) throws Exception { - return SingleJar.singleRun(args); - } -}
diff --git a/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/BUILD b/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/BUILD index 19d3582..1e611dd 100644 --- a/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/BUILD +++ b/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/BUILD
@@ -10,7 +10,6 @@ srcs = glob(["*.java"]), deps = [ "//src/java_tools/singlejar/java/com/google/devtools/build/singlejar:libSingleJar", - "//src/java_tools/singlejar/java/com/google/devtools/build/singlejar:libSingleJarMain", "//src/java_tools/singlejar/java/com/google/devtools/build/zip", "//src/test/java/com/google/devtools/build/lib/testutil:TestSuite", "//third_party:guava",
diff --git a/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/FakeZipFile.java b/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/FakeZipFile.java index 9b4a2dc..ec49240 100644 --- a/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/FakeZipFile.java +++ b/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/FakeZipFile.java
@@ -18,7 +18,6 @@ import static com.google.common.truth.Truth.assertWithMessage; import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.devtools.build.singlejar.SingleJarTest.EntryMode; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -37,6 +36,12 @@ */ public final class FakeZipFile { + private enum EntryMode { + DONT_CARE, + EXPECT_DEFLATE, + EXPECT_STORED; + } + /** * Validates an input provided as a byte array. */
diff --git a/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/MockSimpleFileSystem.java b/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/MockSimpleFileSystem.java deleted file mode 100644 index 6ebef20..0000000 --- a/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/MockSimpleFileSystem.java +++ /dev/null
@@ -1,100 +0,0 @@ -// Copyright 2015 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.singlejar; - -import static com.google.common.truth.Truth.assertThat; -import static java.nio.charset.StandardCharsets.UTF_8; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; -import java.util.HashMap; -import java.util.Map; - -/** - * FileSystem for testing. FileSystem supports exactly one one OutputStream for filename - * specified in constructor. - * Workflow for using this class in tests are following: - * <ul> - * <li> Construct with exactly one outputFile. </li> - * <li> add some input files using method addFile </li> - * <li> check content of outputFile calling toByteArray </li> - * </ul> - */ -public final class MockSimpleFileSystem implements SimpleFileSystem { - - private final String outputFileName; - private ByteArrayOutputStream out; - private final Map<String, byte[]> files = new HashMap<>(); - - public MockSimpleFileSystem(String outputFileName) { - this.outputFileName = outputFileName; - } - - public void addFile(String name, byte[] content) { - files.put(name, content); - } - - public void addFile(String name, String content) { - files.put(name, content.getBytes(UTF_8)); - } - - @Override - public OutputStream getOutputStream(String filename) { - assertThat(filename).isEqualTo(outputFileName); - assertThat(out).isNull(); - out = new ByteArrayOutputStream(); - return out; - } - - @Override - public InputStream getInputStream(String filename) throws IOException { - byte[] data = files.get(filename); - if (data == null) { - throw new FileNotFoundException(); - } - return new ByteArrayInputStream(data); - } - - @Override - public File getFile(String filename) throws IOException { - byte[] data = files.get(filename); - if (data == null) { - throw new FileNotFoundException(); - } - File file = File.createTempFile(filename, null); - Files.copy(new ByteArrayInputStream(data), file.toPath(), StandardCopyOption.REPLACE_EXISTING); - return file; - } - - @Override - public boolean delete(String filename) { - assertThat(filename).isEqualTo(outputFileName); - assertThat(out).isNotNull(); - out = null; - return true; - } - - public byte[] toByteArray() { - assertThat(out).isNotNull(); - return out.toByteArray(); - } -}
diff --git a/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/OptionFileExpanderTest.java b/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/OptionFileExpanderTest.java deleted file mode 100644 index f6556b9..0000000 --- a/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/OptionFileExpanderTest.java +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2015 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.singlejar; - -import static com.google.common.truth.Truth.assertThat; -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.junit.Assert.assertThrows; - -import com.google.devtools.build.singlejar.OptionFileExpander.OptionFileProvider; -import java.io.ByteArrayInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Unit tests for {@link OptionFileExpander}. - */ -@RunWith(JUnit4.class) -public class OptionFileExpanderTest { - - private static class StoredOptionFileProvider implements OptionFileProvider { - - private Map<String, byte[]> availableFiles = new HashMap<>(); - - void addFile(String filename, String content) { - availableFiles.put(filename, content.getBytes(UTF_8)); - } - - @Override - public InputStream getInputStream(String filename) throws IOException { - byte[] result = availableFiles.get(filename); - if (result == null) { - throw new FileNotFoundException(); - } - return new ByteArrayInputStream(result); - } - } - - @Test - public void testNoExpansion() throws IOException { - OptionFileExpander expander = new OptionFileExpander(new StoredOptionFileProvider()); - assertThat(expander.expandArguments(Arrays.asList("--some", "option", "list"))) - .isEqualTo(Arrays.asList("--some", "option", "list")); - } - - @Test - public void testExpandSimpleOptionsFile() throws IOException { - StoredOptionFileProvider provider = new StoredOptionFileProvider(); - provider.addFile("options", "--some option list"); - OptionFileExpander expander = new OptionFileExpander(provider); - assertThat(expander.expandArguments(Arrays.asList("@options"))) - .isEqualTo(Arrays.asList("--some", "option", "list")); - } - - @Test - public void testIllegalOptionsFile() { - StoredOptionFileProvider provider = new StoredOptionFileProvider(); - provider.addFile("options", "'missing apostrophe"); - OptionFileExpander expander = new OptionFileExpander(provider); - assertThrows(IOException.class, () -> expander.expandArguments(Arrays.asList("@options"))); - } -}
diff --git a/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/PrefixListPathFilterTest.java b/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/PrefixListPathFilterTest.java deleted file mode 100644 index 030ae27..0000000 --- a/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/PrefixListPathFilterTest.java +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2015 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.singlejar; - -import static com.google.common.truth.Truth.assertWithMessage; - -import com.google.common.collect.ImmutableList; -import com.google.devtools.build.singlejar.DefaultJarEntryFilter.PathFilter; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Tests {@link PrefixListPathFilter}. - */ -@RunWith(JUnit4.class) -public class PrefixListPathFilterTest { - private PathFilter filter; - - @Test - public void testPrefixList() { - filter = new PrefixListPathFilter(ImmutableList.of("dir1", "dir/subdir")); - assertIncluded("dir1/file1"); - assertExcluded("dir2/file1"); - assertIncluded("dir/subdir/file1"); - assertExcluded("dir2/subdir/file1"); - assertExcluded("dir/othersub/file1"); - assertExcluded("dir3/file1"); - } - - private void assertExcluded(String path) { - assertWithMessage(path + " should have been excluded, but was included") - .that(filter.allowed(path)) - .isFalse(); - } - - private void assertIncluded(String path) { - assertWithMessage(path + " should have been included but was not") - .that(filter.allowed(path)) - .isTrue(); - } -}
diff --git a/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/SingleJarTest.java b/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/SingleJarTest.java deleted file mode 100644 index 688ec14..0000000 --- a/src/java_tools/singlejar/javatests/com/google/devtools/build/singlejar/SingleJarTest.java +++ /dev/null
@@ -1,648 +0,0 @@ -// Copyright 2015 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.singlejar; - -import static com.google.common.truth.Truth.assertThat; -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.junit.Assert.assertThrows; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; -import com.google.devtools.build.singlejar.FakeZipFile.ByteValidator; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.jar.JarFile; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Unit tests for {@link SingleJar}. - */ -@RunWith(JUnit4.class) -public class SingleJarTest { - - public static final byte[] EXTRA_FOR_META_INF = new byte[] {(byte) 0xFE, (byte) 0xCA, 0x00, 0x00}; - - static final Joiner LINE_JOINER = Joiner.on("\r\n"); - static final Joiner LINEFEED_JOINER = Joiner.on("\n"); - - static enum EntryMode { - DONT_CARE, EXPECT_DEFLATE, EXPECT_STORED; - } - - public static final class BuildInfoValidator implements ByteValidator { - private final List<String> buildInfoLines; - - public BuildInfoValidator(List<String> buildInfoLines) { - this.buildInfoLines = buildInfoLines; - } - - @Override - public void validate(byte[] content) { - String actualBuildInfo = new String(content, StandardCharsets.UTF_8); - List<String> expectedBuildInfos = new ArrayList<>(); - for (String line : buildInfoLines) { // the character : is escaped - expectedBuildInfos.add(line.replace(":", "\\:")); - } - Collections.sort(expectedBuildInfos); - String[] actualBuildInfos = actualBuildInfo.split("\n"); - Arrays.sort(actualBuildInfos); - assertThat(LINEFEED_JOINER.join(actualBuildInfos)) - .isEqualTo(LINEFEED_JOINER.join(expectedBuildInfos)); - } - - } - - // Manifest file line ordering is dependent of the ordering in HashMap (Attributes class) so - // we do a sorted comparison for Manifest. - public static final class ManifestValidator implements ByteValidator { - private final List<String> manifestLines; - - public ManifestValidator(List<String> manifestLines) { - this.manifestLines = new ArrayList<>(manifestLines); - Collections.sort(this.manifestLines); - } - - public ManifestValidator(String... manifestLines) { - this.manifestLines = Arrays.asList(manifestLines); - Collections.sort(this.manifestLines); - } - - @Override - public void validate(byte[] content) { - String actualManifest = new String(content, StandardCharsets.UTF_8); - String[] actualManifestLines = actualManifest.trim().split("\r\n"); - Arrays.sort(actualManifestLines); - assertThat(LINEFEED_JOINER.join(actualManifestLines)) - .isEqualTo(LINEFEED_JOINER.join(manifestLines)); - } - - } - - private BuildInfoValidator redactedBuildData(String outputJar) { - return new BuildInfoValidator(ImmutableList.of("build.target=" + outputJar)); - } - - private BuildInfoValidator redactedBuildData(String outputJar, String mainClass) { - return new BuildInfoValidator( - ImmutableList.of("build.target=" + outputJar, "main.class=" + mainClass)); - } - - static List<String> getBuildInfo() { - return ImmutableList.of("build.build_id=11111-222-33333", - "build.version=12659499", - "build.location=user@machine.domain.com:/home/user/source", - "build.target=output.jar", - "build.time=Fri Jan 2 02:17:36 1970 (123456)", - "build.timestamp=Fri Jan 2 02:17:36 1970 (123456)", - "build.timestamp.as.int=123456" - ); - } - - private byte[] sampleZip() { - ZipFactory factory = new ZipFactory(); - factory.addFile("hello.txt", "Hello World!"); - return factory.toByteArray(); - } - - private byte[] sampleUncompressedZip() { - ZipFactory factory = new ZipFactory(); - factory.addFile("hello.txt", "Hello World!", false); - return factory.toByteArray(); - } - - private byte[] sampleZipWithSF() { - ZipFactory factory = new ZipFactory(); - factory.addFile("hello.SF", "Hello World!"); - return factory.toByteArray(); - } - - private byte[] sampleZipWithSubdirs() { - ZipFactory factory = new ZipFactory(); - factory.addFile("dir1/file1", "contents11"); - factory.addFile("dir1/file2", "contents12"); - factory.addFile("dir2/file1", "contents21"); - factory.addFile("dir3/file1", "contents31"); - return factory.toByteArray(); - } - - private void assertStripFirstLine(String expected, String testCase) { - byte[] result = SingleJar.stripFirstLine(testCase.getBytes(StandardCharsets.UTF_8)); - assertThat(new String(result, UTF_8)).isEqualTo(expected); - } - - @Test - public void testStripFirstLine() { - assertStripFirstLine("", ""); - assertStripFirstLine("", "no linefeed"); - assertStripFirstLine(LINEFEED_JOINER.join("toto", "titi"), - LINEFEED_JOINER.join("# timestamp comment", "toto", "titi")); - assertStripFirstLine(LINE_JOINER.join("toto", "titi"), - LINE_JOINER.join("# timestamp comment", "toto", "titi")); - } - - @Test - public void testEmptyJar() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar")) - .addEntry("build-data.properties", redactedBuildData("output.jar")); - expectedResult.assertSame(mockFs.toByteArray()); - } - - // Test that two identical calls at different time actually returns identical results - @Test - public void testDeterministicJar() throws IOException, InterruptedException { - MockSimpleFileSystem mockFs1 = new MockSimpleFileSystem("output.jar"); - SingleJar singleJar1 = new SingleJar(mockFs1); - singleJar1.run(ImmutableList.of("--output", "output.jar", "--extra_build_info", "toto=titi", - "--normalize")); - Thread.sleep(1000); // ensure that we are not at the same seconds - - MockSimpleFileSystem mockFs2 = new MockSimpleFileSystem("output.jar"); - SingleJar singleJar2 = new SingleJar(mockFs2); - singleJar2.run(ImmutableList.of("--output", "output.jar", "--extra_build_info", "toto=titi", - "--normalize")); - - FakeZipFile.assertSame(mockFs1.toByteArray(), mockFs2.toByteArray()); - } - - @Test - public void testExtraManifestContent() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--deploy_manifest_lines", - "Main-Class: SomeClass", "X-Other: Duh")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar", - "Main-Class: SomeClass", - "X-Other: Duh")) - .addEntry("build-data.properties", redactedBuildData("output.jar")); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testMultipleExtraManifestContent() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--deploy_manifest_lines", "X-Other: Duh", - "--output", "output.jar", - "--deploy_manifest_lines", "Main-Class: SomeClass")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar", - "Main-Class: SomeClass", - "X-Other: Duh")) - .addEntry("build-data.properties", redactedBuildData("output.jar")); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testMainClass() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--main_class", "SomeClass")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar", - "Main-Class: SomeClass")) - .addEntry("build-data.properties", redactedBuildData("output.jar", "SomeClass")); - expectedResult.assertSame(mockFs.toByteArray()); - } - - // These four tests test all combinations of compressed/uncompressed input and output. - @Test - public void testSimpleZip() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("test.jar", sampleZip()); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--sources", "test.jar")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF, false) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar"), false) - .addEntry("build-data.properties", redactedBuildData("output.jar"), false) - .addEntry("hello.txt", "Hello World!", false); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testSimpleZipExpectCompressedOutput() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("test.jar", sampleZip()); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--sources", "test.jar", - "--compression")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF, false) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar"), true) - .addEntry("build-data.properties", redactedBuildData("output.jar"), true) - .addEntry("hello.txt", "Hello World!", true); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testSimpleUncompressedZip() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("test.jar", sampleUncompressedZip()); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--sources", "test.jar")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF, false) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator(ImmutableList.of( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar")), false) - .addEntry("build-data.properties", redactedBuildData("output.jar"), false) - .addEntry("hello.txt", "Hello World!", false); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testSimpleUncompressedZipExpectCompressedOutput() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("test.jar", sampleUncompressedZip()); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--sources", "test.jar", - "--compression")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF, false) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar"), true) - .addEntry("build-data.properties", redactedBuildData("output.jar"), true) - .addEntry("hello.txt", "Hello World!", true); - expectedResult.assertSame(mockFs.toByteArray()); - } - - // Integration test for option file expansion. - @Test - public void testOptionFile() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("input.jar", sampleZip()); - mockFs.addFile("options", "--output output.jar --sources input.jar"); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("@options")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar")) - .addEntry("build-data.properties", redactedBuildData("output.jar")) - .addEntry("hello.txt", "Hello World!"); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testSkipsSignatureFiles() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("input.jar", sampleZipWithSF()); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--sources", "input.jar")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar")) - .addEntry("build-data.properties", redactedBuildData("output.jar")); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testSkipsUsingInputPrefixes() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("input.jar", sampleZipWithSubdirs()); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--sources", - "input.jar", "--include_prefixes", "dir1", "dir2")); - - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar")) - .addEntry("build-data.properties", redactedBuildData("output.jar")) - .addEntry("dir1/file1", "contents11") - .addEntry("dir1/file2", "contents12") - .addEntry("dir2/file1", "contents21"); - - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testSkipsUsingMultipleInputPrefixes() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("input.jar", sampleZipWithSubdirs()); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--include_prefixes", "dir2", - "--sources", "input.jar", "--include_prefixes", "dir1")); - - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar")) - .addEntry("build-data.properties", redactedBuildData("output.jar")) - .addEntry("dir1/file1", "contents11") - .addEntry("dir1/file2", "contents12") - .addEntry("dir2/file1", "contents21"); - - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testNormalize() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("input.jar", sampleZip()); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--sources", "input.jar", - "--normalize")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF, false) - .addEntry(JarFile.MANIFEST_NAME, ZipCombiner.DOS_EPOCH, new ManifestValidator( - "Manifest-Version: 1.0", "Created-By: blaze-singlejar"), false) - .addEntry("build-data.properties", ZipCombiner.DOS_EPOCH, - redactedBuildData("output.jar"), false) - .addEntry("hello.txt", ZipCombiner.DOS_EPOCH, "Hello World!", false); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testNormalizeAndCompress() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("input.jar", sampleZip()); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--sources", "input.jar", - "--normalize", "--compression")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF, false) - .addEntry(JarFile.MANIFEST_NAME, ZipCombiner.DOS_EPOCH, new ManifestValidator( - "Manifest-Version: 1.0", "Created-By: blaze-singlejar"), true) - .addEntry("build-data.properties", ZipCombiner.DOS_EPOCH, - redactedBuildData("output.jar"), true) - .addEntry("hello.txt", ZipCombiner.DOS_EPOCH, "Hello World!", true); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testAddBuildInfoProperties() throws IOException { - List<String> buildInfo = getBuildInfo(); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF, false) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", "Created-By: blaze-singlejar"), false) - .addEntry("build-data.properties", new BuildInfoValidator(buildInfo), - false); - - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - SingleJar singleJar = new SingleJar(mockFs); - List<String> args = new ArrayList<>(); - args.add("--output"); - args.add("output.jar"); - args.addAll(infoPropertyArguments(buildInfo)); - singleJar.run(args); - expectedResult.assertSame(mockFs.toByteArray()); - } - - private static List<String> infoPropertyArguments(List<String> buildInfoLines) { - List<String> args = new ArrayList<>(); - for (String s : buildInfoLines) { - if (!s.isEmpty()) { - args.add("--extra_build_info"); - args.add(s); - } - } - return args; - } - - @Test - public void testAddBuildInfoPropertiesFile() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - SingleJar singleJar = new SingleJar(mockFs); - doTestAddBuildInfoPropertiesFile(mockFs, "output.jar", singleJar); - } - - public static void doTestAddBuildInfoPropertiesFile(MockSimpleFileSystem mockFs, String target, - SingleJar singleJar) throws IOException { - List<String> buildInfo = getBuildInfo(); - mockFs.addFile("my.properties", makePropertyFileFromBuildInfo(buildInfo)); - singleJar.run(ImmutableList.of("--output", target, "--build_info_file", "my.properties")); - - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF, false) - .addEntry(JarFile.MANIFEST_NAME, - new ManifestValidator("Manifest-Version: 1.0", "Created-By: blaze-singlejar"), false) - .addEntry("build-data.properties", new BuildInfoValidator(buildInfo), - false); - expectedResult.assertSame(mockFs.toByteArray()); - } - - private static String makePropertyFileFromBuildInfo(List<String> buildInfo) { - return LINEFEED_JOINER.join(buildInfo).replace(":", "\\:"); - } - - @Test - public void testAddBuildInfoPropertiesFiles() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - SingleJar singleJar = new SingleJar(mockFs); - doTestAddBuildInfoPropertiesFiles(mockFs, "output.jar", singleJar); - } - - public static void doTestAddBuildInfoPropertiesFiles(MockSimpleFileSystem mockFs, String target, - SingleJar singleJar) throws IOException { - List<String> buildInfo = getBuildInfo(); - - mockFs.addFile("my1.properties", makePropertyFileFromBuildInfo(buildInfo.subList(0, 4))); - mockFs.addFile("my2.properties", - makePropertyFileFromBuildInfo(buildInfo.subList(4, buildInfo.size()))); - singleJar.run(ImmutableList.of("--output", target, - "--build_info_file", "my1.properties", - "--build_info_file", "my2.properties")); - - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF, false) - .addEntry(JarFile.MANIFEST_NAME, - new ManifestValidator("Manifest-Version: 1.0", "Created-By: blaze-singlejar"), false) - .addEntry("build-data.properties", new BuildInfoValidator(buildInfo), - false); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testAddBuildInfoPropertiesAndFiles() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - SingleJar singleJar = new SingleJar(mockFs); - doTestAddBuildInfoPropertiesAndFiles(mockFs, "output.jar", singleJar); - } - - public static void doTestAddBuildInfoPropertiesAndFiles(MockSimpleFileSystem mockFs, - String target, SingleJar singleJar) throws IOException { - List<String> buildInfo = getBuildInfo(); - - mockFs.addFile("my1.properties", makePropertyFileFromBuildInfo(buildInfo.subList(0, 4))); - mockFs.addFile("my2.properties", makePropertyFileFromBuildInfo( - buildInfo.subList(4, buildInfo.size()))); - List<String> args = ImmutableList.<String>builder() - .add("--output").add(target) - .add("--build_info_file").add("my1.properties") - .add("--build_info_file").add("my2.properties") - .addAll(infoPropertyArguments(buildInfo.subList(4, buildInfo.size()))) - .build(); - - singleJar.run(args); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF, false) - .addEntry(JarFile.MANIFEST_NAME, - new ManifestValidator("Manifest-Version: 1.0", "Created-By: blaze-singlejar"), false) - .addEntry("build-data.properties", new BuildInfoValidator(buildInfo), - false); - expectedResult.assertSame(mockFs.toByteArray()); - } - - - @Test - public void testExcludeBuildData() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - SingleJar singleJar = new SingleJar(mockFs); - doTestExcludeBuildData(mockFs, "output.jar", singleJar); - } - - public static void doTestExcludeBuildData(MockSimpleFileSystem mockFs, String target, - SingleJar singleJar) throws IOException { - singleJar.run(ImmutableList.of("--output", target, "--exclude_build_data")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar")); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testResourceMapping() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("a/b/c", "Test"); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--exclude_build_data", - "--resources", "a/b/c:c/b/a")); - FakeZipFile expectedResult = new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry(JarFile.MANIFEST_NAME, new ManifestValidator( - "Manifest-Version: 1.0", - "Created-By: blaze-singlejar")) - .addEntry("c/", (String) null) - .addEntry("c/b/", (String) null) - .addEntry("c/b/a", "Test"); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testResourceMappingIdentity() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("a/b/c", "Test"); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--exclude_build_data", - "--resources", "a/b/c")); - FakeZipFile expectedResult = - new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry( - JarFile.MANIFEST_NAME, - new ManifestValidator("Manifest-Version: 1.0", "Created-By: blaze-singlejar")) - .addEntry("a/", (String) null) - .addEntry("a/b/", (String) null) - .addEntry("a/b/c", "Test"); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testResourceMappingDuplicateError() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("a/b/c", "Test"); - SingleJar singleJar = new SingleJar(mockFs); - IllegalArgumentException e = - assertThrows( - IllegalArgumentException.class, - () -> - singleJar.run( - ImmutableList.of( - "--output", - "output.jar", - "--exclude_build_data", - "--resources", - "a/b/c", - "a/b/c"))); - assertThat(e).hasMessageThat().contains("already contains a file named 'a/b/c'."); - } - - @Test - public void testResourceMappingDuplicateWarning() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - mockFs.addFile("a/b/c", "Test"); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", "--exclude_build_data", - "--warn_duplicate_resources", "--resources", "a/b/c", "a/b/c")); - FakeZipFile expectedResult = - new FakeZipFile() - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry( - JarFile.MANIFEST_NAME, - new ManifestValidator("Manifest-Version: 1.0", "Created-By: blaze-singlejar")) - .addEntry("a/", (String) null) - .addEntry("a/b/", (String) null) - .addEntry("a/b/c", "Test"); - expectedResult.assertSame(mockFs.toByteArray()); - } - - @Test - public void testCanAddPreamble() throws IOException { - MockSimpleFileSystem mockFs = new MockSimpleFileSystem("output.jar"); - String preamble = "WeThePeople"; - mockFs.addFile(preamble, preamble.getBytes(UTF_8)); - SingleJar singleJar = new SingleJar(mockFs); - singleJar.run(ImmutableList.of("--output", "output.jar", - "--java_launcher", preamble, - "--main_class", "SomeClass")); - FakeZipFile expectedResult = - new FakeZipFile() - .addPreamble(preamble.getBytes(UTF_8)) - .addEntry("META-INF/", EXTRA_FOR_META_INF) - .addEntry( - JarFile.MANIFEST_NAME, - new ManifestValidator("Manifest-Version: 1.0", "Created-By: blaze-singlejar", - "Main-Class: SomeClass")) - .addEntry("build-data.properties", redactedBuildData("output.jar", "SomeClass")); - expectedResult.assertSame(mockFs.toByteArray()); - } -}
diff --git a/src/test/java/com/google/devtools/build/android/desugar/BUILD b/src/test/java/com/google/devtools/build/android/desugar/BUILD index 2131b58..5364c7c 100644 --- a/src/test/java/com/google/devtools/build/android/desugar/BUILD +++ b/src/test/java/com/google/devtools/build/android/desugar/BUILD
@@ -1881,7 +1881,6 @@ _SINGLEJAR_IMPLS = { "singlejar": "//src/tools/singlejar:singlejar_local", - "JavaSingleJar": "//src/java_tools/singlejar:SingleJar", } [sh_test(
diff --git a/tools/jdk/BUILD.java_tools b/tools/jdk/BUILD.java_tools index 78fb5e1..5c25858 100644 --- a/tools/jdk/BUILD.java_tools +++ b/tools/jdk/BUILD.java_tools
@@ -51,11 +51,6 @@ ) filegroup( - name = "SingleJar", - srcs = ["java_tools/bazel-singlejar_deploy.jar"], -) - -filegroup( name = "Turbine", srcs = ["java_tools/turbine_deploy.jar"], )
diff --git a/tools/jdk/BUILD.tools b/tools/jdk/BUILD.tools index f5c3154..2e948d9 100644 --- a/tools/jdk/BUILD.tools +++ b/tools/jdk/BUILD.tools
@@ -230,11 +230,6 @@ ) alias( - name = "bazel-singlejar_deploy.jar", - actual = "@remote_java_tools//:SingleJar", -) - -alias( name = "turbine", actual = "@remote_java_tools//:Turbine", )