This commit is contained in:
Jesper Wilhelmsson 2015-02-05 12:23:29 +01:00
commit ad23789419
45 changed files with 3046 additions and 303 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -44,15 +44,22 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("SymbolTable");
theTableField = type.getAddressField("_the_table");
sharedTableField = type.getAddressField("_shared_table");
}
// Fields
private static AddressField theTableField;
private static AddressField sharedTableField;
private CompactHashTable sharedTable;
// Accessors
public static SymbolTable getTheTable() {
Address tmp = theTableField.getValue();
return (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
SymbolTable table = (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
Address shared = sharedTableField.getStaticFieldAddress();
table.sharedTable = (CompactHashTable)VMObjectFactory.newObject(CompactHashTable.class, shared);
return table;
}
public SymbolTable(Address addr) {
@ -73,8 +80,9 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
/** Clone of VM's "temporary" probe routine, as the SA currently
does not support mutation so lookup() would have no effect
anyway. Returns null if the given string is not in the symbol
table. */
anyway. Searches the regular symbol table and the shared symbol
table. Null is returned if the given name is not found in both
tables. */
public Symbol probe(byte[] name) {
long hashValue = hashSymbol(name);
for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) {
@ -85,7 +93,8 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
}
}
}
return null;
return sharedTable.probe(name, hashValue);
}
public interface SymbolVisitor {

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.utilities.*;
public class CompactHashTable extends VMObject {
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("SymbolCompactHashTable");
baseAddressField = type.getAddressField("_base_address");
bucketCountField = type.getCIntegerField("_bucket_count");
tableEndOffsetField = type.getCIntegerField("_table_end_offset");
bucketsField = type.getAddressField("_buckets");
uintSize = db.lookupType("juint").getSize();
}
// Fields
private static CIntegerField bucketCountField;
private static CIntegerField tableEndOffsetField;
private static AddressField baseAddressField;
private static AddressField bucketsField;
private static long uintSize;
private static int BUCKET_OFFSET_MASK = 0x3FFFFFFF;
private static int BUCKET_TYPE_SHIFT = 30;
private static int COMPACT_BUCKET_TYPE = 1;
public CompactHashTable(Address addr) {
super(addr);
}
private int bucketCount() {
return (int)bucketCountField.getValue(addr);
}
private int tableEndOffset() {
return (int)tableEndOffsetField.getValue(addr);
}
private boolean isCompactBucket(int bucket_info) {
return (bucket_info >> BUCKET_TYPE_SHIFT) == COMPACT_BUCKET_TYPE;
}
private int bucketOffset(int bucket_info) {
return bucket_info & BUCKET_OFFSET_MASK;
}
public Symbol probe(byte[] name, long hash) {
long symOffset;
Symbol sym;
Address baseAddress = baseAddressField.getValue(addr);
Address bucket = bucketsField.getValue(addr);
Address bucketEnd = bucket;
long index = hash % bucketCount();
int bucketInfo = (int)bucket.getCIntegerAt(index * uintSize, uintSize, true);
int bucketOffset = bucketOffset(bucketInfo);
int nextBucketInfo = (int)bucket.getCIntegerAt((index+1) * uintSize, uintSize, true);
int nextBucketOffset = bucketOffset(nextBucketInfo);
bucket = bucket.addOffsetTo(bucketOffset * uintSize);
if (isCompactBucket(bucketInfo)) {
symOffset = bucket.getCIntegerAt(0, uintSize, true);
sym = Symbol.create(baseAddress.addOffsetTo(symOffset));
if (sym.equals(name)) {
return sym;
}
} else {
bucketEnd = bucket.addOffsetTo(nextBucketOffset * uintSize);
while (bucket.lessThan(bucketEnd)) {
long symHash = bucket.getCIntegerAt(0, uintSize, true);
if (symHash == hash) {
symOffset = bucket.getCIntegerAt(uintSize, uintSize, true);
Address symAddr = baseAddress.addOffsetTo(symOffset);
sym = Symbol.create(symAddr);
if (sym.equals(name)) {
return sym;
}
}
bucket = bucket.addOffsetTo(2 * uintSize);
}
}
return null;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -123,7 +123,9 @@ bool frame::safe_for_sender(JavaThread *thread) {
}
intptr_t* sender_sp = NULL;
intptr_t* sender_unextended_sp = NULL;
address sender_pc = NULL;
intptr_t* saved_fp = NULL;
if (is_interpreted_frame()) {
// fp must be safe
@ -132,7 +134,12 @@ bool frame::safe_for_sender(JavaThread *thread) {
}
sender_pc = (address) this->fp()[return_addr_offset];
// for interpreted frames, the value below is the sender "raw" sp,
// which can be different from the sender unextended sp (the sp seen
// by the sender) because of current frame local variables
sender_sp = (intptr_t*) addr_at(sender_sp_offset);
sender_unextended_sp = (intptr_t*) this->fp()[interpreter_frame_sender_sp_offset];
saved_fp = (intptr_t*) this->fp()[link_offset];
} else {
// must be some sort of compiled/runtime frame
@ -144,8 +151,11 @@ bool frame::safe_for_sender(JavaThread *thread) {
}
sender_sp = _unextended_sp + _cb->frame_size();
sender_unextended_sp = sender_sp;
// On Intel the return_address is always the word on the stack
sender_pc = (address) *(sender_sp-1);
// Note: frame::sender_sp_offset is only valid for compiled frame
saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset);
}
@ -156,7 +166,6 @@ bool frame::safe_for_sender(JavaThread *thread) {
// only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved ebp
// is really a frame pointer.
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) {
@ -165,7 +174,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// construct the potential sender
frame sender(sender_sp, saved_fp, sender_pc);
frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
return sender.is_interpreted_frame_valid(thread);
@ -194,7 +203,6 @@ bool frame::safe_for_sender(JavaThread *thread) {
// Could be the call_stub
if (StubRoutines::returns_to_call_stub(sender_pc)) {
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) {
@ -203,7 +211,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// construct the potential sender
frame sender(sender_sp, saved_fp, sender_pc);
frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
// Validate the JavaCallWrapper an entry frame must have
address jcw = (address)sender.entry_frame_call_wrapper();
@ -568,8 +576,11 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
if (!m->is_valid_method()) return false;
// stack frames shouldn't be much larger than max_stack elements
if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
// this test requires the use the unextended_sp which is the sp as seen by
// the current frame, and not sp which is the "raw" pc which could point
// further because of local variables of the callee method inserted after
// method arguments
if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
return false;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,7 @@
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
#include "utilities/resourceHash.hpp"
#if INCLUDE_CDS
#include "classfile/systemDictionaryShared.hpp"
#endif
@ -693,7 +694,6 @@ void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Hand
}
class NameSigHash: public ResourceObj {
public:
Symbol* _name; // name
@ -1370,6 +1370,33 @@ void ClassFileParser::parse_linenumber_table(
}
class LVT_Hash : public AllStatic {
public:
static bool equals(LocalVariableTableElement const& e0, LocalVariableTableElement const& e1) {
/*
* 3-tuple start_bci/length/slot has to be unique key,
* so the following comparison seems to be redundant:
* && elem->name_cp_index == entry->_elem->name_cp_index
*/
return (e0.start_bci == e1.start_bci &&
e0.length == e1.length &&
e0.name_cp_index == e1.name_cp_index &&
e0.slot == e1.slot);
}
static unsigned int hash(LocalVariableTableElement const& e0) {
unsigned int raw_hash = e0.start_bci;
raw_hash = e0.length + raw_hash * 37;
raw_hash = e0.name_cp_index + raw_hash * 37;
raw_hash = e0.slot + raw_hash * 37;
return raw_hash;
}
};
// Class file LocalVariableTable elements.
class Classfile_LVT_Element VALUE_OBJ_CLASS_SPEC {
public:
@ -1380,88 +1407,6 @@ class Classfile_LVT_Element VALUE_OBJ_CLASS_SPEC {
u2 slot;
};
class LVT_Hash: public CHeapObj<mtClass> {
public:
LocalVariableTableElement *_elem; // element
LVT_Hash* _next; // Next entry in hash table
};
unsigned int hash(LocalVariableTableElement *elem) {
unsigned int raw_hash = elem->start_bci;
raw_hash = elem->length + raw_hash * 37;
raw_hash = elem->name_cp_index + raw_hash * 37;
raw_hash = elem->slot + raw_hash * 37;
return raw_hash % HASH_ROW_SIZE;
}
void initialize_hashtable(LVT_Hash** table) {
for (int i = 0; i < HASH_ROW_SIZE; i++) {
table[i] = NULL;
}
}
void clear_hashtable(LVT_Hash** table) {
for (int i = 0; i < HASH_ROW_SIZE; i++) {
LVT_Hash* current = table[i];
LVT_Hash* next;
while (current != NULL) {
next = current->_next;
current->_next = NULL;
delete(current);
current = next;
}
table[i] = NULL;
}
}
LVT_Hash* LVT_lookup(LocalVariableTableElement *elem, int index, LVT_Hash** table) {
LVT_Hash* entry = table[index];
/*
* 3-tuple start_bci/length/slot has to be unique key,
* so the following comparison seems to be redundant:
* && elem->name_cp_index == entry->_elem->name_cp_index
*/
while (entry != NULL) {
if (elem->start_bci == entry->_elem->start_bci
&& elem->length == entry->_elem->length
&& elem->name_cp_index == entry->_elem->name_cp_index
&& elem->slot == entry->_elem->slot
) {
return entry;
}
entry = entry->_next;
}
return NULL;
}
// Return false if the local variable is found in table.
// Return true if no duplicate is found.
// And local variable is added as a new entry in table.
bool LVT_put_after_lookup(LocalVariableTableElement *elem, LVT_Hash** table) {
// First lookup for duplicates
int index = hash(elem);
LVT_Hash* entry = LVT_lookup(elem, index, table);
if (entry != NULL) {
return false;
}
// No duplicate is found, allocate a new entry and fill it.
if ((entry = new LVT_Hash()) == NULL) {
return false;
}
entry->_elem = elem;
// Insert into hash table
entry->_next = table[index];
table[index] = entry;
return true;
}
void copy_lvt_element(Classfile_LVT_Element *src, LocalVariableTableElement *lvt) {
lvt->start_bci = Bytes::get_Java_u2((u1*) &src->start_bci);
lvt->length = Bytes::get_Java_u2((u1*) &src->length);
@ -1861,8 +1806,12 @@ void ClassFileParser::copy_localvariable_table(ConstMethod* cm,
u2** localvariable_type_table_start,
TRAPS) {
LVT_Hash** lvt_Hash = NEW_RESOURCE_ARRAY(LVT_Hash*, HASH_ROW_SIZE);
initialize_hashtable(lvt_Hash);
ResourceMark rm(THREAD);
typedef ResourceHashtable<LocalVariableTableElement, LocalVariableTableElement*,
&LVT_Hash::hash, &LVT_Hash::equals> LVT_HashTable;
LVT_HashTable* table = new LVT_HashTable();
// To fill LocalVariableTable in
Classfile_LVT_Element* cf_lvt;
@ -1872,11 +1821,10 @@ void ClassFileParser::copy_localvariable_table(ConstMethod* cm,
cf_lvt = (Classfile_LVT_Element *) localvariable_table_start[tbl_no];
for (int idx = 0; idx < localvariable_table_length[tbl_no]; idx++, lvt++) {
copy_lvt_element(&cf_lvt[idx], lvt);
// If no duplicates, add LVT elem in hashtable lvt_Hash.
if (LVT_put_after_lookup(lvt, lvt_Hash) == false
// If no duplicates, add LVT elem in hashtable.
if (table->put(*lvt, lvt) == false
&& _need_verify
&& _major_version >= JAVA_1_5_VERSION) {
clear_hashtable(lvt_Hash);
classfile_parse_error("Duplicated LocalVariableTable attribute "
"entry for '%s' in class file %s",
_cp->symbol_at(lvt->name_cp_index)->as_utf8(),
@ -1893,29 +1841,25 @@ void ClassFileParser::copy_localvariable_table(ConstMethod* cm,
cf_lvtt = (Classfile_LVT_Element *) localvariable_type_table_start[tbl_no];
for (int idx = 0; idx < localvariable_type_table_length[tbl_no]; idx++) {
copy_lvt_element(&cf_lvtt[idx], &lvtt_elem);
int index = hash(&lvtt_elem);
LVT_Hash* entry = LVT_lookup(&lvtt_elem, index, lvt_Hash);
LocalVariableTableElement** entry = table->get(lvtt_elem);
if (entry == NULL) {
if (_need_verify) {
clear_hashtable(lvt_Hash);
classfile_parse_error("LVTT entry for '%s' in class file %s "
"does not match any LVT entry",
_cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
CHECK);
}
} else if (entry->_elem->signature_cp_index != 0 && _need_verify) {
clear_hashtable(lvt_Hash);
} else if ((*entry)->signature_cp_index != 0 && _need_verify) {
classfile_parse_error("Duplicated LocalVariableTypeTable attribute "
"entry for '%s' in class file %s",
_cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
CHECK);
} else {
// to add generic signatures into LocalVariableTable
entry->_elem->signature_cp_index = lvtt_elem.descriptor_cp_index;
(*entry)->signature_cp_index = lvtt_elem.descriptor_cp_index;
}
}
}
clear_hashtable(lvt_Hash);
}

View File

@ -188,6 +188,7 @@ public:
// dump time.
//
template <class T, class N> class CompactHashtable VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
uintx _base_address;
juint _entry_count;
juint _bucket_count;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,7 @@
#include "classfile/javaClasses.hpp"
#include "classfile/loaderConstraints.hpp"
#include "classfile/placeholders.hpp"
#include "classfile/compactHashtable.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "ci/ciField.hpp"
@ -243,6 +244,7 @@ typedef TwoOopHashtable<Klass*, mtClass> KlassTwoOopHashtable;
typedef Hashtable<Klass*, mtClass> KlassHashtable;
typedef HashtableEntry<Klass*, mtClass> KlassHashtableEntry;
typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
//--------------------------------------------------------------------------------
// VM_STRUCTS
@ -624,6 +626,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
/***************/ \
\
static_field(SymbolTable, _the_table, SymbolTable*) \
static_field(SymbolTable, _shared_table, SymbolCompactHashTable) \
\
/***************/ \
/* StringTable */ \
@ -632,6 +635,16 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
static_field(StringTable, _the_table, StringTable*) \
\
/********************/ \
/* CompactHashTable */ \
/********************/ \
\
nonstatic_field(SymbolCompactHashTable, _base_address, uintx) \
nonstatic_field(SymbolCompactHashTable, _entry_count, juint) \
nonstatic_field(SymbolCompactHashTable, _bucket_count, juint) \
nonstatic_field(SymbolCompactHashTable, _table_end_offset, juint) \
nonstatic_field(SymbolCompactHashTable, _buckets, juint*) \
\
/********************/ \
/* SystemDictionary */ \
/********************/ \
\
@ -1580,6 +1593,8 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
declare_type(ResourceArea, Arena) \
declare_toplevel_type(Chunk) \
\
declare_toplevel_type(SymbolCompactHashTable) \
\
/***********************************************************/ \
/* Thread hierarchy (needed for run-time type information) */ \
/***********************************************************/ \

View File

@ -97,7 +97,7 @@ needs_jdk = \
runtime/XCheckJniJsig/XCheckJSig.java \
serviceability/attach/AttachWithStalePidFile.java \
serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java \
serviceability/dcmd/DynLibDcmdTest.java
serviceability/dcmd/vm/DynLibsTest.java
# JRE adds further tests to compact3
@ -145,7 +145,8 @@ needs_compact3 = \
gc/survivorAlignment \
runtime/InternalApi/ThreadCpuTimesDeadlock.java \
serviceability/threads/TestFalseDeadLock.java \
compiler/codecache/jmx
compiler/codecache/jmx \
serviceability/dcmd
# Compact 2 adds full VM tests
compact2 = \

View File

@ -0,0 +1,293 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// This creates a duplicate LVT entry
class DuplicateLVT {
0xCAFEBABE;
0; // minor version
52; // version
[] { // Constant Pool
; // first element is empty
Method #34 #68; // #1
double 0x3FF199999999999A;; // #2
float 0x3F99999A; // #4
long 0xFFFFFFFFCAFEBABE;; // #5
class #69; // #7
Method #7 #68; // #8
String #70; // #9
Method #7 #71; // #10
Field #72 #73; // #11
class #74; // #12
Method #12 #68; // #13
String #75; // #14
Method #12 #76; // #15
Method #12 #77; // #16
Method #12 #78; // #17
Method #79 #80; // #18
String #81; // #19
Method #12 #82; // #20
String #83; // #21
Method #12 #84; // #22
String #85; // #23
Method #12 #86; // #24
String #87; // #25
Method #12 #88; // #26
String #89; // #27
String #90; // #28
Method #12 #91; // #29
String #92; // #30
String #93; // #31
Method #12 #94; // #32
class #95; // #33
class #96; // #34
Utf8 "<init>"; // #35
Utf8 "()V"; // #36
Utf8 "Code"; // #37
Utf8 "LineNumberTable"; // #38
Utf8 "LocalVariableTable"; // #39
Utf8 "this"; // #40
Utf8 "LDuplicateLVT;"; // #41
Utf8 "main"; // #42
Utf8 "([Ljava/lang/String;)V"; // #43
Utf8 "args"; // #44
Utf8 "[Ljava/lang/String;"; // #45
Utf8 "b"; // #46
Utf8 "Z"; // #47
Utf8 "by"; // #48
Utf8 "B"; // #49
Utf8 "c"; // #50
Utf8 "C"; // #51
Utf8 "d"; // #52
Utf8 "D"; // #53
Utf8 "f"; // #54
Utf8 "F"; // #55
Utf8 "i"; // #56
Utf8 "I"; // #57
Utf8 "l"; // #58
Utf8 "J"; // #59
Utf8 "s"; // #60
Utf8 "S"; // #61
Utf8 "list"; // #62
Utf8 "Ljava/util/ArrayList;"; // #63
Utf8 "LocalVariableTypeTable"; // #64
Utf8 "Ljava/util/ArrayList<Ljava/lang/String;>;"; // #65
Utf8 "SourceFile"; // #66
Utf8 "DuplicateLVT.java"; // #67
NameAndType #35 #36; // #68
Utf8 "java/util/ArrayList"; // #69
Utf8 "me"; // #70
NameAndType #97 #98; // #71
class #99; // #72
NameAndType #100 #101; // #73
Utf8 "java/lang/StringBuilder"; // #74
Utf8 "b="; // #75
NameAndType #102 #103; // #76
NameAndType #102 #104; // #77
NameAndType #105 #106; // #78
class #107; // #79
NameAndType #108 #109; // #80
Utf8 "by="; // #81
NameAndType #102 #110; // #82
Utf8 "c="; // #83
NameAndType #102 #111; // #84
Utf8 "d="; // #85
NameAndType #102 #112; // #86
Utf8 "f="; // #87
NameAndType #102 #113; // #88
Utf8 "i="; // #89
Utf8 "l="; // #90
NameAndType #102 #114; // #91
Utf8 "s="; // #92
Utf8 "ArrayList<String>="; // #93
NameAndType #102 #115; // #94
Utf8 "DuplicateLVT"; // #95
Utf8 "java/lang/Object"; // #96
Utf8 "add"; // #97
Utf8 "(Ljava/lang/Object;)Z"; // #98
Utf8 "java/lang/System"; // #99
Utf8 "out"; // #100
Utf8 "Ljava/io/PrintStream;"; // #101
Utf8 "append"; // #102
Utf8 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; // #103
Utf8 "(Z)Ljava/lang/StringBuilder;"; // #104
Utf8 "toString"; // #105
Utf8 "()Ljava/lang/String;"; // #106
Utf8 "java/io/PrintStream"; // #107
Utf8 "println"; // #108
Utf8 "(Ljava/lang/String;)V"; // #109
Utf8 "(I)Ljava/lang/StringBuilder;"; // #110
Utf8 "(C)Ljava/lang/StringBuilder;"; // #111
Utf8 "(D)Ljava/lang/StringBuilder;"; // #112
Utf8 "(F)Ljava/lang/StringBuilder;"; // #113
Utf8 "(J)Ljava/lang/StringBuilder;"; // #114
Utf8 "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"; // #115
} // Constant Pool
0x0021; // access
#33;// this_cpx
#34;// super_cpx
[] { // Interfaces
} // Interfaces
[] { // fields
} // fields
[] { // methods
{ // Member
0x0001; // access
#35; // name_cpx
#36; // sig_cpx
[] { // Attributes
Attr(#37) { // Code
1; // max_stack
1; // max_locals
Bytes[]{
0x2AB70001B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#38) { // LineNumberTable
[] { // LineNumberTable
0 26;
}
} // end LineNumberTable
;
Attr(#39) { // LocalVariableTable
[] { // LocalVariableTable
0 5 40 41 0;
}
} // end LocalVariableTable
} // Attributes
} // end Code
} // Attributes
} // Member
;
{ // Member
0x0009; // access
#42; // name_cpx
#43; // sig_cpx
[] { // Attributes
Attr(#37) { // Code
4; // max_stack
12; // max_locals
Bytes[]{
0x043C10423D10583E;
0x1400023904120438;
0x06102A3607140005;
0x37081058360ABB00;
0x0759B700083A0B19;
0x0B1209B6000A57B2;
0x000BBB000C59B700;
0x0D120EB6000F1BB6;
0x0010B60011B60012;
0xB2000BBB000C59B7;
0x000D1213B6000F1C;
0xB60014B60011B600;
0x12B2000BBB000C59;
0xB7000D1215B6000F;
0x1DB60016B60011B6;
0x0012B2000BBB000C;
0x59B7000D1217B600;
0x0F1804B60018B600;
0x11B60012B2000BBB;
0x000C59B7000D1219;
0xB6000F1706B6001A;
0xB60011B60012B200;
0x0BBB000C59B7000D;
0x121BB6000F1507B6;
0x0014B60011B60012;
0xB2000BBB000C59B7;
0x000D121CB6000F16;
0x08B6001DB60011B6;
0x0012B2000BBB000C;
0x59B7000D121EB600;
0x0F150AB60014B600;
0x11B60012B2000BBB;
0x000C59B7000D121F;
0xB6000F190BB60020;
0xB60011B60012B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#38) { // LineNumberTable
[] { // LineNumberTable
0 28;
2 29;
5 30;
8 31;
13 32;
17 33;
21 34;
26 35;
30 36;
39 37;
47 39;
72 40;
97 41;
122 42;
148 43;
174 44;
200 45;
226 46;
252 47;
278 48;
}
} // end LineNumberTable
;
Attr(#39) { // LocalVariableTable
[] { // LocalVariableTable
0 279 44 45 0;
2 277 46 47 1;
5 274 48 49 2;
5 274 48 49 2;
8 271 50 51 3;
13 266 52 53 4;
17 262 54 55 6;
21 258 56 57 7;
26 253 58 59 8;
30 249 60 61 10;
39 240 62 63 11;
}
} // end LocalVariableTable
;
Attr(#64) { // LocalVariableTypeTable
[] { // LocalVariableTypeTable
39 240 62 65 11;
}
} // end LocalVariableTypeTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods
[] { // Attributes
Attr(#66) { // SourceFile
#67;
} // end SourceFile
} // Attributes
} // end class DuplicateLVT

View File

@ -0,0 +1,293 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// There's a duplicate LVTT entry below.
class DuplicateLVTT {
0xCAFEBABE;
0; // minor version
52; // version
[] { // Constant Pool
; // first element is empty
Method #34 #68; // #1
double 0x3FF199999999999A;; // #2
float 0x3F99999A; // #4
long 0xFFFFFFFFCAFEBABE;; // #5
class #69; // #7
Method #7 #68; // #8
String #70; // #9
Method #7 #71; // #10
Field #72 #73; // #11
class #74; // #12
Method #12 #68; // #13
String #75; // #14
Method #12 #76; // #15
Method #12 #77; // #16
Method #12 #78; // #17
Method #79 #80; // #18
String #81; // #19
Method #12 #82; // #20
String #83; // #21
Method #12 #84; // #22
String #85; // #23
Method #12 #86; // #24
String #87; // #25
Method #12 #88; // #26
String #89; // #27
String #90; // #28
Method #12 #91; // #29
String #92; // #30
String #93; // #31
Method #12 #94; // #32
class #95; // #33
class #96; // #34
Utf8 "<init>"; // #35
Utf8 "()V"; // #36
Utf8 "Code"; // #37
Utf8 "LineNumberTable"; // #38
Utf8 "LocalVariableTable"; // #39
Utf8 "this"; // #40
Utf8 "LDuplicateLVTT;"; // #41
Utf8 "main"; // #42
Utf8 "([Ljava/lang/String;)V"; // #43
Utf8 "args"; // #44
Utf8 "[Ljava/lang/String;"; // #45
Utf8 "b"; // #46
Utf8 "Z"; // #47
Utf8 "by"; // #48
Utf8 "B"; // #49
Utf8 "c"; // #50
Utf8 "C"; // #51
Utf8 "d"; // #52
Utf8 "D"; // #53
Utf8 "f"; // #54
Utf8 "F"; // #55
Utf8 "i"; // #56
Utf8 "I"; // #57
Utf8 "l"; // #58
Utf8 "J"; // #59
Utf8 "s"; // #60
Utf8 "S"; // #61
Utf8 "list"; // #62
Utf8 "Ljava/util/ArrayList;"; // #63
Utf8 "LocalVariableTypeTable"; // #64
Utf8 "Ljava/util/ArrayList<Ljava/lang/String;>;"; // #65
Utf8 "SourceFile"; // #66
Utf8 "DuplicateLVTT.java"; // #67
NameAndType #35 #36; // #68
Utf8 "java/util/ArrayList"; // #69
Utf8 "me"; // #70
NameAndType #97 #98; // #71
class #99; // #72
NameAndType #100 #101; // #73
Utf8 "java/lang/StringBuilder"; // #74
Utf8 "b="; // #75
NameAndType #102 #103; // #76
NameAndType #102 #104; // #77
NameAndType #105 #106; // #78
class #107; // #79
NameAndType #108 #109; // #80
Utf8 "by="; // #81
NameAndType #102 #110; // #82
Utf8 "c="; // #83
NameAndType #102 #111; // #84
Utf8 "d="; // #85
NameAndType #102 #112; // #86
Utf8 "f="; // #87
NameAndType #102 #113; // #88
Utf8 "i="; // #89
Utf8 "l="; // #90
NameAndType #102 #114; // #91
Utf8 "s="; // #92
Utf8 "ArrayList<String>="; // #93
NameAndType #102 #115; // #94
Utf8 "DuplicateLVTT"; // #95
Utf8 "java/lang/Object"; // #96
Utf8 "add"; // #97
Utf8 "(Ljava/lang/Object;)Z"; // #98
Utf8 "java/lang/System"; // #99
Utf8 "out"; // #100
Utf8 "Ljava/io/PrintStream;"; // #101
Utf8 "append"; // #102
Utf8 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; // #103
Utf8 "(Z)Ljava/lang/StringBuilder;"; // #104
Utf8 "toString"; // #105
Utf8 "()Ljava/lang/String;"; // #106
Utf8 "java/io/PrintStream"; // #107
Utf8 "println"; // #108
Utf8 "(Ljava/lang/String;)V"; // #109
Utf8 "(I)Ljava/lang/StringBuilder;"; // #110
Utf8 "(C)Ljava/lang/StringBuilder;"; // #111
Utf8 "(D)Ljava/lang/StringBuilder;"; // #112
Utf8 "(F)Ljava/lang/StringBuilder;"; // #113
Utf8 "(J)Ljava/lang/StringBuilder;"; // #114
Utf8 "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"; // #115
} // Constant Pool
0x0021; // access
#33;// this_cpx
#34;// super_cpx
[] { // Interfaces
} // Interfaces
[] { // fields
} // fields
[] { // methods
{ // Member
0x0001; // access
#35; // name_cpx
#36; // sig_cpx
[] { // Attributes
Attr(#37) { // Code
1; // max_stack
1; // max_locals
Bytes[]{
0x2AB70001B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#38) { // LineNumberTable
[] { // LineNumberTable
0 26;
}
} // end LineNumberTable
;
Attr(#39) { // LocalVariableTable
[] { // LocalVariableTable
0 5 40 41 0;
}
} // end LocalVariableTable
} // Attributes
} // end Code
} // Attributes
} // Member
;
{ // Member
0x0009; // access
#42; // name_cpx
#43; // sig_cpx
[] { // Attributes
Attr(#37) { // Code
4; // max_stack
12; // max_locals
Bytes[]{
0x043C10423D10583E;
0x1400023904120438;
0x06102A3607140005;
0x37081058360ABB00;
0x0759B700083A0B19;
0x0B1209B6000A57B2;
0x000BBB000C59B700;
0x0D120EB6000F1BB6;
0x0010B60011B60012;
0xB2000BBB000C59B7;
0x000D1213B6000F1C;
0xB60014B60011B600;
0x12B2000BBB000C59;
0xB7000D1215B6000F;
0x1DB60016B60011B6;
0x0012B2000BBB000C;
0x59B7000D1217B600;
0x0F1804B60018B600;
0x11B60012B2000BBB;
0x000C59B7000D1219;
0xB6000F1706B6001A;
0xB60011B60012B200;
0x0BBB000C59B7000D;
0x121BB6000F1507B6;
0x0014B60011B60012;
0xB2000BBB000C59B7;
0x000D121CB6000F16;
0x08B6001DB60011B6;
0x0012B2000BBB000C;
0x59B7000D121EB600;
0x0F150AB60014B600;
0x11B60012B2000BBB;
0x000C59B7000D121F;
0xB6000F190BB60020;
0xB60011B60012B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#38) { // LineNumberTable
[] { // LineNumberTable
0 28;
2 29;
5 30;
8 31;
13 32;
17 33;
21 34;
26 35;
30 36;
39 37;
47 39;
72 40;
97 41;
122 42;
148 43;
174 44;
200 45;
226 46;
252 47;
278 48;
}
} // end LineNumberTable
;
Attr(#39) { // LocalVariableTable
[] { // LocalVariableTable
0 279 44 45 0;
2 277 46 47 1;
5 274 48 49 2;
8 271 50 51 3;
13 266 52 53 4;
17 262 54 55 6;
21 258 56 57 7;
26 253 58 59 8;
30 249 60 61 10;
39 240 62 63 11;
}
} // end LocalVariableTable
;
Attr(#64) { // LocalVariableTypeTable
[] { // LocalVariableTypeTable
39 240 62 65 11;
39 240 62 65 11;
}
} // end LocalVariableTypeTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods
[] { // Attributes
Attr(#66) { // SourceFile
#67;
} // end SourceFile
} // Attributes
} // end class DuplicateLVTT

View File

@ -0,0 +1,292 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// The LVTT entry points to a non-existant LVT entry
class NotFoundLVTT {
0xCAFEBABE;
0; // minor version
52; // version
[] { // Constant Pool
; // first element is empty
Method #34 #68; // #1
double 0x3FF199999999999A;; // #2
float 0x3F99999A; // #4
long 0xFFFFFFFFCAFEBABE;; // #5
class #69; // #7
Method #7 #68; // #8
String #70; // #9
Method #7 #71; // #10
Field #72 #73; // #11
class #74; // #12
Method #12 #68; // #13
String #75; // #14
Method #12 #76; // #15
Method #12 #77; // #16
Method #12 #78; // #17
Method #79 #80; // #18
String #81; // #19
Method #12 #82; // #20
String #83; // #21
Method #12 #84; // #22
String #85; // #23
Method #12 #86; // #24
String #87; // #25
Method #12 #88; // #26
String #89; // #27
String #90; // #28
Method #12 #91; // #29
String #92; // #30
String #93; // #31
Method #12 #94; // #32
class #95; // #33
class #96; // #34
Utf8 "<init>"; // #35
Utf8 "()V"; // #36
Utf8 "Code"; // #37
Utf8 "LineNumberTable"; // #38
Utf8 "LocalVariableTable"; // #39
Utf8 "this"; // #40
Utf8 "LNotFoundLVTT;"; // #41
Utf8 "main"; // #42
Utf8 "([Ljava/lang/String;)V"; // #43
Utf8 "args"; // #44
Utf8 "[Ljava/lang/String;"; // #45
Utf8 "b"; // #46
Utf8 "Z"; // #47
Utf8 "by"; // #48
Utf8 "B"; // #49
Utf8 "c"; // #50
Utf8 "C"; // #51
Utf8 "d"; // #52
Utf8 "D"; // #53
Utf8 "f"; // #54
Utf8 "F"; // #55
Utf8 "i"; // #56
Utf8 "I"; // #57
Utf8 "l"; // #58
Utf8 "J"; // #59
Utf8 "s"; // #60
Utf8 "S"; // #61
Utf8 "list"; // #62
Utf8 "Ljava/util/ArrayList;"; // #63
Utf8 "LocalVariableTypeTable"; // #64
Utf8 "Ljava/util/ArrayList<Ljava/lang/String;>;"; // #65
Utf8 "SourceFile"; // #66
Utf8 "NotFoundLVTT.java"; // #67
NameAndType #35 #36; // #68
Utf8 "java/util/ArrayList"; // #69
Utf8 "me"; // #70
NameAndType #97 #98; // #71
class #99; // #72
NameAndType #100 #101; // #73
Utf8 "java/lang/StringBuilder"; // #74
Utf8 "b="; // #75
NameAndType #102 #103; // #76
NameAndType #102 #104; // #77
NameAndType #105 #106; // #78
class #107; // #79
NameAndType #108 #109; // #80
Utf8 "by="; // #81
NameAndType #102 #110; // #82
Utf8 "c="; // #83
NameAndType #102 #111; // #84
Utf8 "d="; // #85
NameAndType #102 #112; // #86
Utf8 "f="; // #87
NameAndType #102 #113; // #88
Utf8 "i="; // #89
Utf8 "l="; // #90
NameAndType #102 #114; // #91
Utf8 "s="; // #92
Utf8 "ArrayList<String>="; // #93
NameAndType #102 #115; // #94
Utf8 "NotFoundLVTT"; // #95
Utf8 "java/lang/Object"; // #96
Utf8 "add"; // #97
Utf8 "(Ljava/lang/Object;)Z"; // #98
Utf8 "java/lang/System"; // #99
Utf8 "out"; // #100
Utf8 "Ljava/io/PrintStream;"; // #101
Utf8 "append"; // #102
Utf8 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; // #103
Utf8 "(Z)Ljava/lang/StringBuilder;"; // #104
Utf8 "toString"; // #105
Utf8 "()Ljava/lang/String;"; // #106
Utf8 "java/io/PrintStream"; // #107
Utf8 "println"; // #108
Utf8 "(Ljava/lang/String;)V"; // #109
Utf8 "(I)Ljava/lang/StringBuilder;"; // #110
Utf8 "(C)Ljava/lang/StringBuilder;"; // #111
Utf8 "(D)Ljava/lang/StringBuilder;"; // #112
Utf8 "(F)Ljava/lang/StringBuilder;"; // #113
Utf8 "(J)Ljava/lang/StringBuilder;"; // #114
Utf8 "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"; // #115
} // Constant Pool
0x0021; // access
#33;// this_cpx
#34;// super_cpx
[] { // Interfaces
} // Interfaces
[] { // fields
} // fields
[] { // methods
{ // Member
0x0001; // access
#35; // name_cpx
#36; // sig_cpx
[] { // Attributes
Attr(#37) { // Code
1; // max_stack
1; // max_locals
Bytes[]{
0x2AB70001B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#38) { // LineNumberTable
[] { // LineNumberTable
0 26;
}
} // end LineNumberTable
;
Attr(#39) { // LocalVariableTable
[] { // LocalVariableTable
0 5 40 41 0;
}
} // end LocalVariableTable
} // Attributes
} // end Code
} // Attributes
} // Member
;
{ // Member
0x0009; // access
#42; // name_cpx
#43; // sig_cpx
[] { // Attributes
Attr(#37) { // Code
4; // max_stack
12; // max_locals
Bytes[]{
0x043C10423D10583E;
0x1400023904120438;
0x06102A3607140005;
0x37081058360ABB00;
0x0759B700083A0B19;
0x0B1209B6000A57B2;
0x000BBB000C59B700;
0x0D120EB6000F1BB6;
0x0010B60011B60012;
0xB2000BBB000C59B7;
0x000D1213B6000F1C;
0xB60014B60011B600;
0x12B2000BBB000C59;
0xB7000D1215B6000F;
0x1DB60016B60011B6;
0x0012B2000BBB000C;
0x59B7000D1217B600;
0x0F1804B60018B600;
0x11B60012B2000BBB;
0x000C59B7000D1219;
0xB6000F1706B6001A;
0xB60011B60012B200;
0x0BBB000C59B7000D;
0x121BB6000F1507B6;
0x0014B60011B60012;
0xB2000BBB000C59B7;
0x000D121CB6000F16;
0x08B6001DB60011B6;
0x0012B2000BBB000C;
0x59B7000D121EB600;
0x0F150AB60014B600;
0x11B60012B2000BBB;
0x000C59B7000D121F;
0xB6000F190BB60020;
0xB60011B60012B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#38) { // LineNumberTable
[] { // LineNumberTable
0 28;
2 29;
5 30;
8 31;
13 32;
17 33;
21 34;
26 35;
30 36;
39 37;
47 39;
72 40;
97 41;
122 42;
148 43;
174 44;
200 45;
226 46;
252 47;
278 48;
}
} // end LineNumberTable
;
Attr(#39) { // LocalVariableTable
[] { // LocalVariableTable
0 279 44 45 0;
2 277 46 47 1;
5 274 48 49 2;
8 271 50 51 3;
13 266 52 53 4;
17 262 54 55 6;
21 258 56 57 7;
26 253 58 59 8;
30 249 60 61 10;
39 240 62 63 11;
}
} // end LocalVariableTable
;
Attr(#64) { // LocalVariableTypeTable
[] { // LocalVariableTypeTable
38 240 62 65 11;
}
} // end LocalVariableTypeTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods
[] { // Attributes
Attr(#66) { // SourceFile
#67;
} // end SourceFile
} // Attributes
} // end class NotFoundLVTT

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8049632
* @summary Test ClassFileParser::copy_localvariable_table cases
* @library /testlibrary
* @compile -g -XDignore.symbol.file TestLVT.java
* @run main TestLVT
*/
import com.oracle.java.testlibrary.*;
import java.util.*;
public class TestLVT {
public static void main(String[] args) throws Exception {
test(); // Test good LVT in this test
String jarFile = System.getProperty("test.src") + "/testcase.jar";
// java -cp $testSrc/testcase.jar DuplicateLVT
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-cp", jarFile, "DuplicateLVT");
new OutputAnalyzer(pb.start())
.shouldContain("Duplicated LocalVariableTable attribute entry for 'by' in class file DuplicateLVT")
.shouldHaveExitValue(1);
// java -cp $testclasses/testcase.jar DuplicateLVTT
pb = ProcessTools.createJavaProcessBuilder("-cp", jarFile, "DuplicateLVTT");
new OutputAnalyzer(pb.start())
.shouldContain("Duplicated LocalVariableTypeTable attribute entry for 'list' in class file DuplicateLVTT")
.shouldHaveExitValue(1);
// java -cp $testclasses/testcase.jar NotFoundLVTT
pb = ProcessTools.createJavaProcessBuilder("-cp", jarFile, "NotFoundLVTT");
new OutputAnalyzer(pb.start())
.shouldContain("LVTT entry for 'list' in class file NotFoundLVTT does not match any LVT entry")
.shouldHaveExitValue(1);
}
public static void test() {
boolean b = true;
byte by = 0x42;
char c = 'X';
double d = 1.1;
float f = (float) 1.2;
int i = 42;
long l = 0xCAFEBABE;
short s = 88;
ArrayList<String> list = new ArrayList<String>();
list.add("me");
System.out.println("b=" + b);
System.out.println("by=" + by);
System.out.println("c=" + c);
System.out.println("d=" + d);
System.out.println("f=" + f);
System.out.println("i=" + i);
System.out.println("l=" + l);
System.out.println("s=" + s);
System.out.println("ArrayList<String>=" + list);
}
}

Binary file not shown.

View File

@ -25,7 +25,7 @@
* @test
* @summary Verifies behaviour of Unsafe.allocateMemory
* @library /testlibrary
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=20m AllocateMemory
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m AllocateMemory
*/
import com.oracle.java.testlibrary.*;
@ -56,7 +56,7 @@ public class AllocateMemory {
// allocateMemory() should throw an OutOfMemoryError when the underlying malloc fails,
// we test this by limiting the malloc using -XX:MallocMaxTestWords
try {
address = unsafe.allocateMemory(20 * 1024 * 1024 * 8);
address = unsafe.allocateMemory(100 * 1024 * 1024 * 8);
} catch (OutOfMemoryError e) {
// Expected
return;

View File

@ -26,6 +26,7 @@
* @bug 7162400
* @key regression
* @summary Regression test for attach issue where stale pid files in /tmp lead to connection issues
* @ignore 8024055
* @library /testlibrary
* @build com.oracle.java.testlibrary.* AttachWithStalePidFileTarget
* @run main AttachWithStalePidFile

View File

@ -1,73 +0,0 @@
/*
* Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import sun.management.ManagementFactoryHelper;
import com.sun.management.DiagnosticCommandMBean;
public class DcmdUtil
{
public static String executeDcmd(String cmd, String ... args) {
DiagnosticCommandMBean dcmd = ManagementFactoryHelper.getDiagnosticCommandMBean();
Object[] dcmdArgs = {args};
String[] signature = {String[].class.getName()};
try {
System.out.print("> " + cmd + " ");
for (String s : args) {
System.out.print(s + " ");
}
System.out.println(":");
String result = (String) dcmd.invoke(transform(cmd), dcmdArgs, signature);
System.out.println(result);
return result;
} catch(Exception ex) {
ex.printStackTrace();
}
return null;
}
private static String transform(String name) {
StringBuilder sb = new StringBuilder();
boolean toLower = true;
boolean toUpper = false;
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
if (c == '.' || c == '_') {
toLower = false;
toUpper = true;
} else {
if (toUpper) {
toUpper = false;
sb.append(Character.toUpperCase(c));
} else if(toLower) {
sb.append(Character.toLowerCase(c));
} else {
sb.append(c);
}
}
}
return sb.toString();
}
}

View File

@ -24,17 +24,23 @@
/*
* @test CodeCacheTest
* @bug 8054889
* @library ..
* @build DcmdUtil CodeCacheTest
* @run main/othervm -XX:+SegmentedCodeCache CodeCacheTest
* @run main/othervm -XX:-SegmentedCodeCache CodeCacheTest
* @run main/othervm -Xint -XX:+SegmentedCodeCache CodeCacheTest
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -XX:+SegmentedCodeCache CodeCacheTest
* @run testng/othervm -XX:-SegmentedCodeCache CodeCacheTest
* @run testng/othervm -Xint -XX:+SegmentedCodeCache CodeCacheTest
* @summary Test of diagnostic command Compiler.codecache
*/
import java.io.BufferedReader;
import java.io.StringReader;
import java.lang.reflect.Method;
import org.testng.annotations.Test;
import org.testng.Assert;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -72,7 +78,7 @@ public class CodeCacheTest {
private static boolean getFlagBool(String flag, String where) {
Matcher m = Pattern.compile(flag + "\\s+:?= (true|false)").matcher(where);
if (!m.find()) {
throw new RuntimeException("Could not find value for flag " + flag + " in output string");
Assert.fail("Could not find value for flag " + flag + " in output string");
}
return m.group(1).equals("true");
}
@ -80,16 +86,16 @@ public class CodeCacheTest {
private static int getFlagInt(String flag, String where) {
Matcher m = Pattern.compile(flag + "\\s+:?=\\s+\\d+").matcher(where);
if (!m.find()) {
throw new RuntimeException("Could not find value for flag " + flag + " in output string");
Assert.fail("Could not find value for flag " + flag + " in output string");
}
String match = m.group();
return Integer.parseInt(match.substring(match.lastIndexOf(" ") + 1, match.length()));
}
public static void main(String arg[]) throws Exception {
public void run(CommandExecutor executor) {
// Get number of code cache segments
int segmentsCount = 0;
String flags = DcmdUtil.executeDcmd("VM.flags", "-all");
String flags = executor.execute("VM.flags -all").getOutput();
if (!getFlagBool("SegmentedCodeCache", flags) || !getFlagBool("UseCompiler", flags)) {
// No segmentation
segmentsCount = 1;
@ -102,29 +108,29 @@ public class CodeCacheTest {
}
// Get output from dcmd (diagnostic command)
String result = DcmdUtil.executeDcmd("Compiler.codecache");
BufferedReader r = new BufferedReader(new StringReader(result));
OutputAnalyzer output = executor.execute("Compiler.codecache");
Iterator<String> lines = output.asLines().iterator();
// Validate code cache segments
String line;
Matcher m;
for (int s = 0; s < segmentsCount; ++s) {
// Validate first line
line = r.readLine();
line = lines.next();
m = line1.matcher(line);
if (m.matches()) {
for (int i = 2; i <= 5; i++) {
int val = Integer.parseInt(m.group(i));
if (val < 0) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
}
} else {
throw new Exception("Regexp 1 failed");
Assert.fail("Regexp 1 failed to match line: " + line);
}
// Validate second line
line = r.readLine();
line = lines.next();
m = line2.matcher(line);
if (m.matches()) {
String start = m.group(1);
@ -133,44 +139,49 @@ public class CodeCacheTest {
// Lexical compare of hex numbers to check that they look sane.
if (start.compareTo(mark) > 1) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
if (mark.compareTo(top) > 1) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
} else {
throw new Exception("Regexp 2 failed line: " + line);
Assert.fail("Regexp 2 failed to match line: " + line);
}
}
// Validate third line
line = r.readLine();
line = lines.next();
m = line3.matcher(line);
if (m.matches()) {
int blobs = Integer.parseInt(m.group(1));
if (blobs <= 0) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
int nmethods = Integer.parseInt(m.group(2));
if (nmethods < 0) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
int adapters = Integer.parseInt(m.group(3));
if (adapters <= 0) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
if (blobs < (nmethods + adapters)) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
} else {
throw new Exception("Regexp 3 failed");
Assert.fail("Regexp 3 failed to match line: " + line);
}
// Validate fourth line
line = r.readLine();
line = lines.next();
m = line4.matcher(line);
if (!m.matches()) {
throw new Exception("Regexp 4 failed");
Assert.fail("Regexp 4 failed to match line: " + line);
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -24,14 +24,21 @@
/*
* @test CodelistTest
* @bug 8054889
* @library ..
* @build DcmdUtil MethodIdentifierParser CodelistTest
* @run main CodelistTest
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @build MethodIdentifierParser
* @run testng CodelistTest
* @summary Test of diagnostic command Compiler.codelist
*/
import java.io.BufferedReader;
import java.io.StringReader;
import org.testng.annotations.Test;
import org.testng.Assert;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import java.lang.reflect.Method;
public class CodelistTest {
@ -51,19 +58,17 @@ public class CodelistTest {
*
*/
public static void main(String arg[]) throws Exception {
public void run(CommandExecutor executor) {
int ok = 0;
int fail = 0;
// Get output from dcmd (diagnostic command)
String result = DcmdUtil.executeDcmd("Compiler.codelist");
BufferedReader r = new BufferedReader(new StringReader(result));
OutputAnalyzer output = executor.execute("Compiler.codelist");
// Grab a method name from the output
String line;
int count = 0;
while((line = r.readLine()) != null) {
for (String line : output.asLines()) {
count++;
String[] parts = line.split(" ");
@ -83,14 +88,16 @@ public class CodelistTest {
}
MethodIdentifierParser mf = new MethodIdentifierParser(methodPrintedInLogFormat);
Method m;
Method m = null;
try {
m = mf.getMethod();
} catch (NoSuchMethodException e) {
m = null;
} catch (ClassNotFoundException e) {
Assert.fail("Test error: Caught unexpected exception", e);
}
if (m == null) {
throw new Exception("Test failed on: " + methodPrintedInLogFormat);
Assert.fail("Test failed on: " + methodPrintedInLogFormat);
}
if (count > 10) {
// Testing 10 entries is enough. Lets not waste time.
@ -98,4 +105,9 @@ public class CodelistTest {
}
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -24,17 +24,22 @@
/*
* @test CompilerQueueTest
* @bug 8054889
* @library ..
* @library /testlibrary
* @ignore 8069160
* @build DcmdUtil CompilerQueueTest
* @run main CompilerQueueTest
* @run main/othervm -XX:-TieredCompilation CompilerQueueTest
* @run main/othervm -Xint CompilerQueueTest
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng CompilerQueueTest
* @run testng/othervm -XX:-TieredCompilation CompilerQueueTest
* @run testng/othervm -Xint CompilerQueueTest
* @summary Test of diagnostic command Compiler.queue
*/
import java.io.BufferedReader;
import java.io.StringReader;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import org.testng.annotations.Test;
import java.util.Iterator;
public class CompilerQueueTest {
@ -60,52 +65,55 @@ public class CompilerQueueTest {
*
**/
public static void main(String arg[]) throws Exception {
public void run(CommandExecutor executor) {
// Get output from dcmd (diagnostic command)
String result = DcmdUtil.executeDcmd("Compiler.queue");
BufferedReader r = new BufferedReader(new StringReader(result));
OutputAnalyzer output = executor.execute("Compiler.queue");
Iterator<String> lines = output.asLines().iterator();
String str = r.readLine();
while (str != null) {
while (lines.hasNext()) {
String str = lines.next();
if (str.startsWith("Contents of C")) {
match(r.readLine(), "----------------------------");
str = r.readLine();
match(lines.next(), "----------------------------");
str = lines.next();
if (!str.equals("Empty")) {
while (str.charAt(0) != '-') {
validateMethodLine(str);
str = r.readLine();
str = lines.next();
}
} else {
str = r.readLine();
str = lines.next();
}
match(str,"----------------------------");
str = r.readLine();
} else {
throw new Exception("Failed parsing dcmd queue, line: " + str);
Assert.fail("Failed parsing dcmd queue, line: " + str);
}
}
}
private static void validateMethodLine(String str) throws Exception {
private static void validateMethodLine(String str) {
// Skip until package/class name begins. Trim to remove whitespace that
// may differ.
String name = str.substring(14).trim();
int sep = name.indexOf("::");
if (sep == -1) {
throw new Exception("Failed dcmd queue, didn't find separator :: in: " + name);
Assert.fail("Failed dcmd queue, didn't find separator :: in: " + name);
}
try {
Class.forName(name.substring(0, sep));
} catch (ClassNotFoundException e) {
throw new Exception("Failed dcmd queue, Class for name: " + str);
Assert.fail("Failed dcmd queue, Class for name: " + str);
}
}
public static void match(String line, String str) throws Exception {
public static void match(String line, String str) {
if (!line.equals(str)) {
throw new Exception("String equals: " + line + ", " + str);
Assert.fail("String equals: " + line + ", " + str);
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -51,11 +51,11 @@ public class MethodIdentifierParser {
// Add sanity check for extracted fields
}
public Method getMethod() throws NoSuchMethodException, SecurityException, ClassNotFoundException, Exception {
public Method getMethod() throws NoSuchMethodException, SecurityException, ClassNotFoundException {
try {
return Class.forName(className).getDeclaredMethod(methodName, getParamenterDescriptorArray());
} catch (UnexpectedTokenException e) {
throw new Exception("Parse failed");
throw new RuntimeException("Parse failed");
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.MainClassJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.FileJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import org.testng.annotations.Test;
/*
* @test
* @summary Test of diagnostic command help (tests all DCMD executors)
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -XX:+UsePerfData HelpTest
*/
public class HelpTest {
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("help");
output.shouldContain("The following commands are available");
output.shouldContain("help");
output.shouldContain("VM.version");
}
@Test
public void pid() {
run(new PidJcmdExecutor());
}
@Test
public void mainClass() {
run(new MainClassJcmdExecutor());
}
@Test
public void file() {
run(new FileJcmdExecutor());
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.MainClassJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.FileJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import org.testng.annotations.Test;
/*
* @test
* @summary Test of invalid diagnostic command (tests all DCMD executors)
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -XX:+UsePerfData InvalidCommandTest
*/
public class InvalidCommandTest {
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("asdf");
output.shouldContain("Unknown diagnostic command");
}
@Test
public void pid() {
run(new PidJcmdExecutor());
}
@Test
public void mainClass() {
run(new MainClassJcmdExecutor());
}
@Test
public void file() {
run(new FileJcmdExecutor());
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.MainClassJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.FileJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import org.testng.annotations.Test;
/*
* @test
* @summary Test of diagnostic command VM.version (tests all DCMD executors)
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -XX:+UsePerfData VMVersionTest
*/
public class VMVersionTest {
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("VM.version");
output.shouldMatch(".*(?:HotSpot|OpenJDK).*VM.*");
}
@Test
public void pid() {
run(new PidJcmdExecutor());
}
@Test
public void mainClass() {
run(new MainClassJcmdExecutor());
}
@Test
public void file() {
run(new FileJcmdExecutor());
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Test of diagnostic command GC.class_histogram -all=true
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @build ClassHistogramTest
* @run testng ClassHistogramAllTest
*/
public class ClassHistogramAllTest extends ClassHistogramTest {
public ClassHistogramAllTest() {
super();
classHistogramArgs = "-all=true";
}
/* See ClassHistogramTest for test cases */
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import org.testng.annotations.Test;
import java.util.regex.Pattern;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
/*
* @test
* @summary Test of diagnostic command GC.class_histogram
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng ClassHistogramTest
*/
public class ClassHistogramTest {
public static class TestClass {}
public static TestClass[] instances = new TestClass[1024];
protected String classHistogramArgs = "";
static {
for (int i = 0; i < instances.length; ++i) {
instances[i] = new TestClass();
}
}
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("GC.class_histogram " + classHistogramArgs);
/*
* example output:
* num #instances #bytes class name
* ----------------------------------------------
* 1: 1647 1133752 [B
* 2: 6198 383168 [C
* 3: 1464 165744 java.lang.Class
* 4: 6151 147624 java.lang.String
* 5: 2304 73728 java.util.concurrent.ConcurrentHashMap$Node
* 6: 1199 64280 [Ljava.lang.Object;
* ...
*/
/* Require at least one java.lang.Class */
output.shouldMatch("^\\s+\\d+:\\s+\\d+\\s+\\d+\\s+java.lang.Class\\s*$");
/* Require at least one java.lang.String */
output.shouldMatch("^\\s+\\d+:\\s+\\d+\\s+\\d+\\s+java.lang.String\\s*$");
/* Require at least one java.lang.Object */
output.shouldMatch("^\\s+\\d+:\\s+\\d+\\s+\\d+\\s+java.lang.Object\\s*$");
/* Require at exactly one TestClass[] */
output.shouldMatch("^\\s+\\d+:\\s+1\\s+\\d+\\s+" +
Pattern.quote(TestClass[].class.getName()) + "\\s*$");
/* Require at exactly 1024 TestClass */
output.shouldMatch("^\\s+\\d+:\\s+1024\\s+\\d+\\s+" +
Pattern.quote(TestClass.class.getName()) + "\\s*$");
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Test of diagnostic command GC.heap_dump -all=true
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @build HeapDumpTest
* @run testng HeapDumpAllTest
*/
public class HeapDumpAllTest extends HeapDumpTest {
public HeapDumpAllTest() {
super();
heapDumpArgs = "-all=true";
}
/* See HeapDumpTest for test cases */
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import org.testng.annotations.Test;
import org.testng.Assert;
import java.io.IOException;
import com.oracle.java.testlibrary.JDKToolFinder;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
/*
* @test
* @summary Test of diagnostic command GC.heap_dump
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng HeapDumpTest
*/
public class HeapDumpTest {
protected String heapDumpArgs = "";
public void run(CommandExecutor executor) {
String fileName = "jcmd.gc.heap_dump." + System.currentTimeMillis() + ".hprof";
String cmd = "GC.heap_dump " + heapDumpArgs + " " + fileName;
executor.execute(cmd);
verifyHeapDump(fileName);
}
private void verifyHeapDump(String fileName) {
String jhat = JDKToolFinder.getJDKTool("jhat");
String[] cmd = { jhat, "-parseonly", "true", fileName };
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process p = null;
OutputAnalyzer output = null;
try {
p = pb.start();
output = new OutputAnalyzer(p);
/*
* Some hprof dumps of all objects contain constantPoolOop references that cannot be resolved, so we ignore
* failures about resolving constantPoolOop fields using a negative lookahead
*/
output.shouldNotMatch(".*WARNING(?!.*Failed to resolve object.*constantPoolOop.*).*");
} catch (IOException e) {
Assert.fail("Test error: Caught exception while reading stdout/err of jhat", e);
} finally {
if (p != null) {
p.destroy();
}
}
if (output.getExitValue() != 0) {
Assert.fail("Test error: jhat exit code was nonzero");
}
}
/* GC.heap_dump is not available over JMX, running jcmd pid executor instead */
@Test
public void pid() {
run(new PidJcmdExecutor());
}
}

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import org.testng.annotations.Test;
import org.testng.Assert;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
/*
* @test
* @summary Test of diagnostic command GC.run_finalization
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng RunFinalizationTest
*/
public class RunFinalizationTest {
static ReentrantLock lock = new ReentrantLock();
static Condition cond = lock.newCondition();
static volatile boolean wasFinalized = false;
static volatile boolean wasInitialized = false;
class MyObject {
public MyObject() {
/* Make sure object allocation/deallocation is not optimized out */
wasInitialized = true;
}
protected void finalize() {
lock.lock();
wasFinalized = true;
cond.signalAll();
lock.unlock();
}
}
public static MyObject o;
public void run(CommandExecutor executor) {
lock.lock();
o = new MyObject();
o = null;
System.gc();
executor.execute("GC.run_finalization");
int waited = 0;
int waitTime = 15;
try {
System.out.println("Waiting for signal from finalizer");
while (!cond.await(waitTime, TimeUnit.SECONDS)) {
waited += waitTime;
System.out.println(String.format("Waited %d seconds", waited));
}
System.out.println("Received signal");
} catch (InterruptedException e) {
Assert.fail("Test error: Interrupted while waiting for signal from finalizer", e);
} finally {
lock.unlock();
}
if (!wasFinalized) {
Assert.fail("Test failure: Object was not finalized");
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import org.testng.annotations.Test;
import org.testng.Assert;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
/*
* @test
* @summary Test of diagnostic command GC.run
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -XX:+PrintGCDetails -Xloggc:RunGC.gclog RunGCTest
*/
public class RunGCTest {
public void run(CommandExecutor executor) {
executor.execute("GC.run");
Path gcLogPath = Paths.get("RunGC.gclog").toAbsolutePath();
String gcLog = null;
try {
gcLog = new String(Files.readAllBytes(gcLogPath));
} catch (IOException e) {
Assert.fail("Test error: Could not read GC log file: " + gcLogPath, e);
}
OutputAnalyzer output = new OutputAnalyzer(gcLog, "");
output.shouldMatch(".*\\[Full GC \\(System(\\.gc\\(\\))?.*");
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Test of diagnostic command Thread.print -l=true
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @build PrintTest
* @run testng PrintConcurrentLocksTest
*/
public class PrintConcurrentLocksTest extends PrintTest {
public PrintConcurrentLocksTest() {
jucLocks = true;
}
/* See PrintTest for test cases */
}

View File

@ -0,0 +1,174 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import org.testng.annotations.Test;
import org.testng.Assert;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;
/*
* @test
* @summary Test of diagnostic command Thread.print
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng PrintTest
*/
public class PrintTest {
protected boolean jucLocks = false;
CyclicBarrier readyBarrier = new CyclicBarrier(3);
CyclicBarrier doneBarrier = new CyclicBarrier(3);
private void waitForBarrier(CyclicBarrier b) {
try {
b.await();
} catch (InterruptedException | BrokenBarrierException e) {
Assert.fail("Test error: Caught unexpected exception:", e);
}
}
class MonitorThread extends Thread {
Object lock = new Object();
public void run() {
/* Hold lock on "lock" to show up in thread dump */
synchronized (lock) {
/* Signal that we're ready for thread dump */
waitForBarrier(readyBarrier);
/* Released when the thread dump has been taken */
waitForBarrier(doneBarrier);
}
}
}
class LockThread extends Thread {
ReentrantLock lock = new ReentrantLock();
public void run() {
/* Hold lock "lock" to show up in thread dump */
lock.lock();
/* Signal that we're ready for thread dump */
waitForBarrier(readyBarrier);
/* Released when the thread dump has been taken */
waitForBarrier(doneBarrier);
lock.unlock();
}
}
public void run(CommandExecutor executor) {
MonitorThread mThread = new MonitorThread();
mThread.start();
LockThread lThread = new LockThread();
lThread.start();
/* Wait for threads to get ready */
waitForBarrier(readyBarrier);
/* Execute */
OutputAnalyzer output = executor.execute("Thread.print" + (jucLocks ? " -l=true" : ""));
/* Signal that we've got the thread dump */
waitForBarrier(doneBarrier);
/*
* Example output (trimmed) with arrows indicating the rows we are looking for:
*
* ...
* "Thread-2" #24 prio=5 os_prio=0 tid=0x00007f913411f800 nid=0x4fc9 waiting on condition [0x00007f91fbffe000]
* java.lang.Thread.State: WAITING (parking)
* at sun.misc.Unsafe.park(Native Method)
* - parking to wait for <0x000000071a0868a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
* at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
* at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
* at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:234)
* at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362)
* at Print.waitForBarrier(Print.java:26)
* at Print.access$000(Print.java:18)
* at Print$LockThread.run(Print.java:58)
*
* --> Locked ownable synchronizers:
* --> - <0x000000071a294930> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
*
* "Thread-1" #23 prio=5 os_prio=0 tid=0x00007f913411e800 nid=0x4fc8 waiting on condition [0x00007f9200113000]
* java.lang.Thread.State: WAITING (parking)
* at sun.misc.Unsafe.park(Native Method)
* - parking to wait for <0x000000071a0868a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
* at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
* at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
* at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:234)
* at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362)
* at Print.waitForBarrier(Print.java:26)
* at Print.access$000(Print.java:18)
* at Print$MonitorThread.run(Print.java:42)
* --> - locked <0x000000071a294390> (a java.lang.Object)
*
* Locked ownable synchronizers:
* - None
*
* "MainThread" #22 prio=5 os_prio=0 tid=0x00007f923015b000 nid=0x4fc7 in Object.wait() [0x00007f9200840000]
* java.lang.Thread.State: WAITING (on object monitor)
* at java.lang.Object.wait(Native Method)
* - waiting on <0x000000071a70ad98> (a java.lang.UNIXProcess)
* at java.lang.Object.wait(Object.java:502)
* at java.lang.UNIXProcess.waitFor(UNIXProcess.java:397)
* - locked <0x000000071a70ad98> (a java.lang.UNIXProcess)
* at com.oracle.java.testlibrary.dcmd.JcmdExecutor.executeImpl(JcmdExecutor.java:32)
* at com.oracle.java.testlibrary.dcmd.CommandExecutor.execute(CommandExecutor.java:24)
* --> at Print.run(Print.java:74)
* at Print.file(Print.java:112)
* ...
*/
output.shouldMatch(".*at " + Pattern.quote(PrintTest.class.getName()) + "\\.run.*");
output.shouldMatch(".*- locked <0x\\p{XDigit}+> \\(a " + Pattern.quote(mThread.lock.getClass().getName()) + "\\).*");
String jucLockPattern1 = ".*Locked ownable synchronizers:.*";
String jucLockPattern2 = ".*- <0x\\p{XDigit}+> \\(a " + Pattern.quote(lThread.lock.getClass().getName()) + ".*";
if (jucLocks) {
output.shouldMatch(jucLockPattern1);
output.shouldMatch(jucLockPattern2);
} else {
output.shouldNotMatch(jucLockPattern1);
output.shouldNotMatch(jucLockPattern2);
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -23,18 +23,26 @@
/*
* @test
*
* @build ClassLoaderStatsTest DcmdUtil
* @run main ClassLoaderStatsTest
* @summary Test of diagnostic command VM.classloader_stats
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng ClassLoaderStatsTest
*/
import java.io.BufferedReader;
import org.testng.annotations.Test;
import org.testng.Assert;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -57,36 +65,36 @@ public class ClassLoaderStatsTest {
public static DummyClassLoader dummyloader;
public static void main(String arg[]) throws Exception {
public void run(CommandExecutor executor) throws ClassNotFoundException {
// create a classloader and load our special class
dummyloader = new DummyClassLoader();
Class<?> c = Class.forName("TestClass", true, dummyloader);
if (c.getClassLoader() != dummyloader) {
throw new RuntimeException("TestClass defined by wrong classloader: " + c.getClassLoader());
Assert.fail("TestClass defined by wrong classloader: " + c.getClassLoader());
}
String result = DcmdUtil.executeDcmd("VM.classloader_stats");
BufferedReader r = new BufferedReader(new StringReader(result));
String line;
while((line = r.readLine()) != null) {
OutputAnalyzer output = executor.execute("VM.classloader_stats");
Iterator<String> lines = output.asLines().iterator();
while (lines.hasNext()) {
String line = lines.next();
Matcher m = clLine.matcher(line);
if (m.matches()) {
// verify that DummyClassLoader has loaded 1 class and 1 anonymous class
if (m.group(4).equals("ClassLoaderStatsTest$DummyClassLoader")) {
System.out.println("line: " + line);
if (!m.group(1).equals("1")) {
throw new Exception("Should have loaded 1 class: " + line);
Assert.fail("Should have loaded 1 class: " + line);
}
checkPositiveInt(m.group(2));
checkPositiveInt(m.group(3));
String next = r.readLine();
String next = lines.next();
System.out.println("next: " + next);
Matcher m1 = anonLine.matcher(next);
m1.matches();
if (!m1.group(1).equals("1")) {
throw new Exception("Should have loaded 1 anonymous class, but found : " + m1.group(1));
Assert.fail("Should have loaded 1 anonymous class, but found : " + m1.group(1));
}
checkPositiveInt(m1.group(2));
checkPositiveInt(m1.group(3));
@ -95,9 +103,9 @@ public class ClassLoaderStatsTest {
}
}
private static void checkPositiveInt(String s) throws Exception {
private static void checkPositiveInt(String s) {
if (Integer.parseInt(s) <= 0) {
throw new Exception("Value should have been > 0: " + s);
Assert.fail("Value should have been > 0: " + s);
}
}
@ -114,8 +122,11 @@ public class ClassLoaderStatsTest {
{
return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
} catch (IOException e) {
throw new RuntimeException("Can't open file: " + name, e);
Assert.fail("Can't open file: " + name, e);
}
/* Will not reach here as Assert.fail() throws exception */
return null;
}
protected Class<?> loadClass(String name, boolean resolve)
@ -144,6 +155,10 @@ public class ClassLoaderStatsTest {
}
} /* DummyClassLoader */
@Test
public void jmx() throws ClassNotFoundException {
run(new JMXExecutor());
}
}
class TestClass {

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
import org.testng.annotations.Test;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
/*
* @test
* @summary Test of diagnostic command VM.command_line
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis CommandLineTest
*/
public class CommandLineTest {
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("VM.command_line");
output.shouldContain("-XX:+IgnoreUnrecognizedVMOptions");
output.shouldContain("-XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis");
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -1,6 +1,10 @@
import java.util.HashSet;
import java.util.Set;
import org.testng.annotations.Test;
import org.testng.Assert;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.Platform;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
/*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
@ -29,14 +33,15 @@ import com.oracle.java.testlibrary.Platform;
* @test
* @summary Test of VM.dynlib diagnostic command via MBean
* @library /testlibrary
* @build com.oracle.java.testlibrary.* DcmdUtil
* @run main DynLibDcmdTest
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng DynLibsTest
*/
public class DynLibDcmdTest {
public class DynLibsTest {
public static void main(String[] args) throws Exception {
String result = DcmdUtil.executeDcmd("VM.dynlibs");
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("VM.dynlibs");
String osDependentBaseString = null;
if (Platform.isAix()) {
@ -52,18 +57,16 @@ public class DynLibDcmdTest {
}
if (osDependentBaseString == null) {
throw new Exception("Unsupported OS");
Assert.fail("Unsupported OS");
}
Set<String> expectedContent = new HashSet<>();
expectedContent.add(String.format(osDependentBaseString, "jvm"));
expectedContent.add(String.format(osDependentBaseString, "java"));
expectedContent.add(String.format(osDependentBaseString, "management"));
output.shouldContain(String.format(osDependentBaseString, "jvm"));
output.shouldContain(String.format(osDependentBaseString, "java"));
output.shouldContain(String.format(osDependentBaseString, "management"));
}
for(String expected : expectedContent) {
if (!result.contains(expected)) {
throw new Exception("Dynamic library list output did not contain the expected string: '" + expected + "'");
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import org.testng.annotations.Test;
/*
* @test
* @summary Test of diagnostic command VM.flags
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -Xmx129m -XX:+PrintGC -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis_Right -XX:-TieredCompilation FlagsTest
*/
public class FlagsTest {
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("VM.flags");
/* The following are interpreted by the JVM as actual "flags" */
output.shouldContain("-XX:+PrintGC");
output.shouldContain("-XX:+UnlockDiagnosticVMOptions");
output.shouldContain("-XX:+IgnoreUnrecognizedVMOptions");
output.shouldContain("-XX:-TieredCompilation");
/* The following are not */
output.shouldNotContain("-Xmx129m");
output.shouldNotContain("-XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis_Right");
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import org.testng.annotations.Test;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
/*
* @test
* @summary Test of diagnostic command VM.system_properties
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng SystemPropertiesTest
*/
public class SystemPropertiesTest {
private final static String PROPERTY_NAME = "SystemPropertiesTestPropertyName";
private final static String PROPERTY_VALUE = "SystemPropertiesTestPropertyValue";
public void run(CommandExecutor executor) {
System.setProperty(PROPERTY_NAME, PROPERTY_VALUE);
OutputAnalyzer output = executor.execute("VM.system_properties");
output.shouldContain(PROPERTY_NAME + "=" + PROPERTY_VALUE);
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import org.testng.annotations.Test;
import org.testng.Assert;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import java.text.NumberFormat;
import java.text.ParseException;
/*
* @test
* @summary Test of diagnostic command VM.uptime
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng UptimeTest
*/
public class UptimeTest {
public void run(CommandExecutor executor) {
double someUptime = 1.0;
long startTime = System.currentTimeMillis();
try {
synchronized (this) {
/* Loop to guard against spurious wake ups */
while (System.currentTimeMillis() < (startTime + someUptime * 1000)) {
wait((int) someUptime * 1000);
}
}
} catch (InterruptedException e) {
Assert.fail("Test error: Exception caught when sleeping:", e);
}
OutputAnalyzer output = executor.execute("VM.uptime");
output.stderrShouldBeEmpty();
/*
* Output should be:
* [pid]:
* xx.yyy s
*
* If there is only one line in output there is no "[pid]:" printout;
* skip first line, split on whitespace and grab first half
*/
int index = output.asLines().size() == 1 ? 0 : 1;
String uptimeString = output.asLines().get(index).split("\\s+")[0];
try {
double uptime = NumberFormat.getNumberInstance().parse(uptimeString).doubleValue();
if (uptime < someUptime) {
Assert.fail(String.format(
"Test failure: Uptime was less than intended sleep time: %.3f s < %.3f s",
uptime, someUptime));
}
} catch (ParseException e) {
Assert.fail("Test failure: Could not parse uptime string: " +
uptimeString, e);
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -24,6 +24,8 @@
package com.oracle.java.testlibrary;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -69,6 +71,58 @@ public final class OutputAnalyzer {
}
/**
* Verify that the stdout contents of output buffer is empty
*
* @throws RuntimeException
* If stdout was not empty
*/
public void stdoutShouldBeEmpty() {
if (!getStdout().isEmpty()) {
reportDiagnosticSummary();
throw new RuntimeException("stdout was not empty");
}
}
/**
* Verify that the stderr contents of output buffer is empty
*
* @throws RuntimeException
* If stderr was not empty
*/
public void stderrShouldBeEmpty() {
if (!getStderr().isEmpty()) {
reportDiagnosticSummary();
throw new RuntimeException("stderr was not empty");
}
}
/**
* Verify that the stdout contents of output buffer is not empty
*
* @throws RuntimeException
* If stdout was empty
*/
public void stdoutShouldNotBeEmpty() {
if (getStdout().isEmpty()) {
reportDiagnosticSummary();
throw new RuntimeException("stdout was empty");
}
}
/**
* Verify that the stderr contents of output buffer is not empty
*
* @throws RuntimeException
* If stderr was empty
*/
public void stderrShouldNotBeEmpty() {
if (getStderr().isEmpty()) {
reportDiagnosticSummary();
throw new RuntimeException("stderr was empty");
}
}
/**
* Verify that the stdout and stderr contents of output buffer contains the string
*
* @param expectedString String that buffer should contain
@ -365,4 +419,18 @@ public final class OutputAnalyzer {
public int getExitValue() {
return exitValue;
}
/**
* Get the contents of the output buffer (stdout and stderr) as list of strings.
* Output will be split by newlines.
*
* @return Contents of the output buffer as list of strings
*/
public List<String> asLines() {
return asLines(getOutput());
}
private List<String> asLines(String buffer) {
return Arrays.asList(buffer.split("(\\r\\n|\\n|\\r)"));
}
}

View File

@ -184,23 +184,36 @@ public final class ProcessTools {
return executeProcess(pb);
}
/**
* Executes a process, waits for it to finish and returns the process output.
* @param pb The ProcessBuilder to execute.
* @return The output from the process.
*/
public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Throwable {
OutputAnalyzer output = null;
try {
output = new OutputAnalyzer(pb.start());
return output;
} catch (Throwable t) {
System.out.println("executeProcess() failed: " + t);
throw t;
} finally {
System.out.println(getProcessLog(pb, output));
/**
* Executes a process, waits for it to finish and returns the process output.
* The process will have exited before this method returns.
* @param pb The ProcessBuilder to execute.
* @return The {@linkplain OutputAnalyzer} instance wrapping the process.
*/
public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Exception {
OutputAnalyzer output = null;
Process p = null;
boolean failed = false;
try {
p = pb.start();
output = new OutputAnalyzer(p);
p.waitFor();
return output;
} catch (Throwable t) {
if (p != null) {
p.destroyForcibly().waitFor();
}
failed = true;
System.out.println("executeProcess() failed: " + t);
throw t;
} finally {
if (failed) {
System.err.println(getProcessLog(pb, output));
}
}
}
}
/**
* Executes a process, waits for it to finish and returns the process output.

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.java.testlibrary.dcmd;
import com.oracle.java.testlibrary.OutputAnalyzer;
/**
* Abstract base class for Diagnostic Command executors
*/
public abstract class CommandExecutor {
/**
* Execute a diagnostic command
*
* @param cmd The diagnostic command to execute
* @return an {@link jdk.testlibrary.OutputAnalyzer} encapsulating the output of the command
* @throws CommandExecutorException if there is an exception on the "calling side" while trying to execute the
* Diagnostic Command. Exceptions thrown on the remote side are available as textual representations in
* stderr, regardless of the specific executor used.
*/
public final OutputAnalyzer execute(String cmd) throws CommandExecutorException {
System.out.printf("Running DCMD '%s' through '%s'%n", cmd, this.getClass().getSimpleName());
OutputAnalyzer oa = executeImpl(cmd);
System.out.println("---------------- stdout ----------------");
System.out.println(oa.getStdout());
System.out.println("---------------- stderr ----------------");
System.out.println(oa.getStderr());
System.out.println("----------------------------------------");
System.out.println();
return oa;
}
protected abstract OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException;
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.java.testlibrary.dcmd;
/**
* CommandExecutorException encapsulates exceptions thrown (on the "calling side") from the execution of Diagnostic
* Commands
*/
public class CommandExecutorException extends RuntimeException {
private static final long serialVersionUID = -7039597746579144280L;
public CommandExecutorException(String message, Throwable e) {
super(message, e);
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.java.testlibrary.dcmd;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
/**
* Executes Diagnostic Commands on the target VM (specified by pid) using the jcmd tool and its ability to read
* Diagnostic Commands from a file.
*/
public class FileJcmdExecutor extends PidJcmdExecutor {
/**
* Instantiates a new FileJcmdExecutor targeting the current VM
*/
public FileJcmdExecutor() {
super();
}
/**
* Instantiates a new FileJcmdExecutor targeting the VM indicated by the given pid
*
* @param target Pid of the target VM
*/
public FileJcmdExecutor(String target) {
super(target);
}
protected List<String> createCommandLine(String cmd) throws CommandExecutorException {
File cmdFile = createTempFile();
writeCommandToTemporaryFile(cmd, cmdFile);
return Arrays.asList(jcmdBinary, Integer.toString(pid),
"-f", cmdFile.getAbsolutePath());
}
private void writeCommandToTemporaryFile(String cmd, File cmdFile) {
try (PrintWriter pw = new PrintWriter(cmdFile)) {
pw.println(cmd);
} catch (IOException e) {
String message = "Could not write to file: " + cmdFile.getAbsolutePath();
throw new CommandExecutorException(message, e);
}
}
private File createTempFile() {
try {
File cmdFile = File.createTempFile("input", "jcmd");
cmdFile.deleteOnExit();
return cmdFile;
} catch (IOException e) {
throw new CommandExecutorException("Could not create temporary file", e);
}
}
}

View File

@ -0,0 +1,187 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.java.testlibrary.dcmd;
import com.oracle.java.testlibrary.OutputAnalyzer;
import javax.management.*;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.management.ManagementFactory;
import java.util.HashMap;
/**
* Executes Diagnostic Commands on the target VM (specified by a host/port combination or a full JMX Service URL) using
* the JMX interface. If the target is not the current VM, the JMX Remote interface must be enabled beforehand.
*/
public class JMXExecutor extends CommandExecutor {
private final MBeanServerConnection mbs;
/**
* Instantiates a new JMXExecutor targeting the current VM
*/
public JMXExecutor() {
super();
mbs = ManagementFactory.getPlatformMBeanServer();
}
/**
* Instantiates a new JMXExecutor targeting the VM indicated by the given host/port combination or a full JMX
* Service URL
*
* @param target a host/port combination on the format "host:port" or a full JMX Service URL of the target VM
*/
public JMXExecutor(String target) {
String urlStr;
if (target.matches("^\\w[\\w\\-]*(\\.[\\w\\-]+)*:\\d+$")) {
/* Matches "hostname:port" */
urlStr = String.format("service:jmx:rmi:///jndi/rmi://%s/jmxrmi", target);
} else if (target.startsWith("service:")) {
urlStr = target;
} else {
throw new IllegalArgumentException("Could not recognize target string: " + target);
}
try {
JMXServiceURL url = new JMXServiceURL(urlStr);
JMXConnector c = JMXConnectorFactory.connect(url, new HashMap<>());
mbs = c.getMBeanServerConnection();
} catch (IOException e) {
throw new CommandExecutorException("Could not initiate connection to target: " + target, e);
}
}
protected OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException {
String stdout = "";
String stderr = "";
String[] cmdParts = cmd.split(" ", 2);
String operation = commandToMethodName(cmdParts[0]);
Object[] dcmdArgs = produceArguments(cmdParts);
String[] signature = {String[].class.getName()};
ObjectName beanName = getMBeanName();
try {
stdout = (String) mbs.invoke(beanName, operation, dcmdArgs, signature);
}
/* Failures on the "local" side, the one invoking the command. */
catch (ReflectionException e) {
Throwable cause = e.getCause();
if (cause instanceof NoSuchMethodException) {
/* We want JMXExecutor to match the behavior of the other CommandExecutors */
String message = "Unknown diagnostic command: " + operation;
stderr = exceptionTraceAsString(new IllegalArgumentException(message, e));
} else {
rethrowExecutorException(operation, dcmdArgs, e);
}
}
/* Failures on the "local" side, the one invoking the command. */
catch (InstanceNotFoundException | IOException e) {
rethrowExecutorException(operation, dcmdArgs, e);
}
/* Failures on the remote side, the one executing the invoked command. */
catch (MBeanException e) {
stdout = exceptionTraceAsString(e);
}
return new OutputAnalyzer(stdout, stderr);
}
private void rethrowExecutorException(String operation, Object[] dcmdArgs,
Exception e) throws CommandExecutorException {
String message = String.format("Could not invoke: %s %s", operation,
String.join(" ", (String[]) dcmdArgs[0]));
throw new CommandExecutorException(message, e);
}
private ObjectName getMBeanName() throws CommandExecutorException {
String MBeanName = "com.sun.management:type=DiagnosticCommand";
try {
return new ObjectName(MBeanName);
} catch (MalformedObjectNameException e) {
String message = "MBean not found: " + MBeanName;
throw new CommandExecutorException(message, e);
}
}
private Object[] produceArguments(String[] cmdParts) {
Object[] dcmdArgs = {new String[0]}; /* Default: No arguments */
if (cmdParts.length == 2) {
dcmdArgs[0] = cmdParts[1].split(" ");
}
return dcmdArgs;
}
/**
* Convert from diagnostic command to MBean method name
*
* Examples:
* help --> help
* VM.version --> vmVersion
* VM.command_line --> vmCommandLine
*/
private static String commandToMethodName(String cmd) {
String operation = "";
boolean up = false; /* First letter is to be lower case */
/*
* If a '.' or '_' is encountered it is not copied,
* instead the next character will be converted to upper case
*/
for (char c : cmd.toCharArray()) {
if (('.' == c) || ('_' == c)) {
up = true;
} else if (up) {
operation = operation.concat(Character.toString(c).toUpperCase());
up = false;
} else {
operation = operation.concat(Character.toString(c).toLowerCase());
}
}
return operation;
}
private static String exceptionTraceAsString(Throwable cause) {
StringWriter sw = new StringWriter();
cause.printStackTrace(new PrintWriter(sw));
return sw.toString();
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.java.testlibrary.dcmd;
import com.oracle.java.testlibrary.JDKToolFinder;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.ProcessTools;
import java.util.List;
/**
* Base class for Diagnostic Command Executors using the jcmd tool
*/
public abstract class JcmdExecutor extends CommandExecutor {
protected String jcmdBinary;
protected abstract List<String> createCommandLine(String cmd) throws CommandExecutorException;
protected JcmdExecutor() {
jcmdBinary = JDKToolFinder.getJDKTool("jcmd");
}
protected OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException {
List<String> commandLine = createCommandLine(cmd);
try {
System.out.printf("Executing command '%s'%n", commandLine);
OutputAnalyzer output = ProcessTools.executeProcess(new ProcessBuilder(commandLine));
System.out.printf("Command returned with exit code %d%n", output.getExitValue());
return output;
} catch (Exception e) {
String message = String.format("Caught exception while executing '%s'", commandLine);
throw new CommandExecutorException(message, e);
}
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.java.testlibrary.dcmd;
import java.util.Arrays;
import java.util.List;
/**
* Executes Diagnostic Commands on the target VM (specified by main class) using the jcmd tool
*/
public class MainClassJcmdExecutor extends JcmdExecutor {
private final String mainClass;
/**
* Instantiates a new MainClassJcmdExecutor targeting the current VM
*/
public MainClassJcmdExecutor() {
super();
mainClass = System.getProperty("sun.java.command").split(" ")[0];
}
/**
* Instantiates a new MainClassJcmdExecutor targeting the VM indicated by the given main class
*
* @param target Main class of the target VM
*/
public MainClassJcmdExecutor(String target) {
super();
mainClass = target;
}
protected List<String> createCommandLine(String cmd) throws CommandExecutorException {
return Arrays.asList(jcmdBinary, mainClass, cmd);
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.java.testlibrary.dcmd;
import com.oracle.java.testlibrary.ProcessTools;
import java.util.Arrays;
import java.util.List;
/**
* Executes Diagnostic Commands on the target VM (specified by pid) using the jcmd tool
*/
public class PidJcmdExecutor extends JcmdExecutor {
protected final int pid;
/**
* Instantiates a new PidJcmdExecutor targeting the current VM
*/
public PidJcmdExecutor() {
super();
try {
pid = ProcessTools.getProcessId();
} catch (Exception e) {
throw new CommandExecutorException("Could not determine own pid", e);
}
}
/**
* Instantiates a new PidJcmdExecutor targeting the VM indicated by the given pid
*
* @param target Pid of the target VM
*/
public PidJcmdExecutor(String target) {
super();
pid = Integer.valueOf(target);
}
protected List<String> createCommandLine(String cmd) throws CommandExecutorException {
return Arrays.asList(jcmdBinary, Integer.toString(pid), cmd);
}
}