├── jmxsh.jar
├── lib
├── jacl.jar
├── tcljava.jar
├── jline-0.9.93.jar
├── log4j-1.2.15.jar
├── commons-cli-1.1.jar
├── jakarta-oro-2.0.8.jar
└── one-jar-ant-task-0.96.jar
├── LICENSE-ONEJAR
├── LICENSE-TCLJAVA-3
├── jmxsh.mf
├── HIST
├── jmxsh
├── one-jar-ant-task.xml
├── NOTICE
├── .project
├── .classpath
├── testold
├── test.jmxsh
└── run.jmxsh
├── src
└── jmxsh
│ ├── Mode.java
│ ├── Context.java
│ ├── package.html
│ ├── Readline.java
│ ├── JInterp.java
│ ├── Utils.java
│ ├── ListCmd.java
│ ├── CloseCmd.java
│ ├── TypeName.java
│ ├── SetCmd.java
│ ├── GetCmd.java
│ ├── ShellMode.java
│ ├── ConnectCmd.java
│ ├── InvokeCmd.java
│ ├── Jmx.java
│ ├── Main.java
│ └── BrowseMode.java
├── LICENSE-TCLJAVA-2
├── test
└── jmxsh
│ └── test
│ └── SampleJmxServer.java
├── LICENSE-JLINE
├── LICENSE-TCLJAVA
├── .settings
└── org.eclipse.jdt.core.prefs
├── LICENSE-TCLJAVA-4
└── LICENSE
/jmxsh.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davr/jmxsh/HEAD/jmxsh.jar
--------------------------------------------------------------------------------
/lib/jacl.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davr/jmxsh/HEAD/lib/jacl.jar
--------------------------------------------------------------------------------
/LICENSE-ONEJAR:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davr/jmxsh/HEAD/LICENSE-ONEJAR
--------------------------------------------------------------------------------
/lib/tcljava.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davr/jmxsh/HEAD/lib/tcljava.jar
--------------------------------------------------------------------------------
/LICENSE-TCLJAVA-3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davr/jmxsh/HEAD/LICENSE-TCLJAVA-3
--------------------------------------------------------------------------------
/jmxsh.mf:
--------------------------------------------------------------------------------
1 | Main-Class: com.simontuffs.onejar.Boot
2 | One-Jar-Main-Class: jmxsh.Main
3 |
--------------------------------------------------------------------------------
/lib/jline-0.9.93.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davr/jmxsh/HEAD/lib/jline-0.9.93.jar
--------------------------------------------------------------------------------
/lib/log4j-1.2.15.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davr/jmxsh/HEAD/lib/log4j-1.2.15.jar
--------------------------------------------------------------------------------
/lib/commons-cli-1.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davr/jmxsh/HEAD/lib/commons-cli-1.1.jar
--------------------------------------------------------------------------------
/lib/jakarta-oro-2.0.8.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davr/jmxsh/HEAD/lib/jakarta-oro-2.0.8.jar
--------------------------------------------------------------------------------
/lib/one-jar-ant-task-0.96.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davr/jmxsh/HEAD/lib/one-jar-ant-task-0.96.jar
--------------------------------------------------------------------------------
/HIST:
--------------------------------------------------------------------------------
1 | jmxsh2.0 -- Lots of refactoring. tclsh, readline, command-line parsing.
2 | jmxsh2.1 -- Added rudimentary menus, navigation to mbean. Started on invoke, but stopped.
3 | jmxsh2.6 -- Multi-server, browser broken.
4 | jmxsh2.7 -- Browser fixed.
5 |
--------------------------------------------------------------------------------
/jmxsh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # jmxsh
4 | #
5 | # A shell wrapper for jmxsh.
6 | #
7 | # Assumes java is in the PATH. If not, will need to edit this script.
8 | #
9 | # You'll need to modify this when you find a place to jmxsh.
10 | #
11 | JMXSH_JARFILE=./jmxsh.jar
12 |
13 | exec java -jar $JMXSH_JARFILE "$@"
14 |
--------------------------------------------------------------------------------
/one-jar-ant-task.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | This software includes the following components from the Apache Software Foundation, also
2 | released under the Apache Software License Version 2.0:
3 |
4 | commons-cli-1.1.jar
5 | jakarta-oro-2.0.8.jar
6 | log4j-1.2.15.jar
7 |
8 | The following components are covered under different licenses:
9 |
10 | jline-0.9.94.jar (LICENSE-JLINE)
11 | One-Jar (LICENSE-ONEJAR)
12 | Java/Tcl v1.3.3 (LICENSE-TCLJAVA,-2,-3,-4)
13 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | jmxsh.old
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/testold/test.jmxsh:
--------------------------------------------------------------------------------
1 | set MBEAN DefaultDomain:type=SimpleStandard
2 |
3 | puts "Integer is: [jmx_get -m $MBEAN Int]"
4 | puts "Number of state changes is: [jmx_get -m $MBEAN NbChanges]"
5 | puts "Current State is: [jmx_get -m $MBEAN State]"
6 |
7 | puts [jmx_invoke -m $MBEAN currentState]
8 |
9 | jmx_set -m $MBEAN Int 555
10 | jmx_set -m $MBEAN State "NewJersey"
11 |
12 | puts [jmx_invoke -m $MBEAN currentState]
13 |
14 | puts "Resetting..."
15 |
16 | jmx_invoke -m $MBEAN reset
17 | jmx_set -m $MBEAN Int 100
18 |
19 | puts ""
20 |
21 | puts "Integer is: [jmx_get -m $MBEAN Int]"
22 | puts "Number of state changes is: [jmx_get -m $MBEAN NbChanges]"
23 | puts "Current State is: [jmx_get -m $MBEAN State]"
24 |
25 | puts [jmx_invoke -m $MBEAN currentState]
26 |
--------------------------------------------------------------------------------
/src/jmxsh/Mode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 | abstract class Mode {
26 |
27 | abstract String getPrePromptDisplay();
28 | abstract String getPrompt();
29 | abstract String handleInput(String input);
30 | abstract void displayHelp();
31 |
32 | static Mode getBrowseModeInstance() {
33 | return BrowseMode.instance;
34 | }
35 |
36 | static Mode getShellModeInstance() {
37 | return ShellMode.instance;
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/LICENSE-TCLJAVA-2:
--------------------------------------------------------------------------------
1 | Portions of Jacl and Tcl Blend are
2 | Copyright (c) 1997-1999 The Regents of the University of California.
3 | All rights reserved.
4 |
5 | Permission is hereby granted, without written agreement and without
6 | license or royalty fees, to use, copy, modify, and distribute this
7 | software and its documentation for any purpose, provided that the above
8 | copyright notice and the following two paragraphs appear in all copies
9 | of this software.
10 |
11 | IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
12 | FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
13 | ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
14 | THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
15 | SUCH DAMAGE.
16 |
17 | THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
18 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
20 | PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
21 | CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
22 | ENHANCEMENTS, OR MODIFICATIONS.
23 |
24 |
--------------------------------------------------------------------------------
/testold/run.jmxsh:
--------------------------------------------------------------------------------
1 | puts "Now where are running it."
2 | puts "argv0: $argv0"
3 | puts "argv: $argv"
4 | puts "argc: $argc"
5 |
6 | foreach item $argv {
7 | puts "Arg: $item"
8 | }
9 |
10 | set server "foo"
11 | set mbean "DefaultDomain:type=SimpleStandard"
12 |
13 | puts "Original Int: [jmx_get -s $server -m $mbean Int]"
14 | puts "Original State: [jmx_get -s $server -m $mbean State]"
15 |
16 | jmx_set -s $server -m $mbean Int 20
17 | puts "New Int: [jmx_get -s $server -m $mbean Int]"
18 |
19 | puts "Number of changes: [jmx_get -s $server -m $mbean NbChanges]"
20 |
21 | jmx_set -s $server -m $mbean State "Here's your new state"
22 | puts "New state: [jmx_get -s $server -m $mbean State]"
23 |
24 | puts "Number of changes: [jmx_get -s $server -m $mbean NbChanges]"
25 |
26 | puts "Current state: [jmx_invoke -s $server -m $mbean currentState]"
27 |
28 | puts "Invoking reset."
29 | jmx_invoke -s $server -m $mbean reset
30 |
31 | puts "Current state: [jmx_invoke -s $server -m $mbean currentState]"
32 |
33 | puts "Current NbChange: [jmx_get -s $server -m $mbean NbChanges]"
34 | puts "Current Int: [jmx_get -s $server -m $mbean Int]"
35 | puts "Current State: [jmx_get -s $server -m $mbean State]"
36 |
37 | #set result [jmx_invoke -s $server -m $mbean [list currentState java.lang.Integer] 35]
38 | #puts "Result: $result"
39 |
--------------------------------------------------------------------------------
/src/jmxsh/Context.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 | /**
26 | A tuplet that identifies a server/mbean/attribute/operation.
27 | */
28 |
29 | class Context {
30 | String server;
31 | String domain;
32 | String mbean;
33 | String attrop;
34 |
35 | Context() {
36 | this.server = null;
37 | this.domain = null;
38 | this.mbean = null;
39 | this.attrop = null;
40 | }
41 |
42 | static private Context tclContext = new Context();
43 |
44 | static Context fromTcl() {
45 | tclContext.server = JInterp.getGlobal("SERVER", null);
46 | tclContext.domain = JInterp.getGlobal("DOMAIN", null);
47 | tclContext.mbean = JInterp.getGlobal("MBEAN", null);
48 | tclContext.attrop = JInterp.getGlobal("ATTROP", null);
49 | return tclContext;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/test/jmxsh/test/SampleJmxServer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh.test;
24 |
25 | import javax.management.*;
26 | import java.lang.management.*;
27 | import java.io.IOException;
28 |
29 | /**
30 | * A simple JMX server to use for testing.
31 | *
32 | * @author Dad
33 | */
34 | public class SampleJmxServer {
35 |
36 | public static void main(String[] args) {
37 | System.out.println("Starting up server...");
38 |
39 | MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
40 |
41 |
42 |
43 | System.out.println("Press enter to quit.");
44 | try {
45 | int c = System.in.read();
46 | }
47 | catch (IOException e) {
48 | System.err.println("Error reading input.");
49 | }
50 |
51 | System.out.println("Shutting down server...");
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/LICENSE-JLINE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2002-2006, Marc Prud'hommeaux
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or
5 | without modification, are permitted provided that the following
6 | conditions are met:
7 |
8 | Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 |
11 | Redistributions in binary form must reproduce the above copyright
12 | notice, this list of conditions and the following disclaimer
13 | in the documentation and/or other materials provided with
14 | the distribution.
15 |
16 | Neither the name of JLine nor the names of its contributors
17 | may be used to endorse or promote products derived from this
18 | software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
22 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23 | AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
24 | EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
26 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
31 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32 | OF THE POSSIBILITY OF SUCH DAMAGE.
33 |
34 |
--------------------------------------------------------------------------------
/src/jmxsh/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
27 |
28 |
29 |
30 | An easy-to-use, scriptable, command-line interface to JMX servers based on Java/Tcl.
31 |
32 | Features
33 |
34 |
35 | - Scriptable Tcl interpreter, based on the Java/Tcl project.
36 | - Use interactively, or run scripts from the command line.
37 | - Easy-to-use "Browse" mode to explore JMX namespace interactively.
38 | - Connect to multiple servers simultaneously.
39 | - Command-line editing and persistent history using jline.
40 | - User/password authentication, SSL, and jmxmp in addition to rmi.
41 | - Source in multiple Tcl files from the command line--build a library of useful functions.
42 |
43 |
44 | Future
45 |
46 |
47 | - Support JMX Monitors.
48 | - Tcl command for loading additional classes via jar files.
49 |
50 |
51 |
52 | @author robspassky
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/LICENSE-TCLJAVA:
--------------------------------------------------------------------------------
1 | SUN MICROSYSTEMS, INC. THROUGH ITS SUN MICROSYSTEMS LABORATORIES
2 | DIVISION ("SUN") WILL LICENSE THIS SOFTWARE AND THE ACCOMPANYING
3 | DOCUMENTATION TO YOU (a "Licensee") ONLY ON YOUR ACCEPTANCE OF ALL
4 | THE TERMS SET FORTH BELOW.
5 |
6 | Sun grants Licensee a non-exclusive, royalty-free right to download,
7 | install, compile, use, copy and distribute the Software, modify or
8 | otherwise create derivative works from the Software (each, a
9 | "Modification") and distribute any Modification in source code and/or
10 | binary code form to its customers with a license agreement containing
11 | these terms and noting that the Software has been modified. The
12 | Software is copyrighted by Sun and other third parties and Licensee
13 | shall retain and reproduce all copyright and other notices presently
14 | on the Software. As between Sun and Licensee, Sun is the sole owner of
15 | all rights in and to the Software other than the limited rights
16 | granted to Licensee herein; Licensee will own its Modifications,
17 | expressly subject to Sun's continuing ownership of the
18 | Software. Licensee will, at its expense, defend and indemnify Sun and
19 | its licensors from and against any third party claims, including costs
20 | and reasonable attorneys' fees, and be wholly responsible for any
21 | liabilities arising out of or related to Licensee's development, use
22 | or distribution of the Software or Modifications. Any distribution of
23 | the Software and Modifications must comply with all applicable United
24 | States export control laws.
25 |
26 | THE SOFTWARE IS BEING PROVIDED TO LICENSEE "AS IS" AND ALL EXPRESS OR
27 | IMPLIED CONDITIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
28 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT,
29 | ARE DISCLAIMED. IN NO EVENT WILL SUN BE LIABLE HEREUNDER FOR ANY
30 | DIRECT DAMAGES OR ANY INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL OR
31 | CONSEQUENTIAL DAMAGES OF ANY KIND.
32 |
33 |
--------------------------------------------------------------------------------
/src/jmxsh/Readline.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 | import org.apache.log4j.*;
26 | import java.io.*;
27 | import jline.*;
28 |
29 | /**
30 | Facade for jline classes.
31 | */
32 |
33 | class Readline {
34 |
35 | private static Logger logger = Logger.getLogger(Readline.class);
36 | private static final Readline instance = new Readline();
37 |
38 | public static Readline getInstance() { return instance; }
39 |
40 | private ConsoleReader reader;
41 |
42 | private Readline() {
43 |
44 | try {
45 | reader = new ConsoleReader();
46 | }
47 | catch (IOException e) {
48 | logger.fatal("Could not create jline reader.", e);
49 | throw new IllegalStateException("Error creating jline reader.", e);
50 | }
51 |
52 | reader.setUseHistory(false);
53 | }
54 |
55 | void setHistoryFile(String filename) {
56 | File history = new File(filename);
57 |
58 | try {
59 | reader.getHistory().setHistoryFile(history);
60 | }
61 | catch(IOException e) {
62 | throw new IllegalArgumentException("History file '" + filename + "' does not exist is not writable.", e);
63 | }
64 | }
65 |
66 | public void addToHistory(String command) {
67 | reader.getHistory().addToHistory(command);
68 | }
69 |
70 | public String readline(String prompt) {
71 | try {
72 | return reader.readLine(prompt);
73 | }
74 | catch (IOException e) {
75 | logger.error("Readline error.", e);
76 | throw new IllegalArgumentException("Readline error: " + e.getMessage(), e);
77 | }
78 | }
79 |
80 | public String readline(String prompt, char mask) {
81 | try {
82 | return reader.readLine(prompt, mask);
83 | }
84 | catch (IOException e) {
85 | logger.error("Readline error.", e);
86 | throw new IllegalArgumentException("Readline error: " + e.getMessage(), e);
87 | }
88 | }
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | #Sat May 10 19:29:44 EDT 2008
2 | eclipse.preferences.version=1
3 | org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
4 | org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
5 | org.eclipse.jdt.core.compiler.problem.deprecation=warning
6 | org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
7 | org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
8 | org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
9 | org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
10 | org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
11 | org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
12 | org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
13 | org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
14 | org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
15 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
16 | org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
17 | org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
18 | org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
19 | org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
20 | org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
21 | org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
22 | org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error
23 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
24 | org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
25 | org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
26 | org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
27 | org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
28 | org.eclipse.jdt.core.compiler.problem.nullReference=error
29 | org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
30 | org.eclipse.jdt.core.compiler.problem.parameterAssignment=warning
31 | org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
32 | org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
33 | org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
34 | org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
35 | org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
36 | org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=ignore
37 | org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
38 | org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
39 | org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
40 | org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
41 | org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
42 | org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
43 | org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
44 | org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
45 | org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
46 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
47 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
48 | org.eclipse.jdt.core.compiler.problem.unusedImport=warning
49 | org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
50 | org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
51 | org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
52 | org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
53 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
54 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
55 | org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
56 | org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
57 |
--------------------------------------------------------------------------------
/src/jmxsh/JInterp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 | import org.apache.log4j.*;
26 | import tcl.lang.*;
27 |
28 | class JInterp extends Interp {
29 |
30 | static private Logger logger = Logger.getLogger(JInterp.class);
31 |
32 | static JInterp instance = new JInterp();
33 |
34 | static String getGlobal(String name, String defaultValue) {
35 | try {
36 | TclObject result = instance.getVar(name, TCL.GLOBAL_ONLY);
37 | return result.toString();
38 |
39 | }
40 | catch (TclException e) {
41 | return defaultValue;
42 | }
43 | }
44 |
45 | static void setGlobal(String name, String value) {
46 | try {
47 | instance.setVar(name, TclString.newInstance(value), TCL.GLOBAL_ONLY);
48 | }
49 | catch (TclException e) {
50 | throw new IllegalArgumentException("Tcl error setting variable '" + name + "' to '" + value + ".", e);
51 | }
52 | }
53 |
54 | static void setGlobal(String name, int value) {
55 | try {
56 | instance.setVar(name, TclInteger.newInstance(value), TCL.GLOBAL_ONLY);
57 | }
58 | catch (TclException e) {
59 | throw new IllegalArgumentException("Tcl error setting variable '" + name + "' to '" + value + ".", e);
60 | }
61 | }
62 |
63 | static void setGlobal(String array, String key, String value) {
64 | try {
65 | instance.setVar(array, key, value, TCL.GLOBAL_ONLY);
66 | }
67 | catch (TclException e) {
68 | throw new IllegalArgumentException("Tcl error setting array value.");
69 | }
70 | }
71 |
72 | static void setGlobal(String name, String[] value, int startIndex) {
73 | TclObject list = TclList.newInstance();
74 |
75 | try {
76 | for (int i=startIndex; i ctor = Class.forName(newType.toString()).getConstructor(new Class[]{String.class});
106 | result = ctor.newInstance(new Object[]{obj.toString()});
107 | }
108 | catch (NoSuchMethodException e) {
109 | throw new IllegalArgumentException("Cannot instantiate attribute of type: '" + newType.toString() + "' - cannot convert from string.", e);
110 | }
111 | catch (ClassNotFoundException e) {
112 | throw new IllegalArgumentException("Cannot instantiate attribute of type: '" + newType.toString() + "' - class not found locally.", e);
113 | }
114 | catch (InstantiationException e) {
115 | throw new IllegalArgumentException("Cannot instantiate attribute of type: '" + newType.toString() + "' - class cannot be instantiated.", e);
116 | }
117 | catch (IllegalAccessException e) {
118 | throw new IllegalArgumentException("Cannot instantiate attribute of type: '" + newType.toString() + "' - cannot access constructor.", e);
119 | }
120 | catch (InvocationTargetException e) {
121 | throw new IllegalArgumentException("Cannot instantiate attribute of type: '" + newType.toString() + "' - exception thrown in constructor.", e);
122 | }
123 |
124 | return result;
125 | }
126 |
127 | }
128 |
--------------------------------------------------------------------------------
/src/jmxsh/ListCmd.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 |
26 | import java.util.*;
27 | import org.apache.commons.cli.*;
28 | import tcl.lang.*;
29 |
30 |
31 | class ListCmd implements Command {
32 |
33 | private final static ListCmd instance = new ListCmd();
34 |
35 | private String server;
36 | private Options opts;
37 |
38 | static ListCmd getInstance() {
39 | return instance;
40 | }
41 |
42 | private ListCmd() {
43 | this.opts = new Options();
44 |
45 | this.opts.addOption(
46 | OptionBuilder.withLongOpt("server")
47 | .withDescription("Server containing mbean.")
48 | .withArgName("SERVER")
49 | .hasArg()
50 | .create("s")
51 | );
52 |
53 | this.opts.addOption(
54 | OptionBuilder.withLongOpt("help")
55 | .withDescription("Display usage help.")
56 | .hasArg(false)
57 | .create("?")
58 | );
59 | }
60 |
61 | private CommandLine parseCommandLine(TclObject argv[])
62 | throws ParseException {
63 |
64 | String[] args = new String[argv.length - 1];
65 |
66 | for(int i = 0; i < argv.length - 1; i++)
67 | args[i] = argv[i + 1].toString();
68 |
69 | CommandLine cl = (new PosixParser()).parse(this.opts, args);
70 | return cl;
71 | }
72 |
73 | private void listDefaults(Interp interp) {
74 | this.server = null;
75 |
76 | try {
77 | this.server = interp.getVar("SERVER", TCL.GLOBAL_ONLY).toString();
78 | }
79 | catch (TclException e) {
80 | /* If one doesn't exist, it will just be null. */
81 | }
82 |
83 | }
84 |
85 | public void cmdProc(Interp interp, TclObject argv[])
86 | throws TclException {
87 |
88 | try {
89 | CommandLine cl = parseCommandLine(argv);
90 | String args[] = cl.getArgs();
91 | String[] expressions = null;
92 |
93 | if (cl.hasOption("help")) {
94 | new HelpFormatter().printHelp (
95 | "jmx_list [-?] [-s server] domain_regex:mbean_regex",
96 | "======================================================================",
97 | this.opts,
98 | "======================================================================",
99 | false
100 | );
101 | System.out.println("jmx_list retrieves the list of known mbeans for the given");
102 | System.out.println("server. It takes a pair of regex expressions separated by");
103 | System.out.println("colon. The first is an expression for the domain, the");
104 | System.out.println("second is an expression for the mbean.");
105 | System.out.println("");
106 | System.out.println("It will return a list of tcl strings.");
107 | return;
108 | }
109 |
110 | listDefaults(interp);
111 |
112 | this.server = cl.getOptionValue("server", this.server);
113 |
114 | if (args.length > 0) {
115 | expressions = args[0].split(":");
116 | }
117 |
118 | if (this.server == null) {
119 | throw new TclException(interp, "No server specified; please set SERVER variable or use -s option.", TCL.ERROR);
120 | }
121 |
122 | String domain_regex = (expressions != null && expressions.length > 0) ? expressions[0] : "";
123 | String mbean_regex = (expressions != null && expressions.length > 1) ? expressions[1] : "";
124 |
125 | String[] domains = Jmx.getInstance().getDomains(this.server, domain_regex);
126 | Vector beans = new Vector();
127 | for (String domain : domains) {
128 | List list = Arrays.asList(Jmx.getInstance().getMBeans(this.server, domain, mbean_regex));
129 | beans.addAll(list);
130 | }
131 |
132 | String[] emptyStringArray = new String[0];
133 | TclObject result = Utils.array2list(beans.toArray(emptyStringArray));
134 | interp.setResult(result);
135 | }
136 | catch(ParseException e) {
137 | throw new TclException(interp, e.getMessage(), 1);
138 | }
139 | catch(RuntimeException e) {
140 | throw new TclException(interp, "Cannot convert result to a string.", 1);
141 | }
142 | }
143 |
144 | }
145 |
--------------------------------------------------------------------------------
/src/jmxsh/CloseCmd.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 | import org.apache.commons.cli.CommandLine;
26 | import org.apache.commons.cli.HelpFormatter;
27 | import org.apache.commons.cli.OptionBuilder;
28 | import org.apache.commons.cli.Options;
29 | import org.apache.commons.cli.ParseException;
30 | import org.apache.commons.cli.PosixParser;
31 | import org.apache.log4j.Logger;
32 |
33 | import tcl.lang.Command;
34 | import tcl.lang.Interp;
35 | import tcl.lang.TCL;
36 | import tcl.lang.TclException;
37 | import tcl.lang.TclObject;
38 | import tcl.lang.TclString;
39 |
40 | /**
41 | * Tcl command for closing a JMX connection.
42 | *
43 | * @author robspassky
44 | */
45 |
46 | class CloseCmd implements Command {
47 |
48 | final static CloseCmd instance = new CloseCmd();
49 |
50 | /** Initializes private variables. Setup the command-line options. */
51 | private CloseCmd() {
52 | this.opts = new Options();
53 |
54 | this.opts.addOption(
55 | OptionBuilder.withLongOpt("server")
56 | .withDescription("Server containing mbean.")
57 | .withArgName("SERVER")
58 | .hasArg()
59 | .create("s")
60 | );
61 |
62 | this.opts.addOption(
63 | OptionBuilder.withLongOpt("help")
64 | .withDescription("Display usage help.")
65 | .hasArg(false)
66 | .create("?")
67 | );
68 | }
69 |
70 | private CommandLine parseCommandLine(TclObject argv[])
71 | throws ParseException {
72 |
73 | String[] args = new String[argv.length - 1];
74 |
75 | for(int i = 0; i < argv.length - 1; i++)
76 | args[i] = argv[i + 1].toString();
77 |
78 | CommandLine cl = (new PosixParser()).parse(this.opts, args);
79 | return cl;
80 | }
81 |
82 | private void getDefaults(Interp interp) {
83 | this.server = null;
84 |
85 | try {
86 | this.server = interp.getVar("SERVER", TCL.GLOBAL_ONLY).toString();
87 | }
88 | catch (TclException e) {
89 | /* If one doesn't exist, it will just be null. */
90 | }
91 |
92 | }
93 |
94 | public void cmdProc(Interp interp, TclObject argv[])
95 | throws TclException {
96 |
97 | try {
98 | CommandLine cl = parseCommandLine(argv);
99 |
100 | if (cl.hasOption("help")) {
101 | new HelpFormatter().printHelp (
102 | "jmx_close [-?] [-s server]",
103 | "======================================================================",
104 | this.opts,
105 | "======================================================================",
106 | false
107 | );
108 |
109 | System.out.println("jmx_close closes a connection with a JMX server.");
110 | return;
111 | }
112 |
113 | getDefaults(interp);
114 |
115 | String serverToClose = cl.getOptionValue("server", this.server);
116 |
117 | if (serverToClose == null) {
118 | throw new TclException(interp, "No server specified; please set SERVER variable or use -s option.", TCL.ERROR);
119 | }
120 |
121 | Jmx.getInstance().close(serverToClose);
122 |
123 | if (serverToClose.equals(this.server)) {
124 | // We need this to avoid getting a "cannot unset non-existent variable"
125 | // error, which I could not find a way to suppress nicely.
126 | TclObject space = TclString.newInstance(" ");
127 | interp.setVar("SERVER", space, TCL.GLOBAL_ONLY);
128 | interp.setVar("DOMAIN", space, TCL.GLOBAL_ONLY);
129 | interp.setVar("MBEAN", space, TCL.GLOBAL_ONLY);
130 | interp.setVar("ATTROP", space, TCL.GLOBAL_ONLY);
131 | interp.unsetVar("SERVER", TCL.GLOBAL_ONLY);
132 | interp.unsetVar("DOMAIN", TCL.GLOBAL_ONLY);
133 | interp.unsetVar("MBEAN", TCL.GLOBAL_ONLY);
134 | interp.unsetVar("ATTROP", TCL.GLOBAL_ONLY);
135 | BrowseMode.instance.setServerMenuLevel();
136 | }
137 |
138 | }
139 | catch(ParseException e) {
140 | throw new TclException(interp, e.getMessage(), 1);
141 | }
142 | catch(RuntimeException e) {
143 | logger.error("Runtime Exception", e);
144 | throw new TclException(interp, "Runtime exception.", 1);
145 | }
146 | }
147 |
148 | private static Logger logger = Logger.getLogger(CloseCmd.class);
149 |
150 | private String server;
151 | private Options opts;
152 |
153 |
154 | }
--------------------------------------------------------------------------------
/src/jmxsh/TypeName.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 | import org.apache.log4j.*;
26 |
27 | /**
28 | The name of a class.
29 |
30 | Automatically handles parsing and printing of nice class names,
31 | including the kludgy representation of array names.
32 | */
33 |
34 |
35 |
36 | class TypeName {
37 |
38 | static private Logger logger = Logger.getLogger(TypeName.class);
39 |
40 | private int depth;
41 | private String className;
42 |
43 | static public String translateClassName(String className) {
44 | return TypeName.parseClassName(className).toString();
45 | }
46 |
47 | static public String translateNiceName(String niceName) {
48 | String result = TypeName.fromNiceName(niceName).toClassName();
49 | logger.debug("Input nicename: " + niceName + ", output class name: " + result);
50 | return result;
51 | }
52 |
53 | /** Parse the java internal class name. */
54 | static public TypeName parseClassName(String typeString) {
55 | TypeName tn = new TypeName();
56 |
57 | if (typeString.charAt(0) != '[') {
58 | tn.className = typeString;
59 | return tn;
60 | }
61 |
62 | int pos = 0;
63 | while (typeString.charAt(pos) == '[') {
64 | tn.depth++;
65 | pos++;
66 | }
67 |
68 | switch (typeString.charAt(pos)) {
69 | case 'L': {
70 | int name_begin = pos + 1;
71 | int name_end = typeString.indexOf(';', name_begin);
72 |
73 | tn.className = typeString.substring(name_begin, name_end);
74 | break;
75 | }
76 | case 'Z':
77 | tn.className = "boolean";
78 | break;
79 | case 'B':
80 | tn.className = "byte";
81 | break;
82 | case 'C':
83 | tn.className = "char";
84 | break;
85 | case 'D':
86 | tn.className = "double";
87 | break;
88 | case 'F':
89 | tn.className = "float";
90 | break;
91 | case 'I':
92 | tn.className = "int";
93 | break;
94 | case 'J':
95 | tn.className = "long";
96 | break;
97 | case 'S':
98 | tn.className = "short";
99 | break;
100 | }
101 |
102 | return tn;
103 | }
104 |
105 | /** Return the TypeName from an actual class. */
106 | static public TypeName fromClass(Class> klass) {
107 | return parseClassName(klass.getName());
108 | }
109 |
110 | /** Return the TypeName from an actual class. */
111 | static public TypeName fromNiceName(String niceName) {
112 | TypeName tn = new TypeName();
113 | tn.depth = 0;
114 | for (int pos = niceName.indexOf('['); pos != -1; pos = niceName.indexOf('[', pos+1)) {
115 | tn.depth++;
116 | }
117 | if (tn.depth > 0) {
118 | tn.className = niceName.substring(0, niceName.indexOf('['));
119 | }
120 | else {
121 | tn.className = niceName;
122 | }
123 | return tn;
124 | }
125 |
126 | /** Print a nice string. Remove java.lang. */
127 | public String toString() {
128 | StringBuilder sb = new StringBuilder(50);
129 | if (className.startsWith("java.lang.")) {
130 | sb.append(className.substring(10));
131 | }
132 | else {
133 | sb.append(className);
134 | }
135 | for (int i=0; i 1) {
122 | attribute = args[0];
123 | newvalue = argv[argv.length-args.length+1];
124 | }
125 | else {
126 | attribute = attrop;
127 | newvalue = argv[argv.length-args.length];
128 | }
129 |
130 | if (server == null) {
131 | throw new TclException(interp, "No server specified; please set SERVER variable or use -s option.", TCL.ERROR);
132 | }
133 |
134 | if (mbean == null) {
135 | throw new TclException(interp, "No mbean specified; please set MBEAN variable or use -m option.", TCL.ERROR);
136 | }
137 |
138 | if (attribute == null) {
139 | throw new TclException(interp, "No attribute specified; please set ATTROP variable or add it to the command line.", TCL.ERROR);
140 | }
141 |
142 | if (newvalue == null) {
143 | throw new TclException(interp, "No new value provided for the attribute.", TCL.ERROR);
144 | }
145 |
146 | Jmx.getInstance().setAttribute(server, mbean, attribute, newvalue);
147 | }
148 | catch(ParseException e) {
149 | throw new TclException(interp, e.getMessage(), 1);
150 | }
151 | catch(RuntimeException e) {
152 | throw new TclException(interp, e.getMessage(), 1);
153 | }
154 | }
155 |
156 | private String server;
157 | //private String domain;
158 | private String mbean;
159 | private String attrop;
160 |
161 | //private static Logger logger = Logger.getLogger(SetCmd.class);
162 | private Options opts;
163 | }
164 |
--------------------------------------------------------------------------------
/src/jmxsh/GetCmd.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 | import org.apache.commons.cli.*;
26 | //import org.apache.log4j.Logger;
27 | import tcl.lang.*;
28 |
29 | class GetCmd implements Command {
30 |
31 | private final static GetCmd instance = new GetCmd();
32 | //private final static Logger logger = Logger.getLogger(GetCmd.class);
33 |
34 | private String server;
35 | //private String domain;
36 | private String mbean;
37 | private String attrop;
38 | private Options opts;
39 |
40 | static GetCmd getInstance() {
41 | return instance;
42 | }
43 |
44 | private GetCmd() {
45 | this.opts = new Options();
46 |
47 | this.opts.addOption(
48 | OptionBuilder.withLongOpt("server")
49 | .withDescription("Server containing mbean.")
50 | .withArgName("SERVER")
51 | .hasArg()
52 | .create("s")
53 | );
54 |
55 | this.opts.addOption(
56 | OptionBuilder.withLongOpt("mbean")
57 | .withDescription("MBean containing attribute.")
58 | .withArgName("MBEAN")
59 | .hasArg()
60 | .create("m")
61 | );
62 |
63 | this.opts.addOption(
64 | OptionBuilder.withLongOpt("noconvert")
65 | .withDescription("Do not auto-convert the result to a Tcl string, instead create a java object reference.")
66 | .hasArg(false)
67 | .create("n")
68 | );
69 |
70 | this.opts.addOption(
71 | OptionBuilder.withLongOpt("help")
72 | .withDescription("Display usage help.")
73 | .hasArg(false)
74 | .create("?")
75 | );
76 | }
77 |
78 | private CommandLine parseCommandLine(TclObject argv[])
79 | throws ParseException {
80 |
81 | String[] args = new String[argv.length - 1];
82 |
83 | for(int i = 0; i < argv.length - 1; i++)
84 | args[i] = argv[i + 1].toString();
85 |
86 | CommandLine cl = (new PosixParser()).parse(this.opts, args);
87 | return cl;
88 | }
89 |
90 | private void getDefaults(Interp interp) {
91 | this.server = null;
92 | //domain = null;
93 | this.mbean = null;
94 | this.attrop = null;
95 |
96 | try {
97 | this.server = interp.getVar("SERVER", TCL.GLOBAL_ONLY).toString();
98 | //domain = interp.getVar("DOMAIN", TCL.GLOBAL_ONLY).toString();
99 | this.mbean = interp.getVar("MBEAN", TCL.GLOBAL_ONLY).toString();
100 | this.attrop = interp.getVar("ATTROP", TCL.GLOBAL_ONLY).toString();
101 | }
102 | catch (TclException e) {
103 | /* If one doesn't exist, it will just be null. */
104 | }
105 |
106 | }
107 |
108 | public void cmdProc(Interp interp, TclObject argv[])
109 | throws TclException {
110 |
111 | try {
112 | CommandLine cl = parseCommandLine(argv);
113 | String args[] = cl.getArgs();
114 | String attribute = null;
115 |
116 | if (cl.hasOption("help")) {
117 | new HelpFormatter().printHelp (
118 | "jmx_get [-?] [-n] [-s server] [-m mbean] [ATTRIBUTE]",
119 | "======================================================================",
120 | this.opts,
121 | "======================================================================",
122 | false
123 | );
124 | System.out.println("jmx_get retrieves the current value of the given attribute.");
125 | System.out.println("If you do not specify server, mbean, or ATTRIBUTE, then the");
126 | System.out.println("values in the global variables SERVER, MBEAN, and ATTROP,");
127 | System.out.println("respectively, will be used.");
128 | System.out.println("");
129 | System.out.println("If you specify -n, then the return will be a Java/Tcl java");
130 | System.out.println("object reference. See the Java/Tcl documentation on the");
131 | System.out.println("internet for more details.");
132 | return;
133 | }
134 |
135 | getDefaults(interp);
136 |
137 | this.server = cl.getOptionValue("server", this.server);
138 | this.mbean = cl.getOptionValue("mbean", this.mbean);
139 | this.attrop = cl.getOptionValue("attrop", this.attrop);
140 |
141 | if (args.length > 0) {
142 | attribute = args[0];
143 | }
144 | else {
145 | attribute = this.attrop;
146 | }
147 |
148 | if (this.server == null) {
149 | throw new TclException(interp, "No server specified; please set SERVER variable or use -s option.", TCL.ERROR);
150 | }
151 |
152 | if (this.mbean == null) {
153 | throw new TclException(interp, "No mbean specified; please set MBEAN variable or use -m option.", TCL.ERROR);
154 | }
155 |
156 | if (attribute == null) {
157 | throw new TclException(interp, "No attribute specified; please set ATTROP variable or add it to the command line.", TCL.ERROR);
158 | }
159 |
160 | if (cl.hasOption("noconvert")) {
161 | String result = Utils.java2tcl(Jmx.getInstance().getAttribute(this.server, this.mbean, attribute));
162 | interp.setResult(result);
163 | } else {
164 | interp.setResult(Jmx.getInstance().getAttribute(this.server, this.mbean, attribute).toString());
165 | }
166 | }
167 | catch(ParseException e) {
168 | throw new TclException(interp, e.getMessage(), 1);
169 | }
170 | catch(RuntimeException e) {
171 | throw new TclException(interp, "Cannot convert result to a string.", 1);
172 | }
173 | }
174 |
175 | }
176 |
--------------------------------------------------------------------------------
/src/jmxsh/ShellMode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 | import org.apache.log4j.*;
26 | import tcl.lang.*;
27 |
28 | /**
29 | Implementation of shell mode.
30 |
31 | Interpret user input as Tcl commands. Maintain command line history.
32 | */
33 | class ShellMode extends Mode {
34 |
35 | static private Logger logger = Logger.getLogger(ShellMode.class);
36 | static ShellMode instance = new ShellMode();
37 |
38 | private StringBuilder stringBuilder;
39 |
40 | private ShellMode() {
41 | stringBuilder = new StringBuilder(100);
42 | }
43 |
44 | String getPrePromptDisplay() {
45 | return "";
46 | }
47 |
48 | String getPrompt() {
49 | if (stringBuilder.length() == 0) {
50 | return "%";
51 | }
52 |
53 | return ">>";
54 | }
55 |
56 | String handleInput(String input) {
57 |
58 | stringBuilder.append(input);
59 |
60 | final String command = stringBuilder.toString();
61 |
62 | logger.debug(command);
63 |
64 | if (!Interp.commandComplete(command)) {
65 | return null;
66 | }
67 |
68 | stringBuilder.setLength(0);
69 |
70 | TclEvent event =
71 | new TclEvent() {
72 | public int processEvent(int flags) {
73 | Interp interp = JInterp.instance;
74 |
75 | TclObject cmdObj = TclString.newInstance(command);
76 | cmdObj.preserve();
77 |
78 | try {
79 | interp.recordAndEval(cmdObj, 0);
80 | }
81 | catch (TclException e) {
82 | switch (e.getCompletionCode()) {
83 | case TCL.ERROR:
84 | case TCL.CONTINUE:
85 | String message = interp.getResult().toString();
86 | if (message.length() == 0) {
87 | message = e.getMessage();
88 | }
89 | System.out.println("Error: " + message);
90 | break;
91 | case TCL.BREAK:
92 | System.out.println("Error: invoked \"break\" outside of a loop.");
93 | break;
94 | default:
95 | System.out.println("Error: command returned bad completion code - " + e.getCompletionCode());
96 | }
97 |
98 | }
99 | finally {
100 | cmdObj.release();
101 | }
102 |
103 | System.out.println(interp.getResult().toString());
104 | return 1;
105 | }
106 | };
107 |
108 | JInterp.instance.getNotifier().queueEvent(event, TCL.QUEUE_TAIL);
109 | event.sync();
110 |
111 | return command;
112 | }
113 |
114 | void displayHelp() {
115 | StringBuilder sb = new StringBuilder(1000);
116 |
117 | sb.append("=====================================================\n");
118 | sb.append(" Shell Mode Help\n");
119 | sb.append("\n");
120 | sb.append("This mode is a tcl shell. Several JMX-related commands\n");
121 | sb.append("have been added:\n");
122 | sb.append("\n");
123 | sb.append("o jmx_connect - connect to a JMX server\n");
124 | sb.append("o jmx_close - close a connection\n");
125 | sb.append("o jmx_set - change a JMX attribute\n");
126 | sb.append("o jmx_get - read a JMX attribute\n");
127 | sb.append("o jmx_invoke - invoke a JMX operation\n");
128 | sb.append("o jmx_list - list attribs w/regex (NOT TESTED)\n");
129 | sb.append("\n");
130 | sb.append("To get further help on each command, invoke it with the\n");
131 | sb.append("-? option.\n");
132 | sb.append("\n");
133 | sb.append("The jmx_get and jmx_invoke commands return data from the\n");
134 | sb.append("remote JMX server. This data will be automatically converted\n");
135 | sb.append("to a String when the result is created. If the data being\n");
136 | sb.append("returned is more complex, then the -n or --noconvert option\n");
137 | sb.append("should be used. This will cause jmxsh to create and return\n");
138 | sb.append("a Jacl java object reference. This string (usually of the\n");
139 | sb.append("form 'java0x1' or similar) can be used with the various Jacl\n");
140 | sb.append("java:: commands to obtain full access to the Java object.\n");
141 | sb.append("\n");
142 | sb.append("Most of the commands take -s SERVER and -m MBEAN arguments\n");
143 | sb.append("to determine where they will take effect. Rather than\n");
144 | sb.append("specifying these values each time, the commands will also\n");
145 | sb.append("attempt to read the global variables SERVER and MBEAN\n");
146 | sb.append("and use them if no command-line option was specified.\n");
147 | sb.append("\n");
148 | sb.append("This is intended to work hand-in-hand with the Browse\n");
149 | sb.append("Mode: As one browses through the JMX namespace, these\n");
150 | sb.append("global variables will be constantly updated. Thus, one\n");
151 | sb.append("can flip back to shell mode and enter commands, flip\n");
152 | sb.append("back to browser modes and navigate, then flip back\n");
153 | sb.append("to shell mode, etc.\n");
154 | sb.append("\n");
155 | sb.append("Incidentally, to flip to Browse mode, just hit enter\n");
156 | sb.append("on an empty line. You will know you have left Shell\n");
157 | sb.append("Mode when you see a Browse-style prompt (usually a\n");
158 | sb.append("phrase followed by a colon, such as 'Select a domain:'\n");
159 | sb.append("=====================================================\n");
160 |
161 | System.out.println(sb.toString());
162 | }
163 |
164 | }
165 |
166 |
--------------------------------------------------------------------------------
/src/jmxsh/ConnectCmd.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 | /**
26 | * ConnectCmd.java
27 | *
28 | * Tcl Command to connect via JMX to a running process.
29 | *
30 | * @author robspassky
31 | */
32 |
33 | import org.apache.commons.cli.CommandLine;
34 | import org.apache.commons.cli.HelpFormatter;
35 | import org.apache.commons.cli.OptionBuilder;
36 | import org.apache.commons.cli.Options;
37 | import org.apache.commons.cli.ParseException;
38 | import org.apache.commons.cli.PosixParser;
39 | import org.apache.log4j.Logger;
40 |
41 | import tcl.lang.Command;
42 | import tcl.lang.Interp;
43 | import tcl.lang.TclException;
44 | import tcl.lang.TclObject;
45 |
46 |
47 |
48 | class ConnectCmd implements Command {
49 |
50 | private final static ConnectCmd instance = new ConnectCmd();
51 |
52 | static ConnectCmd getInstance() { return instance; }
53 |
54 | /** Initialize private variables. Setup the command-line options. */
55 | private ConnectCmd() {
56 | this.opts = new Options();
57 |
58 | this.opts.addOption(
59 | OptionBuilder.withLongOpt("server")
60 | .withDescription("Server to connect to (in the form of an URL).")
61 | .withArgName("SERVER")
62 | .hasArg()
63 | .create("s")
64 | );
65 |
66 | this.opts.addOption(
67 | OptionBuilder.withLongOpt("host")
68 | .withDescription("Host to connect to.")
69 | .withArgName("HOST")
70 | .hasArg()
71 | .create("h")
72 | );
73 |
74 | this.opts.addOption(
75 | OptionBuilder.withLongOpt("port")
76 | .withDescription("Port to connect to.")
77 | .withArgName("PORT")
78 | .hasArg()
79 | .create("p")
80 | );
81 |
82 | this.opts.addOption(
83 | OptionBuilder.withLongOpt("url_path")
84 | .withDescription("Path portion of the JMX Service URL.")
85 | .withArgName("PATH")
86 | .hasArg()
87 | .create("T")
88 | );
89 |
90 | this.opts.addOption(
91 | OptionBuilder.withLongOpt("user")
92 | .withArgName("USER")
93 | .hasArg()
94 | .withDescription("Connect with this username.")
95 | .create("U")
96 | );
97 |
98 | this.opts.addOption(
99 | OptionBuilder.withLongOpt("password")
100 | .withArgName("PASSWORD")
101 | .hasArg()
102 | .withDescription("Connect with this password.")
103 | .create("P")
104 | );
105 |
106 | this.opts.addOption(
107 | OptionBuilder.withLongOpt("help")
108 | .withDescription("Display usage help.")
109 | .hasArg(false)
110 | .create("?")
111 | );
112 |
113 | this.opts.addOption(
114 | OptionBuilder.withLongOpt("protocol")
115 | .withDescription("Choose a connection protocol (rmi|jmxmp), default rmi.")
116 | .hasArg(true)
117 | .withArgName("PROTOCOL")
118 | .create("R")
119 | );
120 | }
121 |
122 | private CommandLine parseCommandLine(TclObject argv[])
123 | throws ParseException {
124 |
125 | String[] args = new String[argv.length - 1];
126 |
127 | for(int i = 0; i < argv.length - 1; i++)
128 | args[i] = argv[i + 1].toString();
129 |
130 | CommandLine cl = (new PosixParser()).parse(this.opts, args);
131 | return cl;
132 | }
133 |
134 | private void connect(CommandLine commandLine) {
135 | String serverUrl = commandLine.getOptionValue("server");
136 | String host = commandLine.getOptionValue("host");
137 | String protocol = commandLine.getOptionValue("protocol", "rmi");
138 | String path = commandLine.getOptionValue("url_path");
139 | String user = commandLine.getOptionValue("user");
140 | String password = commandLine.getOptionValue("password");
141 | int port = -1;
142 | if (commandLine.hasOption("port")) {
143 | port = Integer.parseInt(commandLine.getOptionValue("port"));
144 | }
145 |
146 | if (Main.interactive) {
147 | Readline rl = Readline.getInstance();
148 |
149 | if (user != null && password == null) {
150 | password = rl.readline("Password: ", '*');
151 | }
152 | }
153 |
154 | if (serverUrl != null) {
155 | Jmx.getInstance().connect(serverUrl, user, password);
156 | }
157 | else {
158 | Jmx.getInstance().connect(host, port, protocol, path, user, password);
159 | }
160 | }
161 |
162 |
163 | public void cmdProc(Interp interp, TclObject argv[])
164 | throws TclException {
165 |
166 | try {
167 | CommandLine cl = parseCommandLine(argv);
168 |
169 | if (cl.hasOption("help")) {
170 | new HelpFormatter().printHelp (
171 | "jmx_connect ",
172 | "======================================================================",
173 | this.opts,
174 | "======================================================================",
175 | true
176 | );
177 |
178 | System.out.println("jmx_connect establishes a connection to a JMX server.");
179 | return;
180 | }
181 |
182 | this.connect(cl);
183 | }
184 | catch (ParseException e) {
185 | throw new TclException(interp, e.getMessage(), 1);
186 | }
187 | catch (RuntimeException e) {
188 | logger.error("Runtime Exception", e);
189 | throw new TclException(interp, "Runtime exception.", 1);
190 | }
191 | }
192 |
193 | private static Logger logger = Logger.getLogger(ConnectCmd.class);
194 | private Options opts;
195 |
196 | }
197 |
--------------------------------------------------------------------------------
/src/jmxsh/InvokeCmd.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 | import org.apache.log4j.Logger;
26 | import org.apache.commons.cli.*;
27 | import tcl.lang.*;
28 |
29 | /** Retrieve the value of an mbean's attribute. */
30 | class InvokeCmd implements Command {
31 |
32 | private final static InvokeCmd instance = new InvokeCmd();
33 |
34 | static InvokeCmd getInstance() { return instance; }
35 |
36 | /** Initialize private variables. Setup the command-line options. */
37 | private InvokeCmd() {
38 | this.opts = new Options();
39 |
40 | this.opts.addOption(
41 | OptionBuilder.withLongOpt("server")
42 | .withDescription("Server containing mbean.")
43 | .withArgName("SERVER")
44 | .hasArg()
45 | .create("s")
46 | );
47 |
48 | this.opts.addOption(
49 | OptionBuilder.withLongOpt("mbean")
50 | .withDescription("MBean containing attribute.")
51 | .withArgName("MBEAN")
52 | .hasArg()
53 | .create("m")
54 | );
55 |
56 | this.opts.addOption(
57 | OptionBuilder.withLongOpt("noconvert")
58 | .withDescription("Do not auto-convert the result to a Tcl string, instead create a java object reference.")
59 | .hasArg(false)
60 | .create("n")
61 | );
62 |
63 | this.opts.addOption(
64 | OptionBuilder.withLongOpt("help")
65 | .withDescription("Display usage help.")
66 | .hasArg(false)
67 | .create("?")
68 | );
69 | }
70 |
71 | private CommandLine parseCommandLine(TclObject argv[])
72 | throws ParseException {
73 |
74 | String[] args = new String[argv.length - 1];
75 |
76 | for(int i = 0; i < argv.length - 1; i++)
77 | args[i] = argv[i + 1].toString();
78 |
79 | CommandLine cl = (new PosixParser()).parse(this.opts, args);
80 | return cl;
81 | }
82 |
83 | private void getDefaults(Interp interp) {
84 | this.server = null;
85 | //this.domain = null;
86 | this.mbean = null;
87 | this.attrop = null;
88 |
89 | try {
90 | this.server = interp.getVar("SERVER", TCL.GLOBAL_ONLY).toString();
91 | //this.domain = interp.getVar("DOMAIN", TCL.GLOBAL_ONLY).toString();
92 | this.mbean = interp.getVar("MBEAN", TCL.GLOBAL_ONLY).toString();
93 | this.attrop = interp.getVar("ATTROP", TCL.GLOBAL_ONLY);
94 | }
95 | catch (TclException e) {
96 | /* If one doesn't exist, it will just be null. */
97 | }
98 |
99 | }
100 |
101 | public void cmdProc(Interp interp, TclObject argv[])
102 | throws TclException {
103 |
104 | try {
105 | CommandLine cl = parseCommandLine(argv);
106 | String args[] = cl.getArgs();
107 | String opname = null;
108 | TclObject opTclObj = null;
109 | Object[] params = null;
110 | String[] signature = null;
111 |
112 | if (cl.hasOption("help")) {
113 | new HelpFormatter().printHelp (
114 | "jmx_invoke [-?] [-n] [-s server] [-m mbean] [OPERATION] [ARGS]",
115 | "======================================================================",
116 | this.opts,
117 | "======================================================================",
118 | false
119 | );
120 |
121 | System.out.println("jmx_invoke executes an operation on a remote mbean, returning the result");
122 | System.out.println("(if any).");
123 | System.out.println("");
124 | System.out.println("If you specify -n, then the return will be a Java/Tcl java");
125 | System.out.println("object reference. See the Java/Tcl documentation on the");
126 | System.out.println("internet for more details.");
127 | System.out.println("");
128 | System.out.println("If there are multiple operations with the same name in the mbean, you can");
129 | System.out.println("disambiguate by specifying 'operation' as a tcl list of the operation name");
130 | System.out.println("and the java types of its parameters.");
131 | System.out.println(" e.g., ");
132 | System.out.println(" jmx_invoke -m $MBEAN [hello java.lang.Integer java.lang.String] arg1 arg2");
133 | System.out.println(" jmx_invoke -m $MBEAN [hello java.lang.String java.lang.String] arg1 arg2");
134 | System.out.println(" Invoke two different operations, both named 'hello'.");
135 | return;
136 | }
137 |
138 | getDefaults(interp);
139 |
140 | this.server = cl.getOptionValue("server", this.server);
141 | this.mbean = cl.getOptionValue("mbean", this.mbean);
142 |
143 | logger.debug("argv length:" + argv.length);
144 | logger.debug("args length:" + args.length);
145 | logger.debug("offset :" + args.length);
146 |
147 | if (this.server == null) {
148 | throw new TclException(interp, "No server specified; please set SERVER variable or use -s option.", TCL.ERROR);
149 | }
150 |
151 | if (this.mbean == null) {
152 | throw new TclException(interp, "No mbean specified; please set MBEAN variable or use -m option.", TCL.ERROR);
153 | }
154 |
155 | int offset = argv.length - args.length;
156 | if (args.length > 0) {
157 | opTclObj = argv[offset];
158 | offset++;
159 | }
160 | else {
161 | opTclObj = this.attrop;
162 | }
163 |
164 | if (opTclObj == null) {
165 | throw new TclException(interp, "No operation specified; please set ATTROP variable or add it to the command line.", TCL.ERROR);
166 | }
167 |
168 | //int num_params = argv.length - offset;
169 |
170 | opname = TclList.index(interp, opTclObj, 0).toString();
171 | if (TclList.getLength(interp, opTclObj) > 1) {
172 | signature = new String[TclList.getLength(interp, opTclObj)-1];
173 | for (int i=1; i connectors;
46 |
47 | private Jmx() {
48 | this.connectors = new HashMap();
49 | }
50 |
51 |
52 | public String[] getServers() {
53 | return this.connectors.keySet().toArray(EMPTY_STRING_ARRAY);
54 | }
55 |
56 |
57 | public String[] getDomains(String server, String regex) {
58 | try {
59 | Vector result = new Vector();
60 | String[] domains = getMBSC(server).getDomains();
61 | if (domains == null) {
62 | domains = EMPTY_STRING_ARRAY;
63 | }
64 | for (String domain : domains) {
65 | if (regex.length() == 0 || domain.matches(regex)) {
66 | result.add(domain);
67 | }
68 | }
69 | return result.toArray(EMPTY_STRING_ARRAY);
70 | }
71 | catch (IOException e) {
72 | logger.error("Error getting domains.", e);
73 | throw new IllegalArgumentException("Unable to get domains for " + server + ".", e);
74 | }
75 | }
76 |
77 |
78 | public String[] getDomains(String server) {
79 | return getDomains(server, ".*");
80 | }
81 |
82 | public void close(String server) {
83 | try {
84 | this.connectors.get(server).close();
85 | this.connectors.remove(server);
86 | JInterp.unsetGlobal("SERVERS", server);
87 | }
88 | catch (IOException e) {
89 | logger.error("Error closing connection.", e);
90 | throw new IllegalArgumentException("Error closing connection.", e);
91 | }
92 | }
93 |
94 |
95 | public String[] getMBeans(String server, String domain, String regex) {
96 | try {
97 | ObjectName wildcardQuery = getObjectName(domain + ":*");
98 | Set> mbeans = getMBSC(server).queryNames(wildcardQuery, null);
99 | Vector result = new Vector();
100 | for (Object mbean : mbeans) {
101 | String name = ((ObjectName) mbean).toString();
102 | if (regex.length() == 0 || name.matches(regex)) {
103 | result.add(name);
104 | }
105 | }
106 | return result.toArray(EMPTY_STRING_ARRAY);
107 | }
108 | catch (IOException e) {
109 | logger.error("Error getting mbeans.", e);
110 | throw new IllegalArgumentException("Error getting mbeans.");
111 | }
112 | }
113 |
114 | public String[] getMBeans(String server, String domain) {
115 | return getMBeans(server, domain, ".*");
116 | }
117 |
118 | public MBeanOperationInfo getOperationInfo(String server, String mbean, String opname) {
119 | MBeanOperationInfo[] operations = getMBI(server, mbean).getOperations();
120 | for (MBeanOperationInfo operation : operations) {
121 | if (operation.getName().equals(opname)) {
122 | return operation;
123 | }
124 | }
125 | return null;
126 | }
127 |
128 | public MBeanOperationInfo[] getOperations(String server, String mbean) {
129 | return getMBI(server, mbean).getOperations();
130 | }
131 |
132 | public String[] getSignature(String server, String mbean, String opname) {
133 | MBeanOperationInfo info = getOperationInfo(server, mbean, opname);
134 |
135 | if (info == null) {
136 | throw new IllegalArgumentException("Could not find operation " + opname);
137 | }
138 |
139 | MBeanParameterInfo[] params = info.getSignature();
140 | String[] signature = new String[params.length];
141 | for (int i=0; i credentials = null;
369 | JMXConnector connector = this.connectors.get(url.toString());
370 |
371 | if (connector != null) {
372 | if (Main.interactive) {
373 | System.out.println("Already connected.");
374 | }
375 | return;
376 | }
377 |
378 | try {
379 | if (user != null) {
380 | credentials = new HashMap();
381 | credentials.put(JMXConnector.CREDENTIALS, new String[] { user, password });
382 | }
383 |
384 | String urlStr = url.toString();
385 | connector = JMXConnectorFactory.connect(url, credentials);
386 | this.connectors.put(urlStr, connector);
387 | JInterp.setGlobal("SERVER", urlStr);
388 | JInterp.setGlobal("SERVERS", urlStr, urlStr);
389 | BrowseMode.instance.setDomainMenuLevel();
390 | if (Main.interactive) {
391 | System.out.println("Connected to " + urlStr + ".");
392 | }
393 | }
394 | catch (SecurityException e) {
395 | logger.error("Connection error.", e);
396 | throw new IllegalArgumentException("Authentication error: " + e.getMessage());
397 | }
398 | catch (IOException e) {
399 | logger.error("Connection error.", e);
400 | try {
401 | if (e.getCause().getClass() == Class.forName("javax.naming.ConfigurationException")) {
402 | throw new IllegalArgumentException("Host name not found.");
403 | }
404 | if (e.getCause().getClass() == Class.forName("javax.naming.ServiceUnavailableException")) {
405 | throw new IllegalArgumentException("Nothing is listening on that port, or it's firewalled off.");
406 | }
407 | if (e.getCause().getClass() == Class.forName("javax.naming.CommunicationException")) {
408 | throw new IllegalArgumentException("Timed out. Probably some non-JMX process is listening on it.");
409 | }
410 | if (e.getCause().getClass() == Class.forName("javax.net.ssl.SSLHandshakeException")) {
411 | throw new IllegalStateException("Host is using SSL, set the appropriate System Properties to connect to it.");
412 | }
413 | if (e.getCause().getClass() == Class.forName("java.net.ConnectException")) {
414 | throw new IllegalStateException("Connection refused.");
415 | }
416 | }
417 |
418 | catch (java.lang.ClassNotFoundException ee) {
419 | // Do nothing, fall through to default error message.
420 | }
421 |
422 | throw new IllegalStateException("Network error, see log.");
423 | }
424 | }
425 |
426 |
427 | }
428 |
--------------------------------------------------------------------------------
/src/jmxsh/Main.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 | import org.apache.commons.cli.*;
26 | import org.apache.log4j.*;
27 | import java.io.IOException;
28 | import java.util.Date;
29 |
30 |
31 | /**
32 | Wrapper class for main() function of jmxsh.
33 |
34 | This class must be public because it is not invoked directly by
35 | java. Instead, the One-Jar code is executed by the java
36 | command-line, which then calls this main() function.
37 | */
38 | public final class Main {
39 |
40 | // Change this version information before a release.
41 | static final String VERSION = "1.0";
42 | static final long EPOCH_DATE = 1201018992L; // Get with date +"%s"
43 | static final String CODENAME = "ERETRIA";
44 | static final Date DATE = new Date(EPOCH_DATE*1000);
45 |
46 | static final protected Logger logger = Logger.getLogger(Main.class);
47 | static boolean interactive = false;
48 |
49 | protected boolean historyEnabled;
50 | protected CommandLine commandLine;
51 |
52 | private Options makeCommandLineOptions() {
53 |
54 | Options opts = new Options();
55 |
56 | opts.addOption(
57 | OptionBuilder.withLongOpt("server")
58 | .withDescription("JMX Service URL of remote JMX service.")
59 | .withArgName("SERVER")
60 | .hasArg()
61 | .create("s")
62 | );
63 |
64 | opts.addOption(
65 | OptionBuilder.withLongOpt("host")
66 | .withDescription("Hostname or IP address of remote JMX service.")
67 | .withArgName("HOST")
68 | .hasArg()
69 | .create("h")
70 | );
71 |
72 | opts.addOption(
73 | OptionBuilder.withLongOpt("port")
74 | .withDescription("Port of remote JMX service.")
75 | .withArgName("PORT")
76 | .hasArg()
77 | .create("p")
78 | );
79 |
80 | opts.addOption(
81 | OptionBuilder.withLongOpt("url_path")
82 | .withDescription("Path portion of the JMX Service URL.")
83 | .withArgName("PATH")
84 | .hasArg()
85 | .create("T")
86 | );
87 |
88 | opts.addOption(
89 | OptionBuilder.withLongOpt("user")
90 | .withArgName("USER")
91 | .hasArg()
92 | .withDescription("Connect with this username.")
93 | .create("U")
94 | );
95 |
96 | opts.addOption(
97 | OptionBuilder.withLongOpt("password")
98 | .withArgName("PASSWORD")
99 | .hasArg()
100 | .withDescription("Connect with this password.")
101 | .create("P")
102 | );
103 |
104 | opts.addOption(
105 | OptionBuilder.withLongOpt("debug")
106 | .withDescription("Verbose logging.")
107 | .hasArg(false)
108 | .create("d")
109 | );
110 |
111 | opts.addOption(
112 | OptionBuilder.withLongOpt("logfile")
113 | .withDescription("Log information to this file.")
114 | .withArgName("LOGFILE")
115 | .hasArg()
116 | .create("l")
117 | );
118 |
119 | opts.addOption(
120 | OptionBuilder.withLongOpt("version")
121 | .hasArg(false)
122 | .withDescription("Show version information.")
123 | .create("v")
124 | );
125 |
126 | opts.addOption(
127 | OptionBuilder.withLongOpt("help")
128 | .withDescription("Display usage help.")
129 | .hasArg(false)
130 | .create("?")
131 | );
132 |
133 | opts.addOption(
134 | OptionBuilder.withLongOpt("protocol")
135 | .withDescription("Choose a connection protocol (rmi|jmxmp), default rmi.")
136 | .hasArg(true)
137 | .withArgName("PROTOCOL")
138 | .create("R")
139 | );
140 |
141 | opts.addOption(
142 | OptionBuilder.withLongOpt("include")
143 | .withDescription("Source this file. May be specified multiple times. [N.B. Do not make this the last option, because of a bug in CLI parsing library.]")
144 | .withArgName("FILE")
145 | .hasArg()
146 | .hasArgs()
147 | .create("i")
148 | );
149 |
150 | opts.addOption(
151 | OptionBuilder.withLongOpt("interactive")
152 | .withDescription("Always go into interactive mode, even if executing a script.")
153 | .hasArg(false)
154 | .create("I")
155 | );
156 |
157 | opts.addOption(
158 | OptionBuilder.withLongOpt("browse")
159 | .withDescription("Start interactive session in browser mode.")
160 | .hasArg(false)
161 | .create("b")
162 | );
163 |
164 | opts.addOption(
165 | OptionBuilder.withLongOpt("nohistory")
166 | .withDescription("Do not save history.")
167 | .hasArg(false)
168 | .create("n")
169 | );
170 |
171 | opts.addOption(
172 | OptionBuilder.withLongOpt("historyfile")
173 | .withDescription("Use this file to save history (default $HOME/.jmxsh_history).")
174 | .hasArg(true)
175 | .withArgName("HISTORYFILE")
176 | .create("H")
177 | );
178 |
179 | return opts;
180 | }
181 |
182 |
183 | private void showVersion() {
184 |
185 | System.out.println("jmxsh " + Main.VERSION + " (" + Main.CODENAME + "), " + Main.DATE + ". #69108");
186 | System.out.println("");
187 | System.out.println("Brought to you by the letter 'X', and the number 25.");
188 | System.out.println("");
189 | System.out.println("\"There was a point to this story, but it has temporarily ");
190 | System.out.println(" escaped the chronicler's mind.\"");
191 | System.out.println(" -- Douglas Adams");
192 |
193 | }
194 |
195 |
196 | private void showUsage(Options opts) {
197 |
198 | System.out.println("Start a command-line interface to a JMX service provider.");
199 | System.out.println("The first non-option argument, if present, is the");
200 | System.out.println("file name of a script to execute. Any remaining arguments");
201 | System.out.println("are passed 'argv' elements to the script.");
202 | System.out.println("");
203 | System.out.println("If no script file is specified, or if the -I option was specified,");
204 | System.out.println("then an interactive session will be started.");
205 | System.out.println("");
206 |
207 | new HelpFormatter().printHelp("java -jar jmxsh.jar [OPTIONS] -h host -p port [FILENAME ARGS]",
208 | "=========================================================================",
209 | opts,
210 | "=========================================================================",
211 | false);
212 |
213 | }
214 |
215 |
216 | private void connect() {
217 | String server = commandLine.getOptionValue("server");
218 | String host = commandLine.getOptionValue("host");
219 | String protocol = commandLine.getOptionValue("protocol", "rmi");
220 | String path = commandLine.getOptionValue("url_path");
221 | String user = commandLine.getOptionValue("user");
222 | String password = commandLine.getOptionValue("password");
223 | int port = Integer.parseInt(commandLine.getOptionValue("port"));
224 |
225 | try {
226 | if (user == null && password != null) {
227 | user = Readline.getInstance().readline("User: ");
228 | }
229 |
230 | if (password == null && user != null) {
231 | password = Readline.getInstance().readline("Password: ", '*');
232 | }
233 |
234 | if (server == null) {
235 | Jmx.getInstance().connect(host, port, protocol, path, user, password);
236 | }
237 | else {
238 | Jmx.getInstance().connect(server, user, password);
239 | }
240 | BrowseMode.instance.setDomainMenuLevel();
241 | }
242 | catch (RuntimeException e) {
243 | System.err.println("Failed to connect to " + host + ", port " + port + ": " + e.getMessage());
244 | System.exit(1);
245 | }
246 | }
247 |
248 |
249 | /**
250 | Entry-point when jmxsh is executed.
251 |
252 | Parses command line options, evaluates tcl files, then goes to
253 | interactive mode if desired.
254 |
255 | @param args Command line arguments passed to jmxsh.
256 | */
257 | public static void main(String[] args) {
258 |
259 | Main mainObj = new Main();
260 |
261 | try {
262 | mainObj.run(args);
263 | }
264 | catch (RuntimeException e) {
265 | System.err.println("Error: " + e.getMessage());
266 | logger.fatal("Runtime Exception received in main(): " + e.getMessage(), e);
267 | System.exit(1);
268 | }
269 |
270 | System.exit(0);
271 |
272 | }
273 |
274 | void run(String[] args) {
275 |
276 | // 1. Parse the command line options.
277 |
278 | Options opts = makeCommandLineOptions();
279 |
280 | try {
281 | commandLine = new PosixParser().parse(opts, args, true);
282 | }
283 | catch (ParseException e) {
284 | showUsage(opts);
285 | System.err.println("Usage error: " + e.getMessage());
286 | System.exit(1);
287 | }
288 |
289 | String logfile = commandLine.getOptionValue("logfile", "/dev/null");
290 | try {
291 | BasicConfigurator.configure(new FileAppender(new PatternLayout("%r [%t] %-5p %c %x - %m%n"), logfile));
292 | }
293 | catch (IOException e) {
294 | System.err.println("Unable to open logfile: " + e.getMessage());
295 | System.exit(1);
296 | }
297 |
298 | if (commandLine.hasOption("help")) {
299 | showUsage(opts);
300 | System.exit(0);
301 | }
302 |
303 | if (commandLine.hasOption("version")) {
304 | showVersion();
305 | System.exit(0);
306 | }
307 |
308 | if (commandLine.hasOption("debug")) {
309 | Logger.getRootLogger().setLevel(Level.ALL);
310 | }
311 |
312 | // 2. Make any specified JMX connections.
313 |
314 | if (commandLine.hasOption("host") && commandLine.hasOption("port")) {
315 | connect();
316 | }
317 |
318 | // 4. Source in any include files.
319 |
320 | String[] includeFiles = commandLine.getOptionValues("include");
321 | if (includeFiles != null) {
322 | for (String filename: commandLine.getOptionValues("include")) {
323 | logger.debug("Including " + filename);
324 | JInterp.evaluateFile(filename);
325 | }
326 | }
327 |
328 | // 5a. If script file name provided, run it and exit.
329 |
330 | String[] scriptArgs = commandLine.getArgs();
331 |
332 | if (scriptArgs.length > 0) {
333 | String scriptName = scriptArgs[0];
334 |
335 | JInterp.setGlobal("argv0", scriptName);
336 | JInterp.setGlobal("argv", scriptArgs, 1);
337 | JInterp.setGlobal("argc", scriptArgs.length-1);
338 |
339 | JInterp.evaluateFile(scriptName);
340 |
341 | if (!commandLine.hasOption("interactive")) {
342 | System.exit(0);
343 | }
344 | }
345 |
346 | // 5b. Otherwise, start interactive session.
347 |
348 | interactive = true;
349 | historyEnabled = true;
350 | if (commandLine.hasOption("nohistory")) {
351 | historyEnabled = false;
352 | }
353 |
354 | ConsoleThread thread = new ConsoleThread();
355 | thread.setDaemon(true);
356 | thread.start();
357 |
358 | JInterp.processTclEvents();
359 |
360 | System.exit(0);
361 | }
362 |
363 | class ConsoleThread extends Thread {
364 |
365 | private Mode mode;
366 |
367 | public ConsoleThread() {
368 | setName("ConsoleThread");
369 | String filename = commandLine.getOptionValue("historyfile", System.getenv("HOME") + "/.jmxsh_history");
370 | if (historyEnabled == true) {
371 | try {
372 | Readline.getInstance().setHistoryFile(filename);
373 | }
374 | catch (IllegalArgumentException e) {
375 | System.out.println("History file " + filename + " not writable, command-line history disabled.");
376 | historyEnabled = false;
377 | }
378 | }
379 | mode = null;
380 | }
381 |
382 | private void switchMode() {
383 | if (mode == Mode.getBrowseModeInstance()) {
384 | System.out.println("Entering shell mode.");
385 | mode = Mode.getShellModeInstance();
386 | }
387 | else {
388 | System.out.println("Entering browse mode.");
389 | mode = Mode.getBrowseModeInstance();
390 | }
391 | }
392 |
393 | public synchronized void run() {
394 |
395 | try {
396 |
397 | System.out.println("jmxsh v" + Main.VERSION + ", " + Main.DATE + "\n");
398 | System.out.println("Type 'help' for help. Give the option '-?' to any command");
399 | System.out.println("for usage help.\n");
400 |
401 | if (commandLine.hasOption("browse")) {
402 | System.out.println("Starting up in browser mode.");
403 | mode = Mode.getBrowseModeInstance();
404 | } else {
405 | System.out.println("Starting up in shell mode.");
406 | mode = Mode.getShellModeInstance();
407 | }
408 |
409 | String lastResult = "";
410 | while (true) {
411 |
412 | System.out.print(mode.getPrePromptDisplay());
413 |
414 | String line = Readline.getInstance().readline(mode.getPrompt() + " ");
415 |
416 | if (line == null) {
417 | System.exit(0);
418 | }
419 | else if (line.length() == 0) {
420 | switchMode();
421 | continue;
422 | }
423 | else if (line.equals("help")) {
424 | mode.displayHelp();
425 | continue;
426 | }
427 |
428 | String result = mode.handleInput(line);
429 |
430 | if (historyEnabled && result != null && !result.equals(lastResult)) {
431 | Readline.getInstance().addToHistory(result);
432 | lastResult = result;
433 | }
434 | }
435 | }
436 | catch (RuntimeException e) {
437 | logger.error("Runtime exception caught.", e);
438 | System.err.println("Exception caught: " + e.getMessage());
439 | }
440 | }
441 | }
442 |
443 | }
444 |
445 |
--------------------------------------------------------------------------------
/src/jmxsh/BrowseMode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * $URL$
3 | *
4 | * $Revision$
5 | *
6 | * $LastChangedDate$
7 | *
8 | * $LastChangedBy$
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | *
22 | */
23 | package jmxsh;
24 |
25 | /**
26 | * BrowseMode.java
27 | *
28 | * Implements a menu-based browsing mode of the JMX namespace.
29 | *
30 | * @author robspassky
31 | */
32 |
33 | import java.util.ArrayList;
34 | import java.util.List;
35 |
36 | import javax.management.MBeanAttributeInfo;
37 | import javax.management.MBeanOperationInfo;
38 | import javax.management.MBeanParameterInfo;
39 |
40 | import org.apache.log4j.Logger;
41 | import org.apache.oro.text.GlobCompiler;
42 | import org.apache.oro.text.regex.MalformedPatternException;
43 | import org.apache.oro.text.regex.Pattern;
44 | import org.apache.oro.text.regex.PatternCompiler;
45 | import org.apache.oro.text.regex.PatternMatcher;
46 | import org.apache.oro.text.regex.Perl5Matcher;
47 |
48 | import tcl.lang.TclException;
49 | import tcl.lang.TclList;
50 | import tcl.lang.TclObject;
51 | import tcl.lang.TclString;
52 |
53 | class BrowseMode extends Mode {
54 |
55 | enum Menu { ATTRIBUTE, ATTROP, DOMAIN, MBEAN, NONE, OPERATION, SERVER }
56 |
57 | static BrowseMode instance = new BrowseMode();
58 |
59 | static private PatternCompiler GLOB_COMPILER = new GlobCompiler();
60 | static private Logger logger = Logger.getLogger(BrowseMode.class);
61 | static private PatternMatcher PERL5_MATCHER = new Perl5Matcher();
62 |
63 | private List attributes;
64 | private Menu currentMenu;
65 |
66 | private String[] items;
67 | private int maxChoice;
68 | private List operations;
69 | private Pattern pattern;
70 | private String prompt;
71 |
72 | private BrowseMode() {
73 | this.prompt = "";
74 | this.currentMenu = Menu.SERVER;
75 | this.pattern = null;
76 | this.attributes = new ArrayList();
77 | this.operations = new ArrayList();
78 | this.maxChoice = 0;
79 | }
80 |
81 | void accessAttribute(MBeanAttributeInfo attr) {
82 | Context context = Context.fromTcl();
83 | Object value = Jmx.getInstance().getAttribute(context.server, context.mbean, attr.getName());
84 |
85 | System.out.println("=====================================================\n");
86 | System.out.printf(" Accessing Attribute %s\n\n", attr.getName());
87 | System.out.printf("%s = %s\n\n", attr.getName(), value.toString());
88 |
89 | if (attr.isWritable()) {
90 | System.out.println("Enter a new value for this attribute, or hit enter to leave it unchanged.");
91 | this.prompt = String.format("New value (%1$s): ", TypeName.translateClassName(attr.getType()));
92 | String newValue = Readline.getInstance().readline(this.prompt);
93 | if (newValue != null && newValue.length() > 0) {
94 | Jmx.getInstance().setAttribute(
95 | context.server,
96 | context.mbean,
97 | attr.getName(),
98 | TclString.newInstance(newValue)
99 | );
100 | System.out.println("Value changed.");
101 | }
102 | else {
103 | System.out.println("Value not changed.");
104 | }
105 | }
106 | Readline.getInstance().readline("Press enter to continue.");
107 | }
108 |
109 | void displayHelp() {
110 | StringBuilder sb = new StringBuilder(1000);
111 |
112 | sb.append("=====================================================\n");
113 | sb.append(" Browse Mode Help\n");
114 | sb.append("\n");
115 | sb.append("This mode is a tree browser of the JMX namespace. It\n");
116 | sb.append("is menu-driven, so there are no commands to memorize.\n");
117 | sb.append("\n");
118 | sb.append("At most times, you will be presented with a list of\n");
119 | sb.append("JMX objects. You can select one by number and that\n");
120 | sb.append("will result in descending the tree, and opening a new\n");
121 | sb.append("menu of choices.\n");
122 | sb.append("\n");
123 | sb.append("Besides entering a number, you can enter the words 'up'\n");
124 | sb.append("or 'down' (or 'u' or 'd') and you will return to the\n");
125 | sb.append("move a level up or down in the browsing hierarchy, based\n");
126 | sb.append("on your browsing history.\n");
127 | sb.append("\n");
128 | sb.append("If you enter some other non-numerical string,\n");
129 | sb.append("that string will be treated as a glob pattern (case-\n");
130 | sb.append("insensitive, with *'s prefixed and suffixed) and applied\n");
131 | sb.append("to the current listing of JMX items.\n");
132 | sb.append("\n");
133 | sb.append("To clear a glob currently in effect, enter a single space\n");
134 | sb.append("and hit enter.\n");
135 | sb.append("\n");
136 | sb.append("As you browse, the current SERVER, DOMAIN, MBEAN, and\n");
137 | sb.append("ATTROP (attribute or operation) values will be shown.\n");
138 | sb.append("These represent actual global variables in the Tcl\n");
139 | sb.append("session that will be usable when you leave Browse mode.\n");
140 | sb.append("\n");
141 | sb.append("To leave the Browse mode, press enter at an empty line.\n");
142 | sb.append("You will know you have left when you see the Shell prompt,\n");
143 | sb.append("'% '\n");
144 | sb.append("=====================================================\n");
145 |
146 | System.out.println(sb.toString());
147 | Readline.getInstance().readline("Press enter to continue.");
148 | }
149 |
150 | private String getAttropMenu() {
151 | StringBuilder msb = new StringBuilder(1000);
152 | Context context = Context.fromTcl();
153 |
154 | this.attributes.clear();
155 | this.operations.clear();
156 |
157 | MBeanAttributeInfo[] attrArray = Jmx.getInstance().getAttributes(context.server, context.mbean);
158 | MBeanOperationInfo[] operArray = Jmx.getInstance().getOperations(context.server, context.mbean);
159 |
160 | int i = 0;
161 |
162 | msb.append(" Attribute List:\n\n");
163 |
164 | for (MBeanAttributeInfo attr : attrArray) {
165 | if (this.pattern != null && !PERL5_MATCHER.matches(attr.getName(), this.pattern))
166 | continue;
167 |
168 | this.attributes.add(attr);
169 |
170 | StringBuilder sb = new StringBuilder(100);
171 | sb.append(attr.isIs() ? "i" : "-");
172 | sb.append(attr.isReadable() ? "r" : "-");
173 | sb.append(attr.isWritable() ? "w" : "-");
174 | sb.append(" ");
175 | String typename = TypeName.translateClassName(attr.getType());
176 | sb.append(typename);
177 | int numSpaces = 5 - (typename.length() % 5);
178 | if (typename.length() < 5) {
179 | numSpaces += 5;
180 | }
181 | for (int j=0; j 0)
191 | msb.append("\n Operation List:\n\n");
192 |
193 | for (MBeanOperationInfo op : operArray) {
194 | if (this.pattern != null && !PERL5_MATCHER.matches(op.getName(), this.pattern))
195 | continue;
196 |
197 | this.operations.add(op);
198 |
199 | StringBuilder namesb = new StringBuilder(50);
200 | MBeanParameterInfo[] params = op.getSignature();
201 | StringBuilder sb = new StringBuilder(100);
202 | TclObject paramTclList = TclList.newInstance();
203 |
204 | String typename = TypeName.translateClassName(op.getReturnType());
205 | sb.append(typename);
206 | int numSpaces = 5 - (typename.length() % 5);
207 | if (typename.length() < 5) {
208 | numSpaces += 5;
209 | }
210 | for (int j=0; j menu = new ArrayList();
283 | for (String item: this.items) {
284 | if (this.pattern == null || PERL5_MATCHER.matches(item, this.pattern)) {
285 | menu.add(item);
286 | }
287 | }
288 |
289 | this.items = new String[menu.size()];
290 | this.items = menu.toArray(this.items);
291 |
292 | for (int i=1; i<=this.items.length; i++) {
293 | sb.append(String.format(" %1$3d. %2$s\n", i, this.items[i-1]));
294 | }
295 |
296 | if (this.items.length == 0) {
297 | sb.append("\n ((((( No options available.\n\n");
298 | this.prompt = "(no options available):";
299 | }
300 |
301 | this.maxChoice = this.items.length;
302 | return sb.toString();
303 | }
304 |
305 | String getPrePromptDisplay() {
306 |
307 | StringBuilder sb = new StringBuilder(1000);
308 |
309 | sb.append("====================================================\n\n");
310 |
311 | switch (this.currentMenu) {
312 |
313 | case SERVER:
314 | sb.append(" Available Servers:\n\n");
315 | sb.append(getMenu());
316 | break;
317 |
318 | case DOMAIN:
319 | sb.append(" Available Domains:\n\n");
320 | sb.append(getMenu());
321 | break;
322 |
323 | case MBEAN:
324 | sb.append(" Available MBeans:\n\n");
325 | sb.append(getMenu());
326 | break;
327 |
328 | case ATTROP:
329 | sb.append(getAttropMenu());
330 | break;
331 |
332 | default:
333 | throw new IllegalStateException("Bad menu state.");
334 |
335 | }
336 |
337 |
338 | Context context = Context.fromTcl();
339 | if (context.server != null) {
340 | sb.append("\n SERVER: ");
341 | sb.append(context.server);
342 | }
343 | if (context.domain != null) {
344 | sb.append("\n DOMAIN: ");
345 | sb.append(context.domain);
346 | }
347 | if (context.mbean != null) {
348 | sb.append("\n MBEAN: ");
349 | sb.append(context.mbean);
350 | }
351 | if (context.attrop != null) {
352 | sb.append("\n ATTROP: ");
353 | sb.append(context.attrop);
354 | }
355 | if (this.pattern != null) {
356 | String pattstr = this.pattern.getPattern();
357 | pattstr = pattstr.substring(2, pattstr.length()-2);
358 | sb.append("\n GLOB: ");
359 | sb.append("*" + pattstr + "*");
360 | sb.append(" (space to clear)");
361 | }
362 |
363 | sb.append("\n\n====================================================\n");
364 |
365 | return sb.toString();
366 | }
367 |
368 | String getPrompt() {
369 | return this.prompt;
370 | }
371 |
372 | String handleInput(String input) {
373 | if (input.equals("up") || input.equals("u")) {
374 | switch (this.currentMenu) {
375 | case SERVER:
376 | break;
377 | case DOMAIN:
378 | this.currentMenu = Menu.SERVER;
379 | break;
380 | case MBEAN:
381 | this.currentMenu = Menu.DOMAIN;
382 | break;
383 | case ATTROP:
384 | this.currentMenu = Menu.MBEAN;
385 | break;
386 | case ATTRIBUTE:
387 | case OPERATION:
388 | this.currentMenu = Menu.ATTROP;
389 | this.attributes.clear();
390 | this.operations.clear();
391 | break;
392 | default:
393 | break;
394 | }
395 | return null;
396 | }
397 |
398 | if (input.equals("down") || input.equals("d")) {
399 | switch (this.currentMenu) {
400 | case SERVER:
401 | this.currentMenu = Menu.DOMAIN;
402 | break;
403 | case DOMAIN:
404 | this.currentMenu = Menu.MBEAN;
405 | break;
406 | case MBEAN:
407 | this.currentMenu = Menu.ATTROP;
408 | break;
409 | case ATTROP:
410 | break;
411 | case ATTRIBUTE:
412 | case OPERATION:
413 | this.currentMenu = Menu.ATTROP;
414 | break;
415 | default:
416 | break;
417 | }
418 | return null;
419 | }
420 |
421 | int choice = 0;
422 |
423 | try {
424 | choice = Integer.parseInt(input);
425 | }
426 | catch (NumberFormatException e) {
427 | if (input.equals(" ")) {
428 | this.pattern = null;
429 | }
430 | else {
431 | try {
432 | this.pattern = GLOB_COMPILER.compile("*" + input + "*", GlobCompiler.CASE_INSENSITIVE_MASK);
433 | }
434 | catch (MalformedPatternException me) {
435 | System.out.println("Invalid glob pattern '" + input + "' - " + me.getMessage());
436 | this.pattern = null;
437 | }
438 | }
439 | return null;
440 | }
441 |
442 | if (choice < 1 || choice > this.maxChoice) {
443 | System.out.printf("Please make a choice between %d and %d.\n", 1, this.maxChoice);
444 | Readline.getInstance().readline("Press enter to continue.");
445 | return null;
446 | }
447 |
448 | switch (this.currentMenu) {
449 | case SERVER:
450 | JInterp.setGlobal("SERVER", this.items[choice-1]);
451 | JInterp.unsetGlobal("DOMAIN");
452 | JInterp.unsetGlobal("MBEAN");
453 | JInterp.unsetGlobal("ATTROP");
454 | this.currentMenu = Menu.DOMAIN;
455 | break;
456 | case DOMAIN:
457 | JInterp.setGlobal("DOMAIN", this.items[choice-1]);
458 | this.currentMenu = Menu.MBEAN;
459 | JInterp.unsetGlobal("MBEAN");
460 | JInterp.unsetGlobal("ATTROP");
461 | break;
462 | case MBEAN:
463 | JInterp.setGlobal("MBEAN", this.items[choice-1]);
464 | this.currentMenu = Menu.ATTROP;
465 | JInterp.unsetGlobal("ATTROP");
466 | break;
467 | case ATTROP:
468 | if (choice > this.attributes.size()) {
469 | choice = choice - this.attributes.size();
470 | JInterp.setGlobal("ATTROP", this.operations.get(choice-1).getName());
471 | invokeOperation(this.operations.get(choice-1));
472 | }
473 | else {
474 | JInterp.setGlobal("ATTROP", this.attributes.get(choice-1).getName());
475 | accessAttribute(this.attributes.get(choice-1));
476 | }
477 | break;
478 | default:
479 | throw new IllegalStateException("Unsupported menu action.");
480 | }
481 |
482 | return null;
483 | }
484 |
485 | void invokeOperation(MBeanOperationInfo op) {
486 | MBeanParameterInfo[] signature = op.getSignature();
487 | String[] paramTypes = new String[signature.length];
488 |
489 | Context context = Context.fromTcl();
490 |
491 | System.out.println("=====================================================\n");
492 | System.out.printf(" Invoking Operation %s\n\n", op.getName());
493 |
494 | if (signature.length > 0) {
495 | System.out.println("Please enter values for " + signature.length + " parameters.");
496 | }
497 |
498 | Object[] parameters = new Object[signature.length];
499 | for (int i=0; i