Repository: accumulo Updated Branches: refs/heads/master cf69e3f67 -> c2778b8af
ACCUMULO-4604 Improve 'accumulo classpath' command * Default output is now colon seperated jars on one line * Added '-d' option to print old human readable format * Improved usage for accumulo script commands Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/c2778b8a Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/c2778b8a Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/c2778b8a Branch: refs/heads/master Commit: c2778b8afaacb3c548b14993d5a6ae919adfe39b Parents: cf69e3f Author: Mike Walch <mwa...@apache.org> Authored: Fri Mar 10 15:27:21 2017 -0500 Committer: Mike Walch <mwa...@apache.org> Committed: Wed Mar 22 09:48:08 2017 -0400 ---------------------------------------------------------------------- assemble/bin/accumulo | 5 +- assemble/conf/templates/accumulo-env.sh | 2 +- .../accumulo/core/file/rfile/PrintInfo.java | 2 +- .../apache/accumulo/core/util/Classpath.java | 14 ++++- .../apache/accumulo/core/util/CreateToken.java | 2 +- docs/src/main/asciidoc/chapters/clients.txt | 18 +++--- .../apache/accumulo/server/init/Initialize.java | 2 +- .../org/apache/accumulo/server/util/Admin.java | 2 +- .../shell/commands/ClasspathCommand.java | 16 ++---- .../java/org/apache/accumulo/start/Main.java | 2 +- .../classloader/vfs/AccumuloVFSClassLoader.java | 59 +++++++++++++------- .../classloader/vfs/AccumuloClasspathTest.java | 48 ++++++++++++++++ 12 files changed, 122 insertions(+), 50 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/accumulo/blob/c2778b8a/assemble/bin/accumulo ---------------------------------------------------------------------- diff --git a/assemble/bin/accumulo b/assemble/bin/accumulo index bbd2b91..5dd96e2 100755 --- a/assemble/bin/accumulo +++ b/assemble/bin/accumulo @@ -83,10 +83,7 @@ function main() { CLASSPATH="${conf}:${lib}/*:${CLASSPATH}" export CLASSPATH - exec "${JAVA[@]}" \ - "${JAVA_OPTS[@]}" \ - org.apache.accumulo.start.Main \ - "$@" + exec "${JAVA[@]}" "${JAVA_OPTS[@]}" org.apache.accumulo.start.Main "$@" } main "$@" http://git-wip-us.apache.org/repos/asf/accumulo/blob/c2778b8a/assemble/conf/templates/accumulo-env.sh ---------------------------------------------------------------------- diff --git a/assemble/conf/templates/accumulo-env.sh b/assemble/conf/templates/accumulo-env.sh index 2985402..64b8294 100644 --- a/assemble/conf/templates/accumulo-env.sh +++ b/assemble/conf/templates/accumulo-env.sh @@ -51,7 +51,7 @@ JAVA_OPTS=("${ACCUMULO_JAVA_OPTS[@]}" "-Daccumulo.native.lib.path=${lib}/native") ## Make sure Accumulo native libraries are built since they are enabled by default -${bin}/accumulo-util build-native &> /dev/null +"${bin}"/accumulo-util build-native &> /dev/null ## JVM options set for individual applications case "$cmd" in http://git-wip-us.apache.org/repos/asf/accumulo/blob/c2778b8a/core/src/main/java/org/apache/accumulo/core/file/rfile/PrintInfo.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/file/rfile/PrintInfo.java b/core/src/main/java/org/apache/accumulo/core/file/rfile/PrintInfo.java index d17528c..b947a7e 100644 --- a/core/src/main/java/org/apache/accumulo/core/file/rfile/PrintInfo.java +++ b/core/src/main/java/org/apache/accumulo/core/file/rfile/PrintInfo.java @@ -124,7 +124,7 @@ public class PrintInfo implements KeywordExecutable { @Override public void execute(final String[] args) throws Exception { Opts opts = new Opts(); - opts.parseArgs(PrintInfo.class.getName(), args); + opts.parseArgs("accumulo rfile-info", args); if (opts.files.isEmpty()) { System.err.println("No files were given"); System.exit(-1); http://git-wip-us.apache.org/repos/asf/accumulo/blob/c2778b8a/core/src/main/java/org/apache/accumulo/core/util/Classpath.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/util/Classpath.java b/core/src/main/java/org/apache/accumulo/core/util/Classpath.java index 40f5ac7..66adb64 100644 --- a/core/src/main/java/org/apache/accumulo/core/util/Classpath.java +++ b/core/src/main/java/org/apache/accumulo/core/util/Classpath.java @@ -16,6 +16,7 @@ */ package org.apache.accumulo.core.util; +import com.beust.jcommander.Parameter; import org.apache.accumulo.start.Main; import org.apache.accumulo.start.spi.KeywordExecutable; @@ -23,6 +24,13 @@ import com.google.auto.service.AutoService; @AutoService(KeywordExecutable.class) public class Classpath implements KeywordExecutable { + + static class Opts extends org.apache.accumulo.core.cli.Help { + + @Parameter(names = {"-d", "--debug"}, description = "Turns on debugging") + public boolean debug = false; + } + @Override public String keyword() { return "classpath"; @@ -35,6 +43,10 @@ public class Classpath implements KeywordExecutable { @Override public void execute(final String[] args) throws Exception { - Main.getVFSClassLoader().getMethod("printClassPath").invoke(Main.getVFSClassLoader()); + + Opts opts = new Opts(); + opts.parseArgs("accumulo classpath", args); + + Main.getVFSClassLoader().getMethod("printClassPath", boolean.class).invoke(Main.getVFSClassLoader(), opts.debug); } } http://git-wip-us.apache.org/repos/asf/accumulo/blob/c2778b8a/core/src/main/java/org/apache/accumulo/core/util/CreateToken.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/util/CreateToken.java b/core/src/main/java/org/apache/accumulo/core/util/CreateToken.java index 005b5ba..d51ba28 100644 --- a/core/src/main/java/org/apache/accumulo/core/util/CreateToken.java +++ b/core/src/main/java/org/apache/accumulo/core/util/CreateToken.java @@ -85,7 +85,7 @@ public class CreateToken implements KeywordExecutable { @Override public void execute(String[] args) { Opts opts = new Opts(); - opts.parseArgs(CreateToken.class.getName(), args); + opts.parseArgs("accumulo create-token", args); Password pass = opts.password; if (pass == null && opts.securePassword != null) { http://git-wip-us.apache.org/repos/asf/accumulo/blob/c2778b8a/docs/src/main/asciidoc/chapters/clients.txt ---------------------------------------------------------------------- diff --git a/docs/src/main/asciidoc/chapters/clients.txt b/docs/src/main/asciidoc/chapters/clients.txt index 6e0909b..a18ab91 100644 --- a/docs/src/main/asciidoc/chapters/clients.txt +++ b/docs/src/main/asciidoc/chapters/clients.txt @@ -26,15 +26,15 @@ of the different ways to execute client code. ==== Using the java command -To run Accumulo client code using the +java+ command, you will need to -include the jars that Accumulo depends on in your classpath. Accumulo client -code depends on Hadoop and Zookeeper. For Hadoop add the hadoop client jar, all -of the jars in the Hadoop lib directory, and the conf directory to the -classpath. For recent Zookeeper versions, you only need to add the Zookeeper jar, and not -what is in the Zookeeper lib directory. You can run the following command on a -configured Accumulo system to see what its using for its classpath. - - accumulo classpath +To run Accumulo client code using the +java+ command, use the +accumulo classpath+ command +to include all of Accumulo's dependencies on your classpath: + + java -classpath /path/to/my.jar:/path/to/dep.jar:$(accumulo classpath) com.my.Main arg1 arg2 + +If you would like to review which jars are included, the +accumulo classpath+ command can +output a more human readable format using the +-d+ option which enables debugging: + + accumulo classpath -d ==== Using the accumulo command http://git-wip-us.apache.org/repos/asf/accumulo/blob/c2778b8a/server/base/src/main/java/org/apache/accumulo/server/init/Initialize.java ---------------------------------------------------------------------- diff --git a/server/base/src/main/java/org/apache/accumulo/server/init/Initialize.java b/server/base/src/main/java/org/apache/accumulo/server/init/Initialize.java index 35f18c6..347ac87 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/init/Initialize.java +++ b/server/base/src/main/java/org/apache/accumulo/server/init/Initialize.java @@ -758,7 +758,7 @@ public class Initialize implements KeywordExecutable { @Override public void execute(final String[] args) { Opts opts = new Opts(); - opts.parseArgs(Initialize.class.getName(), args); + opts.parseArgs("accumulo init", args); try { zoo = ZooReaderWriter.getInstance(); http://git-wip-us.apache.org/repos/asf/accumulo/blob/c2778b8a/server/base/src/main/java/org/apache/accumulo/server/util/Admin.java ---------------------------------------------------------------------- diff --git a/server/base/src/main/java/org/apache/accumulo/server/util/Admin.java b/server/base/src/main/java/org/apache/accumulo/server/util/Admin.java index b5bb118..a333c08 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/util/Admin.java +++ b/server/base/src/main/java/org/apache/accumulo/server/util/Admin.java @@ -169,7 +169,7 @@ public class Admin implements KeywordExecutable { AdminOpts opts = new AdminOpts(); JCommander cl = new JCommander(opts); - cl.setProgramName(Admin.class.getName()); + cl.setProgramName("accumulo admin"); CheckTabletsCommand checkTabletsCommand = new CheckTabletsCommand(); cl.addCommand("checkTablets", checkTabletsCommand); http://git-wip-us.apache.org/repos/asf/accumulo/blob/c2778b8a/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java ---------------------------------------------------------------------- diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java index 071571c..0cd1181 100644 --- a/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java +++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ClasspathCommand.java @@ -23,23 +23,19 @@ import jline.console.ConsoleReader; import org.apache.accumulo.shell.Shell; import org.apache.accumulo.shell.Shell.Command; import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader; -import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader.Printer; import org.apache.commons.cli.CommandLine; public class ClasspathCommand extends Command { @Override public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) { final ConsoleReader reader = shellState.getReader(); - AccumuloVFSClassLoader.printClassPath(new Printer() { - @Override - public void print(String s) { - try { - reader.println(s); - } catch (IOException ex) { - throw new RuntimeException(ex); - } + AccumuloVFSClassLoader.printClassPath(s -> { + try { + reader.print(s); + } catch (IOException ex) { + throw new RuntimeException(ex); } - }); + }, true); return 0; } http://git-wip-us.apache.org/repos/asf/accumulo/blob/c2778b8a/start/src/main/java/org/apache/accumulo/start/Main.java ---------------------------------------------------------------------- diff --git a/start/src/main/java/org/apache/accumulo/start/Main.java b/start/src/main/java/org/apache/accumulo/start/Main.java index ea2e1b8..f4c954d 100644 --- a/start/src/main/java/org/apache/accumulo/start/Main.java +++ b/start/src/main/java/org/apache/accumulo/start/Main.java @@ -205,7 +205,7 @@ public class Main { public static void printUsage() { Map<String,KeywordExecutable> executableMap = new TreeMap<>(getExecutables(getClassLoader())); - System.out.println("\nUsage: accumulo <command> (<argument> ...)\n\nCore Commands:"); + System.out.println("\nUsage: accumulo <command> [-h] (<argument> ...)\n\n -h Prints usage for specified command\n\nCore Commands:"); for (String cmd : Arrays.asList("init", "shell", "classpath", "version", "admin", "info", "help")) { printCommand(executableMap.remove(cmd)); } http://git-wip-us.apache.org/repos/asf/accumulo/blob/c2778b8a/start/src/main/java/org/apache/accumulo/start/classloader/vfs/AccumuloVFSClassLoader.java ---------------------------------------------------------------------- diff --git a/start/src/main/java/org/apache/accumulo/start/classloader/vfs/AccumuloVFSClassLoader.java b/start/src/main/java/org/apache/accumulo/start/classloader/vfs/AccumuloVFSClassLoader.java index 8e6a84b..fbc4a99 100644 --- a/start/src/main/java/org/apache/accumulo/start/classloader/vfs/AccumuloVFSClassLoader.java +++ b/start/src/main/java/org/apache/accumulo/start/classloader/vfs/AccumuloVFSClassLoader.java @@ -283,16 +283,27 @@ public class AccumuloVFSClassLoader { void print(String s); } - public static void printClassPath() { - printClassPath(new Printer() { - @Override - public void print(String s) { - System.out.println(s); - } - }); + public static void printClassPath(boolean debug) { + printClassPath(System.out::print, debug); + } + + public static String getClassPath(boolean debug) { + StringBuilder cp = new StringBuilder(); + printClassPath(s -> cp.append(s), debug); + return cp.toString(); } - public static void printClassPath(Printer out) { + private static void printJar(Printer out, String jarPath, boolean debug, boolean sawFirst) { + if (debug) + out.print("\t"); + if (!debug && sawFirst) + out.print(":"); + out.print(jarPath); + if (debug) + out.print("\n"); + } + + public static void printClassPath(Printer out, boolean debug) { try { ClassLoader cl = getClassLoader(); ArrayList<ClassLoader> classloaders = new ArrayList<>(); @@ -307,12 +318,17 @@ public class AccumuloVFSClassLoader { int level = 0; for (ClassLoader classLoader : classloaders) { - if (level > 0) - out.print(""); + level++; - String classLoaderDescription; + if (debug && level > 1) { + out.print("\n"); + } + if (!debug && level < 2) { + continue; + } + String classLoaderDescription; switch (level) { case 1: classLoaderDescription = level + ": Java System Classloader (loads Java system resources)"; @@ -332,25 +348,28 @@ public class AccumuloVFSClassLoader { break; } + boolean sawFirst = false; if (classLoader instanceof URLClassLoader) { - // If VFS class loader enabled, but no contexts defined. - out.print("Level " + classLoaderDescription + " URL classpath items are:"); - + if (debug) + out.print("Level " + classLoaderDescription + " URL classpath items are:\n"); for (URL u : ((URLClassLoader) classLoader).getURLs()) { - out.print("\t" + u.toExternalForm()); + printJar(out, u.getFile(), debug, sawFirst); + sawFirst = true; } - } else if (classLoader instanceof VFSClassLoader) { - out.print("Level " + classLoaderDescription + " VFS classpaths items are:"); + if (debug) + out.print("Level " + classLoaderDescription + " VFS classpaths items are:\n"); VFSClassLoader vcl = (VFSClassLoader) classLoader; for (FileObject f : vcl.getFileObjects()) { - out.print("\t" + f.getURL().toExternalForm()); + printJar(out, f.getURL().getFile(), debug, sawFirst); + sawFirst = true; } } else { - out.print("Unknown classloader configuration " + classLoader.getClass()); + if (debug) + out.print("Unknown classloader configuration " + classLoader.getClass() + "\n"); } } - + out.print("\n"); } catch (Throwable t) { throw new RuntimeException(t); } http://git-wip-us.apache.org/repos/asf/accumulo/blob/c2778b8a/start/src/test/java/org/apache/accumulo/start/classloader/vfs/AccumuloClasspathTest.java ---------------------------------------------------------------------- diff --git a/start/src/test/java/org/apache/accumulo/start/classloader/vfs/AccumuloClasspathTest.java b/start/src/test/java/org/apache/accumulo/start/classloader/vfs/AccumuloClasspathTest.java new file mode 100644 index 0000000..4925d67 --- /dev/null +++ b/start/src/test/java/org/apache/accumulo/start/classloader/vfs/AccumuloClasspathTest.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.accumulo.start.classloader.vfs; + +import static org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader.getClassPath; + +import org.junit.Assert; +import org.junit.Test; + +public class AccumuloClasspathTest { + + private static void assertPattern(String output, String pattern, boolean shouldMatch) { + if (shouldMatch) { + Assert.assertTrue("Pattern " + pattern + " did not match output: " + output, + output.matches(pattern)); + } else { + Assert.assertFalse("Pattern " + pattern + " should not match output: " + output, + output.matches(pattern)); + } + } + + @Test + public void basic() { + assertPattern(getClassPath(true), "(?s).*\\s+.*\\n$", true); + Assert.assertTrue(getClassPath(true).contains("Java System Classloader")); + Assert.assertTrue(getClassPath(true).contains("Level")); + + Assert.assertTrue(getClassPath(true).length() > getClassPath(false).length()); + + assertPattern(getClassPath(false), "(?s).*\\s+.*\\n$", false); + Assert.assertFalse(getClassPath(false).contains("Java System Classloader")); + Assert.assertFalse(getClassPath(false).contains("Level")); + } +}