This commit is contained in:
J. Duke 2017-07-05 16:41:28 +02:00
commit d8dbcf3152
358 changed files with 34238 additions and 45988 deletions

View File

@ -9,3 +9,4 @@ cbc8ad9dd0e085a607427ea35411990982f19a36 jdk7-b25
64da805be725721bf2004e7409a0d7a16fc8ddbc jdk7-b32
bb1ef4ee3d2c8cbf43a37d372325a7952be590b9 jdk7-b33
46a989ab932992b2084b946eeb322fa99b9fee6c jdk7-b34
143c1abedb7d3095eff0f9ee5fec9bf48e3490fc jdk7-b35

View File

@ -5,7 +5,7 @@
</head>
<body style="background-color:lightcyan">
<!-- ====================================================== -->
+ <table width="100%">
<table width="100%">
<tr>
<td align="center">
<img alt="OpenJDK"
@ -39,6 +39,11 @@
<li><a href="#introduction">Introduction</a></li>
<li><a href="#MBE">Minimum Build Environments</a></li>
<li><a href="#SDBE">Specific Developer Build Environments</a></li>
<ul>
<li><a href="#fedora">Fedora Linux</a> </li>
<li><a href="#centos">CentOS Linux</a> </li>
<li><a href="#ubuntu">Ubuntu Linux</a> </li>
</ul>
<li><a href="#directories">Source Directory Structure</a> </li>
<li><a href="#building">Build Information</a>
<ul>
@ -182,14 +187,64 @@
we will try to provide what information we have available to us.
</blockquote>
<!-- ------------------------------------------------------ -->
<h3><a name="fedora">Fedora</a></h3>
<h3><a name="fedora">Fedora 9</a></h3>
<blockquote>
TBD
After installing
<a href="http://www.fedoraproject.org/">Fedora 9</a>
you need to make sure you have
the "Software Development" bundle installed, plus the
following packages:
<blockquote>
<ul>
<li>cups devel: Cups Development Package</li>
<li>freetype 2.3+ devel: Freetype 2.3 Development Package</li>
<li>hg: Mercurial, if you need to clone or manage source repositories</li>
<li>ksh: May be needed when using <tt>webrev</tt></li>
</ul>
</blockquote>
<p>
Always a good idea to do a complete Software Update/Refresh
after you get all the packages installed.
</blockquote>
<!-- ------------------------------------------------------ -->
<h3><a name="debian">Debian</a></h3>
<h3><a name="centos">CentOS 5.2</a></h3>
<blockquote>
TBD
After installing
<a href="http://www.centos.org/">CentOS 5.2</a>
you need to make sure you have
the following Development bundles installed:
<blockquote>
<ul>
<li>Development Libraries</li>
<li>Development Tools</li>
<li>Java Development</li>
<li>X Software Development</li>
</ul>
</blockquote>
<p>
Plus the following packages:
<blockquote>
<ul>
<li>cups devel: Cups Development Package</li>
<li>alsa devel: Alsa Development Package</li>
<li>ant: Ant Package</li>
<li>Xi devel: libXi.so Development Package</li>
</ul>
</blockquote>
<p>
The freetype 2.3 packages don't seem to be available,
but the freetype 2.3 sources can be downloaded, built,
and installed easily enough from
<a href="http://downloads.sourceforge.net/freetype">
the freetype site</a>.
Build and install with something like:
<blockquote>
<tt>./configure && make && sudo -u root make install</tt>
</blockquote>
<p>
Mercurial packages could not be found easily, but a Google
search should find ones, and they usually include Python if
it's needed.
</blockquote>
<!-- ------------------------------------------------------ -->
<h3><a name="ubuntu">Ubuntu</a></h3>
@ -664,8 +719,8 @@
</li>
<li>
Install the
<a href="#msvc">Microsoft Visual Studio .NET 2003 Professional</a> or the
<a href="#mssdk">Microsoft Platform SDK</a>.
<a href="#msvc">Microsoft Visual Studio .NET 2003 Professional</a> (32bit) or the
<a href="#mssdk">Microsoft Platform SDK</a> (64bit).
</li>
<li>
Setup all environment variables for compilers
@ -871,6 +926,11 @@
The Microsoft Visual Studio .NET 2005 (VS2005) compiler
will not work at this time due to the new runtime dll
and the manifest requirements.
<p>
<b>WARNING:</b> Make sure you check out the
<a href="#cygwin">CYGWIN link.exe WARNING</a>.
The path <tt>/usr/bin</tt> must be after the path to the
Visual Studio product.
</blockquote>
<strong><a name="mssdk">Windows X64: Microsoft Platform SDK April 2005</a></strong>
<blockquote>
@ -1079,6 +1139,7 @@
<thead>
<tr>
<td>Binary Name</td>
<td>Category</td>
<td>Package</td>
<td>Description</td>
</tr>
@ -1087,50 +1148,59 @@
<tr>
<td>ar.exe</td>
<td>Devel</td>
<td>binutils: The GNU assembler, linker and binary
<td>binutils</td>
<td>The GNU assembler, linker and binary
utilities</td>
</tr>
<tr>
<td>make.exe</td>
<td>Devel</td>
<td>make: The GNU version of the 'make' utility<br>
<td>make</td>
<td>The GNU version of the 'make' utility built for CYGWIN.<br>
<b>NOTE</b>: See <a href="#gmake">the GNU make section</a></td>
</tr>
<tr>
<td>m4.exe</td>
<td>Interpreters</td>
<td>m4: GNU implementation of the traditional Unix macro
<td>m4</td>
<td>GNU implementation of the traditional Unix macro
processor</td>
</tr>
<tr>
<td>cpio.exe</td>
<td>Utils</td>
<td>cpio: A program to manage archives of files</td>
<td>cpio</td>
<td>A program to manage archives of files</td>
</tr>
<tr>
<td>gawk.exe</td>
<td>Utils</td>
<td>awk: Pattern-directed scanning and processing language</td>
<td>awk</td>
<td>Pattern-directed scanning and processing language</td>
</tr>
<tr>
<td>file.exe</td>
<td>Utils</td>
<td>file: Determines file type using 'magic' numbers</td>
<td>file</td>
<td>Determines file type using 'magic' numbers</td>
</tr>
<tr>
<td>zip.exe</td>
<td>Archive</td>
<td>zip: Package and compress (archive) files</td>
<td>zip</td>
<td>Package and compress (archive) files</td>
</tr>
<tr>
<td>unzip.exe</td>
<td>Archive</td>
<td>unzip: Extract compressed files in a ZIP archive</td>
<td>unzip</td>
<td>Extract compressed files in a ZIP archive</td>
</tr>
<tr>
<td>free.exe</td>
<td>Procps</td>
<td>free: Display amount of free and used memory in the system</td>
<td>System</td>
<td>procps</td>
<td>Display amount of free and used memory in the system</td>
</tr>
</tbody>
</table>
@ -1144,6 +1214,13 @@
section on
<a href="http://cygwin.com/faq/faq.using.html#faq.using.bloda" target="_blank">
BLODA (applications that interfere with CYGWIN)</a>.
<p>
<b>WARNING:</b>
Be very careful with <b><tt>link.exe</tt></b>, it will conflict
with the Visual Studio version. You need the Visual Studio
version of <tt>link.exe</tt>, not the CYGWIN one.
So it's important that the Visual Studio paths in PATH preceed
the CYGWIN path <tt>/usr/bin</tt>.
</blockquote>
<strong><a name="dxsdk">Microsoft DirectX 9.0 SDK header files and libraries</a></strong>
<blockquote>
@ -1429,7 +1506,7 @@
build output is to go.
The default output directory will be build/<i>platform</i>.
</dd>
<dt><a name="ALT_SLASHJAVA"><tt>ALT_SLASHJAVA</tt></a></dt>
<dt><a name="ALT_SLASH_JAVA"><tt>ALT_SLASH_JAVA</tt></a></dt>
<dd>
The default root location for many of the ALT path locations
of the following ALT variables.

View File

@ -9,3 +9,4 @@ ef6af34d75a7b44e77083f1d4ee47631fa09d3b4 jdk7-b31
80a0f46a6203e727012bd579fe38a609b83decce jdk7-b32
6a5b9d2f8b20de54e3bfe33cd12bd0793caedc4e jdk7-b33
0a812b9824e5d17b073765d1505594b49ff88a10 jdk7-b34
3867c4d14a5bfdbb37c97b4874ccb0ee5343111c jdk7-b35

View File

@ -1,5 +1,5 @@
#
# Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
# Copyright 2005-2008 Sun Microsystems, Inc. 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
@ -67,16 +67,6 @@ ifeq ($(PLATFORM),windows)
UTILS_DEVTOOL_PATH=$(DEVTOOLS_PATH)
endif
# Utilities ant and findbugs
ifndef ANT_HOME
ANT_HOME = $(JDK_DEVTOOLS_DIR)/share/ant/latest
endif
ANT = $(ANT_HOME)/bin/ant
ifndef FINDBUGS_HOME
FINDBUGS_HOME = $(JDK_DEVTOOLS_DIR)/share/findbugs/latest
endif
FINDBUGS = $(FINDBUGS_HOME)/bin/findbugs
# Utilities
ADB = $(UTILS_COMMAND_PATH)adb
AR = $(UTILS_CCS_BIN_PATH)ar

View File

@ -93,23 +93,13 @@ jdk_import="${ALT_JDK_IMPORT_PATH}"
jdk_devtools="${slashjava}/devtools"
share="${jdk_devtools}/share"
# Needed for langtools, maybe other parts of the build
ANT_HOME="${share}/ant/latest"
export ANT_HOME
FINDBUGS_HOME="${share}/findbugs/latest"
export FINDBUGS_HOME
# The 3 bin directories in common to all platforms
sharebin="${share}/bin"
antbin="${ANT_HOME}/bin"
findbugsbin="${FINDBUGS_HOME}/bin"
# Check input
dirMustExist "${bootdir}" ALT_BOOTDIR
dirMustExist "${slashjava}" ALT_SLASH_JAVA
dirMustExist "${jdk_import}" ALT_JDK_IMPORT_PATH
dirMustExist "${ANT_HOME}" ANT_HOME
dirMustExist "${FINDBUGS_HOME}" FINDBUGS_HOME
# Uses 'uname -s', but only expect SunOS or Linux, assume Windows otherwise.
osname=`uname -s`
@ -133,7 +123,7 @@ if [ "${osname}" = SunOS ] ; then
ALT_COMPILER_PATH="${compiler_path}"
export ALT_COMPILER_PATH
dirMustExist "${compiler_path}" ALT_COMPILER_PATH
path4sdk=${compiler_path}:${sharebin}:${antbin}:${findbugsbin}
path4sdk=${compiler_path}:${sharebin}
# Add basic solaris system paths
path4sdk=${path4sdk}:/usr/ccs/bin:/usr/ccs/lib:/usr/bin:/bin:/usr/sfw/bin
@ -170,7 +160,7 @@ elif [ "${osname}" = Linux ] ; then
ALT_COMPILER_PATH="${compiler_path}"
export ALT_COMPILER_PATH
dirMustExist "${compiler_path}" ALT_COMPILER_PATH
path4sdk=${compiler_path}:${sharebin}:${antbin}:${findbugsbin}
path4sdk=${compiler_path}:${sharebin}
# Add basic paths
path4sdk=${path4sdk}:/usr/bin:/bin:/usr/sbin:/sbin
@ -211,7 +201,7 @@ else
dosname="${mkshome}/mksnt/dosname -s"
# Most unix utilities are in the mksnt directory of ROOTDIR
unixcommand_path="${mkshome}/mksnt"
path4sdk="${sharebin};${antbin};${findbugsbin};${unixcommand_path}"
path4sdk="${sharebin};${unixcommand_path}"
dirMustExist "${unixcommand_path}" ALT_UNIXCOMMAND_PATH
devtools_path="${jdk_devtools}/win32/bin"
path4sdk="${devtools_path};${path4sdk}"
@ -229,7 +219,7 @@ else
dosname="/usr/bin/cygpath -a -m -s"
# Most unix utilities are in the /usr/bin
unixcommand_path="/usr/bin"
path4sdk="${sharebin};${antbin};${findbugsbin};${unixcommand_path}"
path4sdk="${sharebin};${unixcommand_path}"
dirMustExist "${unixcommand_path}" ALT_UNIXCOMMAND_PATH
# Find GNU make
make="${unixcommand_path}/make.exe"

View File

@ -9,3 +9,4 @@ d1605aabd0a15ecf93787c47de63073c33fba52d jdk7-b30
b727c32788a906c04839516ae7443a085185a300 jdk7-b32
585535ec8a14adafa6bfea65d6975e29094c8cec jdk7-b33
5251a9cd8eb8743eee647365bee1c8afdc131556 jdk7-b34
5fa96a5a7e76da7c8dad12486293a0456c2c116c jdk7-b35

View File

@ -1,5 +1,5 @@
/*
* Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2008 Sun Microsystems, Inc. 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
@ -39,9 +39,9 @@ import sun.jvm.hotspot.utilities.*;
<P> Encoding: </P>
<PRE>
bits:
Where: [15]
Type: [14..12]
Offset: [11..0]
Type: [3..0]
Where: [4]
Offset: [31..5]
</PRE>
*/
@ -69,6 +69,7 @@ public class Location {
// Location::Type constants
TYPE_NORMAL = db.lookupIntConstant("Location::normal").intValue();
TYPE_OOP = db.lookupIntConstant("Location::oop").intValue();
TYPE_NARROWOOP = db.lookupIntConstant("Location::narrowoop").intValue();
TYPE_INT_IN_LONG = db.lookupIntConstant("Location::int_in_long").intValue();
TYPE_LNG = db.lookupIntConstant("Location::lng").intValue();
TYPE_FLOAT_IN_DBL = db.lookupIntConstant("Location::float_in_dbl").intValue();
@ -115,6 +116,8 @@ public class Location {
public static final Type NORMAL = new Type("normal");
/** Oop (please GC me!) */
public static final Type OOP = new Type("oop");
/** NarrowOop (please GC me!) */
public static final Type NARROWOOP = new Type("narrowoop");
/** Long held in one register */
public static final Type INT_IN_LONG = new Type("int_in_long");
/** Long held in one register */
@ -142,6 +145,8 @@ public class Location {
return TYPE_NORMAL;
} else if (this == OOP) {
return TYPE_OOP;
} else if (this == NARROWOOP) {
return TYPE_NARROWOOP;
} else if (this == INT_IN_LONG) {
return TYPE_INT_IN_LONG;
} else if (this == LNG) {
@ -170,6 +175,7 @@ public class Location {
// constants in Type enum
private static int TYPE_NORMAL;
private static int TYPE_OOP;
private static int TYPE_NARROWOOP;
private static int TYPE_INT_IN_LONG;
private static int TYPE_LNG;
private static int TYPE_FLOAT_IN_DBL;
@ -185,7 +191,7 @@ public class Location {
Location(Where where, Type type, int offset) {
setWhere(where);
setType(type);
setOffset(offset & 0x0000FFFF);
setOffset(offset);
}
public Where getWhere() {
@ -205,6 +211,8 @@ public class Location {
return Type.NORMAL;
} else if (type == TYPE_OOP) {
return Type.OOP;
} else if (type == TYPE_NARROWOOP) {
return Type.NARROWOOP;
} else if (type == TYPE_INT_IN_LONG) {
return Type.INT_IN_LONG;
} else if (type == TYPE_LNG) {
@ -238,6 +246,10 @@ public class Location {
return getType() == Type.OOP;
}
public boolean holdsNarrowOop() {
return getType() == Type.NARROWOOP;
}
public boolean holdsInt() {
return getType() == Type.INT_IN_LONG;
}
@ -266,7 +278,7 @@ public class Location {
if (Assert.ASSERTS_ENABLED) {
Assert.that(getWhere() == Where.ON_STACK, "wrong Where");
}
return getOffset() << VM.getVM().getLogAddressSize();
return getOffset() * (int)VM.getVM().getIntSize();
}
public int getRegisterNumber() {
@ -296,6 +308,8 @@ public class Location {
if (type == Type.NORMAL) {
} else if (type == Type.OOP) {
tty.print(",oop");
} else if (type == Type.NARROWOOP) {
tty.print(",narrowoop");
} else if (type == Type.INT_IN_LONG) {
tty.print(",int");
} else if (type == Type.LNG) {
@ -314,26 +328,26 @@ public class Location {
/** Serialization of debugging information */
public Location(DebugInfoReadStream stream) {
value = (0x0000FFFF & stream.readInt());
value = stream.readInt();
}
// FIXME: not yet implementable
// void write_on(DebugInfoWriteStream* stream);
//--------------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Internals only below this point
//
private void setWhere(Where where) {
value |= (where.getValue() << WHERE_SHIFT);
value |= ((where.getValue() << WHERE_SHIFT) & WHERE_MASK);
}
private void setType(Type type) {
value |= (type.getValue() << TYPE_SHIFT);
value |= ((type.getValue() << TYPE_SHIFT) & TYPE_MASK);
}
private void setOffset(int offset) {
value |= (offset << OFFSET_SHIFT);
value |= ((offset << OFFSET_SHIFT) & OFFSET_MASK);
}
}

View File

@ -206,6 +206,16 @@ public class CompiledVFrame extends JavaVFrame {
Assert.that( loc.isRegister(), "ints always saved to stack in 1 word" );
}
return new StackValue(valueAddr.getJLongAt(0) & 0xFFFFFFFF);
} else if (loc.holdsNarrowOop()) { // Holds an narrow oop?
if (loc.isRegister() && VM.getVM().isBigEndian()) {
// The callee has no clue whether the register holds an narrow oop,
// long or is unused. He always saves a long. Here we know
// a long was saved, but we only want an narrow oop back. Narrow the
// saved long to the narrow oop that the JVM wants.
return new StackValue(valueAddr.getCompOopHandleAt(VM.getVM().getIntSize()));
} else {
return new StackValue(valueAddr.getCompOopHandleAt(0));
}
} else if( loc.holdsOop() ) { // Holds an oop?
return new StackValue(valueAddr.getOopHandleAt(0));
} else if( loc.holdsDouble() ) {

View File

@ -621,6 +621,11 @@ public class VM {
return bytes;
}
/** Returns true if this is a isBigEndian, false otherwise */
public boolean isBigEndian() {
return isBigEndian;
}
/** Returns true if this is a "core" build, false if either C1 or C2
is present */
public boolean isCore() {

View File

@ -1135,6 +1135,8 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
buf.append("normal");
} else if (type == Location.Type.OOP) {
buf.append("oop");
} else if (type == Location.Type.NARROWOOP) {
buf.append("narrowoop");
} else if (type == Location.Type.INT_IN_LONG) {
buf.append("int");
} else if (type == Location.Type.LNG) {

View File

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2008
HS_MAJOR_VER=14
HS_MINOR_VER=0
HS_BUILD_NUMBER=04
HS_BUILD_NUMBER=05
JDK_MAJOR_VER=1
JDK_MINOR_VER=7

View File

@ -295,3 +295,9 @@ jprt.test.targets = \
${jprt.my.windows.i586.test.targets}, \
${jprt.my.windows.x64.test.targets}
# The default test/Makefile targets that should be run
# Example:
# jprt.make.rule.test.targets=*-*-*-packtest
#jprt.make.rule.test.targets=*-product-*-packtest

View File

@ -1129,8 +1129,8 @@ void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) {
#else
__ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 0));
// push and pop the part at src + wordSize, adding wordSize for the previous push
__ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), wordSize));
__ popl (frame_map()->address_for_slot(dest->double_stack_ix(), wordSize));
__ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 2 * wordSize));
__ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 2 * wordSize));
__ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 0));
#endif // _LP64

View File

@ -1,5 +1,5 @@
/*
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2008 Sun Microsystems, Inc. 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
@ -26,7 +26,7 @@
#include "incls/_location.cpp.incl"
void Location::print_on(outputStream* st) const {
if(type() == invalid && !legal_offset_in_bytes(offset() * BytesPerInt)) {
if(type() == invalid) {
// product of Location::invalid_loc() or Location::Location().
switch (where()) {
case on_stack: st->print("empty"); break;
@ -42,6 +42,7 @@ void Location::print_on(outputStream* st) const {
switch (type()) {
case normal: break;
case oop: st->print(",oop"); break;
case narrowoop: st->print(",narrowoop"); break;
case int_in_long: st->print(",int"); break;
case lng: st->print(",long"); break;
case float_in_dbl: st->print(",float"); break;
@ -53,17 +54,17 @@ void Location::print_on(outputStream* st) const {
Location::Location(DebugInfoReadStream* stream) {
_value = (uint16_t) stream->read_int();
_value = (juint) stream->read_int();
}
void Location::write_on(DebugInfoWriteStream* stream) {
stream->write_int(_value & 0x0000FFFF);
stream->write_int(_value);
}
// Valid argument to Location::new_stk_loc()?
bool Location::legal_offset_in_bytes(int offset_in_bytes) {
if ((offset_in_bytes % BytesPerInt) != 0) return false;
return (offset_in_bytes / BytesPerInt) < (OFFSET_MASK >> OFFSET_SHIFT);
return (juint)(offset_in_bytes / BytesPerInt) < (OFFSET_MASK >> OFFSET_SHIFT);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2008 Sun Microsystems, Inc. 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
@ -28,10 +28,10 @@
//
// Encoding:
//
// bits:
// Where: [15]
// Type: [14..12]
// Offset: [11..0]
// bits (use low bits for best compression):
// Type: [3..0]
// Where: [4]
// Offset: [31..5]
class Location VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
@ -42,6 +42,7 @@ class Location VALUE_OBJ_CLASS_SPEC {
};
enum Type {
invalid, // Invalid location
normal, // Ints, floats, double halves
oop, // Oop (please GC me!)
int_in_long, // Integer held in long register
@ -49,21 +50,21 @@ class Location VALUE_OBJ_CLASS_SPEC {
float_in_dbl, // Float held in double register
dbl, // Double held in one register
addr, // JSR return address
invalid // Invalid location
narrowoop // Narrow Oop (please GC me!)
};
private:
enum {
OFFSET_MASK = (jchar) 0x0FFF,
OFFSET_SHIFT = 0,
TYPE_MASK = (jchar) 0x7000,
TYPE_SHIFT = 12,
WHERE_MASK = (jchar) 0x8000,
WHERE_SHIFT = 15
TYPE_MASK = (juint) 0x0F,
TYPE_SHIFT = 0,
WHERE_MASK = (juint) 0x10,
WHERE_SHIFT = 4,
OFFSET_MASK = (juint) 0xFFFFFFE0,
OFFSET_SHIFT = 5
};
uint16_t _value;
juint _value;
// Create a bit-packed Location
Location(Where where_, Type type_, unsigned offset_) {
@ -74,9 +75,9 @@ class Location VALUE_OBJ_CLASS_SPEC {
}
inline void set(Where where_, Type type_, unsigned offset_) {
_value = (uint16_t) ((where_ << WHERE_SHIFT) |
(type_ << TYPE_SHIFT) |
((offset_ << OFFSET_SHIFT) & OFFSET_MASK));
_value = (juint) ((where_ << WHERE_SHIFT) |
(type_ << TYPE_SHIFT) |
((offset_ << OFFSET_SHIFT) & OFFSET_MASK));
}
public:
@ -86,7 +87,7 @@ class Location VALUE_OBJ_CLASS_SPEC {
// Register location Factory
static Location new_reg_loc( Type t, VMReg reg ) { return Location(in_register, t, reg->value()); }
// Default constructor
Location() { set(on_stack,invalid,(unsigned) -1); }
Location() { set(on_stack,invalid,0); }
// Bit field accessors
Where where() const { return (Where) ((_value & WHERE_MASK) >> WHERE_SHIFT);}

View File

@ -157,6 +157,7 @@ Node *AddNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node *a12 = add1->in(2);
const Type *t12 = phase->type( a12 );
if( t12->singleton() && t12 != Type::TOP && (add1 != add1->in(1)) ) {
assert(add1->in(1) != this, "dead loop in AddNode::Ideal");
add2 = add1->clone();
add2->set_req(2, in(2));
add2 = phase->transform(add2);
@ -173,6 +174,7 @@ Node *AddNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node *a22 = add2->in(2);
const Type *t22 = phase->type( a22 );
if( t22->singleton() && t22 != Type::TOP && (add2 != add2->in(1)) ) {
assert(add2->in(1) != this, "dead loop in AddNode::Ideal");
Node *addx = add2->clone();
addx->set_req(1, in(1));
addx->set_req(2, add2->in(1));

View File

@ -334,6 +334,9 @@ static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, c
case Type::InstPtr:
st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop());
break;
case Type::NarrowOop:
st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_oopptr()->const_oop());
break;
case Type::RawPtr:
st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,t->is_rawptr());
break;

View File

@ -1967,6 +1967,7 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
!n->is_Proj() &&
nop != Op_CreateEx &&
nop != Op_CheckCastPP &&
nop != Op_DecodeN &&
!n->is_Mem() ) {
Node *x = n->clone();
call->set_req( TypeFunc::Parms, x );
@ -2075,20 +2076,27 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
case Op_CmpP:
// Do this transformation here to preserve CmpPNode::sub() and
// other TypePtr related Ideal optimizations (for example, ptr nullness).
if( n->in(1)->is_DecodeN() ) {
if (n->in(1)->is_DecodeN() || n->in(2)->is_DecodeN()) {
Node* in1 = n->in(1);
Node* in2 = n->in(2);
if (!in1->is_DecodeN()) {
in2 = in1;
in1 = n->in(2);
}
assert(in1->is_DecodeN(), "sanity");
Compile* C = Compile::current();
Node* in2 = NULL;
if( n->in(2)->is_DecodeN() ) {
in2 = n->in(2)->in(1);
} else if ( n->in(2)->Opcode() == Op_ConP ) {
const Type* t = n->in(2)->bottom_type();
if (t == TypePtr::NULL_PTR) {
Node *in1 = n->in(1);
Node* new_in2 = NULL;
if (in2->is_DecodeN()) {
new_in2 = in2->in(1);
} else if (in2->Opcode() == Op_ConP) {
const Type* t = in2->bottom_type();
if (t == TypePtr::NULL_PTR && UseImplicitNullCheckForNarrowOop) {
if (Matcher::clone_shift_expressions) {
// x86, ARM and friends can handle 2 adds in addressing mode.
// Decode a narrow oop and do implicit NULL check in address
// [R12 + narrow_oop_reg<<3 + offset]
in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
} else {
// Don't replace CmpP(o ,null) if 'o' is used in AddP
// to generate implicit NULL check on Sparc where
@ -2099,16 +2107,22 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
break;
}
if (i >= in1->outcnt()) {
in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
}
}
} else if (t->isa_oopptr()) {
in2 = ConNode::make(C, t->make_narrowoop());
new_in2 = ConNode::make(C, t->make_narrowoop());
}
}
if( in2 != NULL ) {
Node* cmpN = new (C, 3) CmpNNode(n->in(1)->in(1), in2);
if (new_in2 != NULL) {
Node* cmpN = new (C, 3) CmpNNode(in1->in(1), new_in2);
n->subsume_by( cmpN );
if (in1->outcnt() == 0) {
in1->disconnect_inputs(NULL);
}
if (in2->outcnt() == 0) {
in2->disconnect_inputs(NULL);
}
}
}
break;
@ -2214,6 +2228,9 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
// Replacing Opaque nodes with their input in final_graph_reshaping_impl(),
// requires that the walk visits a node's inputs before visiting the node.
static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &fpu ) {
ResourceArea *area = Thread::current()->resource_area();
Unique_Node_List sfpt(area);
fpu._visited.set(root->_idx); // first, mark node as visited
uint cnt = root->req();
Node *n = root;
@ -2224,6 +2241,8 @@ static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Re
Node* m = n->in(i);
++i;
if (m != NULL && !fpu._visited.test_set(m->_idx)) {
if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL)
sfpt.push(m);
cnt = m->req();
nstack.push(n, i); // put on stack parent and next input's index
n = m;
@ -2240,6 +2259,41 @@ static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Re
nstack.pop(); // Shift to the next node on stack
}
}
// Go over safepoints nodes to skip DecodeN nodes for debug edges.
// It could be done for an uncommon traps or any safepoints/calls
// if the DecodeN node is referenced only in a debug info.
while (sfpt.size() > 0) {
n = sfpt.pop();
JVMState *jvms = n->as_SafePoint()->jvms();
assert(jvms != NULL, "sanity");
int start = jvms->debug_start();
int end = n->req();
bool is_uncommon = (n->is_CallStaticJava() &&
n->as_CallStaticJava()->uncommon_trap_request() != 0);
for (int j = start; j < end; j++) {
Node* in = n->in(j);
if (in->is_DecodeN()) {
bool safe_to_skip = true;
if (!is_uncommon ) {
// Is it safe to skip?
for (uint i = 0; i < in->outcnt(); i++) {
Node* u = in->raw_out(i);
if (!u->is_SafePoint() ||
u->is_Call() && u->as_Call()->has_non_debug_use(n)) {
safe_to_skip = false;
}
}
}
if (safe_to_skip) {
n->set_req(j, in->in(1));
}
if (in->outcnt() == 0) {
in->disconnect_inputs(NULL);
}
}
}
}
}
//------------------------------final_graph_reshaping--------------------------

View File

@ -1212,6 +1212,7 @@ Node* GraphKit::null_check_common(Node* value, BasicType type,
Deoptimization::Action_make_not_entrant,
NULL, "assert_null");
} else {
replace_in_map(value, zerocon(type));
builtin_throw(reason);
}
}
@ -1960,6 +1961,7 @@ Node* GraphKit::null_check_oop(Node* value, Node* *null_control,
// method will be compiled to handle NULLs.
PreserveJVMState pjvms(this);
set_control(*null_control);
replace_in_map(value, null());
uncommon_trap(Deoptimization::Reason_null_check,
Deoptimization::Action_make_not_entrant);
(*null_control) = top(); // NULL path is dead

View File

@ -58,6 +58,9 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe
not_null_block = _succs[0];
null_block = _succs[1];
}
while (null_block->is_Empty() == Block::empty_with_goto) {
null_block = null_block->_succs[0];
}
// Search the exception block for an uncommon trap.
// (See Parse::do_if and Parse::do_ifnull for the reason
@ -149,6 +152,10 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe
const TypePtr *adr_type = NULL; // Do not need this return value here
const Node* base = mach->get_base_and_disp(offset, adr_type);
if (base == NULL || base == NodeSentinel) {
// Narrow oop address doesn't have base, only index
if( val->bottom_type()->isa_narrowoop() &&
MacroAssembler::needs_explicit_null_check(offset) )
continue; // Give up if offset is beyond page size
// cannot reason about it; is probably not implicit null exception
} else {
const TypePtr* tptr = base->bottom_type()->is_ptr();

View File

@ -932,7 +932,7 @@ void PhaseIdealLoop::split_if_with_blocks_post( Node *n ) {
// to fold a StoreP and an AddP together (as part of an
// address expression) and the AddP and StoreP have
// different controls.
if( !x->is_Load() ) _igvn._worklist.yank(x);
if( !x->is_Load() && !x->is_DecodeN() ) _igvn._worklist.yank(x);
}
_igvn.remove_dead_node(n);
}

View File

@ -685,6 +685,8 @@ void Compile::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local,
} else if( t->base() == Type::Int && OptoReg::is_reg(regnum) ) {
array->append(new_loc_value( _regalloc, regnum, Matcher::int_in_long
? Location::int_in_long : Location::normal ));
} else if( t->base() == Type::NarrowOop ) {
array->append(new_loc_value( _regalloc, regnum, Location::narrowoop ));
} else {
array->append(new_loc_value( _regalloc, regnum, _regalloc->is_oop(local) ? Location::oop : Location::normal ));
}
@ -704,6 +706,13 @@ void Compile::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local,
case Type::KlassPtr: // fall through
array->append(new ConstantOopWriteValue(t->isa_oopptr()->const_oop()->encoding()));
break;
case Type::NarrowOop:
if (t == TypeNarrowOop::NULL_PTR) {
array->append(new ConstantOopWriteValue(NULL));
} else {
array->append(new ConstantOopWriteValue(t->make_ptr()->isa_oopptr()->const_oop()->encoding()));
}
break;
case Type::Int:
array->append(new ConstantIntValue(t->is_int()->get_con()));
break;
@ -878,9 +887,14 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
}
} else if( !obj_node->is_Con() ) {
OptoReg::Name obj_reg = _regalloc->get_reg_first(obj_node);
scval = new_loc_value( _regalloc, obj_reg, Location::oop );
if( obj_node->bottom_type()->base() == Type::NarrowOop ) {
scval = new_loc_value( _regalloc, obj_reg, Location::narrowoop );
} else {
scval = new_loc_value( _regalloc, obj_reg, Location::oop );
}
} else {
scval = new ConstantOopWriteValue(obj_node->bottom_type()->is_instptr()->const_oop()->encoding());
const TypePtr *tp = obj_node->bottom_type()->make_ptr();
scval = new ConstantOopWriteValue(tp->is_instptr()->const_oop()->encoding());
}
OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node);

View File

@ -527,6 +527,7 @@ uint PhaseChaitin::Split( uint maxlrg ) {
// Initialize needs_phi and needs_split
bool needs_phi = false;
bool needs_split = false;
bool has_phi = false;
// Walk the predecessor blocks to check inputs for that live range
// Grab predecessor block header
n1 = b->pred(1);
@ -570,28 +571,30 @@ uint PhaseChaitin::Split( uint maxlrg ) {
}
} // End for all potential Phi inputs
// If a phi is needed, check for it
if( needs_phi ) {
// check block for appropriate phinode & update edges
for( insidx = 1; insidx <= b->end_idx(); insidx++ ) {
n1 = b->_nodes[insidx];
// bail if this is not a phi
phi = n1->is_Phi() ? n1->as_Phi() : NULL;
if( phi == NULL ) {
// Keep track of index of first non-PhiNode instruction in block
non_phi = insidx;
// break out of the for loop as we have handled all phi nodes
break;
}
// must be looking at a phi
if( Find_id(n1) == lidxs.at(slidx) ) {
// found the necessary phi
needs_phi = false;
// initialize the Reaches entry for this LRG
Reachblock[slidx] = phi;
break;
} // end if found correct phi
} // end for all phi's
// check block for appropriate phinode & update edges
for( insidx = 1; insidx <= b->end_idx(); insidx++ ) {
n1 = b->_nodes[insidx];
// bail if this is not a phi
phi = n1->is_Phi() ? n1->as_Phi() : NULL;
if( phi == NULL ) {
// Keep track of index of first non-PhiNode instruction in block
non_phi = insidx;
// break out of the for loop as we have handled all phi nodes
break;
}
// must be looking at a phi
if( Find_id(n1) == lidxs.at(slidx) ) {
// found the necessary phi
needs_phi = false;
has_phi = true;
// initialize the Reaches entry for this LRG
Reachblock[slidx] = phi;
break;
} // end if found correct phi
} // end for all phi's
// If a phi is needed or exist, check for it
if( needs_phi || has_phi ) {
// add new phinode if one not already found
if( needs_phi ) {
// create a new phi node and insert it into the block
@ -695,7 +698,8 @@ uint PhaseChaitin::Split( uint maxlrg ) {
}
}
assert( u, "at least 1 valid input expected" );
if( i >= cnt ) { // Didn't find 2+ unique inputs?
if( i >= cnt ) { // Found one unique input
assert(Find_id(n) == Find_id(u), "should be the same lrg");
n->replace_by(u); // Then replace with unique input
n->disconnect_inputs(NULL);
b->_nodes.remove(insidx);

View File

@ -1204,15 +1204,17 @@ void Arguments::set_ergonomics_flags() {
// Turn off until bug is fixed.
// FLAG_SET_ERGO(bool, UseCompressedOops, true);
}
#ifdef _WIN64
if (UseLargePages && UseCompressedOops) {
// Cannot allocate guard pages for implicit checks in indexed addressing
// mode, when large pages are specified on windows.
FLAG_SET_DEFAULT(UseImplicitNullCheckForNarrowOop, false);
}
#endif // _WIN64
} else {
if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) {
// If specified, give a warning
if (UseConcMarkSweepGC){
warning("Compressed Oops does not work with CMS");
} else {
warning(
"Max heap size too large for Compressed Oops");
}
warning( "Max heap size too large for Compressed Oops");
FLAG_SET_DEFAULT(UseCompressedOops, false);
}
}

View File

@ -294,6 +294,9 @@ class CommandLineFlags {
lp64_product(bool, CheckCompressedOops, trueInDebug, \
"generate checks in encoding/decoding code") \
\
product(bool, UseImplicitNullCheckForNarrowOop, true, \
"generate implicit null check in indexed addressing mode.") \
\
/* UseMembar is theoretically a temp flag used for memory barrier \
* removal testing. It was supposed to be removed before FCS but has \
* been re-added (see 6401008) */ \

View File

@ -1,5 +1,5 @@
/*
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2008 Sun Microsystems, Inc. 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
@ -86,6 +86,22 @@ StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* r
case Location::lng:
// Long value in an aligned adjacent pair
return new StackValue(*(intptr_t*)value_addr);
case Location::narrowoop: {
union { intptr_t p; narrowOop noop;} value;
value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
if (loc.is_register()) {
// The callee has no clue whether the register holds an int,
// long or is unused. He always saves a long. Here we know
// a long was saved, but we only want an int back. Narrow the
// saved long to the int that the JVM wants.
value.noop = (narrowOop) *(julong*) value_addr;
} else {
value.noop = *(narrowOop*) value_addr;
}
// Decode narrowoop and wrap a handle around the oop
Handle h(oopDesc::decode_heap_oop(value.noop));
return new StackValue(h);
}
#endif
case Location::oop: {
Handle h(*(oop *)value_addr); // Wrap a handle around the oop

View File

@ -2756,13 +2756,17 @@ void Threads::threads_do(ThreadClosure* tc) {
// For now, just manually iterate through them.
tc->do_thread(VMThread::vm_thread());
Universe::heap()->gc_threads_do(tc);
{
// Grab the Terminator_lock to prevent watcher_thread from being terminated.
MutexLockerEx mu(Terminator_lock, Mutex::_no_safepoint_check_flag);
WatcherThread *wt = WatcherThread::watcher_thread();
if (wt != NULL)
tc->do_thread(wt);
}
WatcherThread *wt = WatcherThread::watcher_thread();
// Strictly speaking, the following NULL check isn't sufficient to make sure
// the data for WatcherThread is still valid upon being examined. However,
// considering that WatchThread terminates when the VM is on the way to
// exit at safepoint, the chance of the above is extremely small. The right
// way to prevent termination of WatcherThread would be to acquire
// Terminator_lock, but we can't do that without violating the lock rank
// checking in some cases.
if (wt != NULL)
tc->do_thread(wt);
// If CompilerThreads ever become non-JavaThreads, add them here
}

View File

@ -380,7 +380,8 @@ ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment,
bool large, char* requested_address) :
ReservedSpace(size, alignment, large,
requested_address,
UseCompressedOops ? lcm(os::vm_page_size(), alignment) : 0) {
UseCompressedOops && UseImplicitNullCheckForNarrowOop ?
lcm(os::vm_page_size(), alignment) : 0) {
// Only reserved space for the java heap should have a noaccess_prefix
// if using compressed oops.
protect_noaccess_prefix(size);
@ -391,7 +392,8 @@ ReservedHeapSpace::ReservedHeapSpace(const size_t prefix_size,
const size_t suffix_size,
const size_t suffix_align) :
ReservedSpace(prefix_size, prefix_align, suffix_size, suffix_align,
UseCompressedOops ? lcm(os::vm_page_size(), prefix_align) : 0) {
UseCompressedOops && UseImplicitNullCheckForNarrowOop ?
lcm(os::vm_page_size(), prefix_align) : 0) {
protect_noaccess_prefix(prefix_size+suffix_size);
}

View File

@ -1577,6 +1577,7 @@ static inline uint64_t cast_uint64_t(size_t x)
\
declare_constant(Location::normal) \
declare_constant(Location::oop) \
declare_constant(Location::narrowoop) \
declare_constant(Location::int_in_long) \
declare_constant(Location::lng) \
declare_constant(Location::float_in_dbl) \

View File

@ -1,5 +1,5 @@
#
# Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
# Copyright 1995-2008 Sun Microsystems, Inc. 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
@ -19,17 +19,18 @@
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
#
#
#
# Makefile to run jtreg
# Makefile to run various jdk tests
#
# Get OS/ARCH specifics
OSNAME = $(shell uname -s)
SLASH_JAVA = /java
ifeq ($(OSNAME), SunOS)
PLATFORM = solaris
JCT_PLATFORM = solaris
ARCH = $(shell uname -p)
ifeq ($(ARCH), i386)
ARCH=i586
@ -37,203 +38,165 @@ ifeq ($(OSNAME), SunOS)
endif
ifeq ($(OSNAME), Linux)
PLATFORM = linux
JCT_PLATFORM = linux
ARCH = $(shell uname -m)
ifeq ($(ARCH), i386)
ARCH=i586
ARCH = i586
endif
endif
ifeq ($(OSNAME), Windows_NT)
PLATFORM = windows
JCT_PLATFORM = win32
SLASH_JAVA = J:
ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),ia64)
ARCH=ia64
ARCH = ia64
else
ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),AMD64)
ARCH=x64
ARCH = x64
else
ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),EM64T)
ARCH=x64
ARCH = x64
else
ARCH=i586
ARCH = i586
endif
endif
endif
EXESUFFIX = .exe
endif
# Default bundle of all test results (passed or not)
JPRT_ARCHIVE_BUNDLE=$(TEST_ROOT)/JPRT_ARCHIVE_BUNDLE.zip
# Utilities used
CD = cd
CP = cp
ECHO = echo
MKDIR = mkdir
ZIP = zip
# Default home for JTREG
ifeq ($(PLATFORM), windows)
JT_HOME = J:/svc/jct-tools3.2.2_01
else
JT_HOME = /java/svc/jct-tools3.2.2_01
endif
# Default JTREG to run
JTREG = $(JT_HOME)/$(JCT_PLATFORM)/bin/jtreg
# Root of this test area
# Root of this test area (important to use full paths in some places)
TEST_ROOT := $(shell pwd)
# Default JDK to test
JAVA_HOME = $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH)
# The test directories to run
DEFAULT_TESTDIRS = serviceability
TESTDIRS = $(DEFAULT_TESTDIRS)
# Files that hold total passed and failed counts (passed==0 is bad)
JTREG_TOTALS_DIR = $(TEST_ROOT)/JTREG_TOTALS_$(PLATFORM)_$(ARCH)
JTREG_FAILED = $(JTREG_TOTALS_DIR)/failed_count
JTREG_PASSED = $(JTREG_TOTALS_DIR)/passed_count
# Root of all test results
JTREG_ALL_OUTPUT_DIRNAME = JTREG_OUTPUT_$(PLATFORM)_$(ARCH)
JTREG_ALL_OUTPUT_DIR = $(TEST_ROOT)/$(JTREG_ALL_OUTPUT_DIRNAME)
ABS_BUILD_ROOT = $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH)
ABS_TEST_OUTPUT_DIR = $(ABS_BUILD_ROOT)/testoutput
# Test results for one test directory
JTREG_TEST_OUTPUT_DIR = $(JTREG_ALL_OUTPUT_DIR)/$@
JTREG_TEST_REPORT_DIR = $(JTREG_TEST_OUTPUT_DIR)/JTreport
JTREG_TEST_WORK_DIR = $(JTREG_TEST_OUTPUT_DIR)/JTwork
JTREG_TEST_SUMMARY = $(JTREG_TEST_REPORT_DIR)/summary.txt
# Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test)
ifndef PRODUCT_HOME
# Try to use j2sdk-image if it exists
ABS_JDK_IMAGE = $(ABS_BUILD_ROOT)/j2sdk-image
PRODUCT_HOME := \
$(shell \
if [ -d $(ABS_JDK_IMAGE) ] ; then \
$(ECHO) "$(ABS_JDK_IMAGE)"; \
else \
$(ECHO) "$(ABS_BUILD_ROOT)" ; \
fi)
endif
# Temp files used by this Makefile
JTREG_TEST_TEMP_DIR = $(JTREG_ALL_OUTPUT_DIR)/$@/temp
JTREG_TEMP_PASSED = $(JTREG_TEST_TEMP_DIR)/passed
JTREG_TEMP_FAILED = $(JTREG_TEST_TEMP_DIR)/failed
JTREG_TEMP_OUTPUT = $(JTREG_TEST_TEMP_DIR)/output
JTREG_TEMP_RESULTS = $(JTREG_TEST_TEMP_DIR)/results
# Expect JPRT to set JAVA_ARGS (e.g. -server etc.)
JAVA_OPTIONS =
ifdef JAVA_ARGS
JAVA_OPTIONS = $(JAVA_ARGS)
endif
# JTREG options (different for 2.1.6 and 3.2.2_01)
JTREG_COMMON_OPTIONS = -r:$(JTREG_TEST_REPORT_DIR) \
-w:$(JTREG_TEST_WORK_DIR) \
-testjdk:$(JAVA_HOME) \
-automatic \
-verbose:all
JTREG_216_OPTIONS = $(JTREG_COMMON_OPTIONS) $@ $(JAVA_ARGS)
JTREG_322_OPTIONS = $(JTREG_COMMON_OPTIONS) $(JAVA_ARGS:%=-vmoption:%) $@
# Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results)
ARCHIVE_BUNDLE = $(ABS_TEST_OUTPUT_DIR)/ARCHIVE_BUNDLE.zip
ifdef JPRT_ARCHIVE_BUNDLE
ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE)
endif
# Default make rule
all: clean check tests
# How to create the test bundle (pass or fail, we want to create this)
BUNDLE_UP = ( $(MKDIR) -p `dirname $(ARCHIVE_BUNDLE)` \
&& $(CD) $(ABS_TEST_OUTPUT_DIR) \
&& $(ZIP) -q -r $(ARCHIVE_BUNDLE) . )
BUNDLE_UP_FAILED = ( exitCode=$$? && $(BUNDLE_UP) && exit $${exitCode} )
# Chaeck to make sure these directories exist
check: $(JT_HOME) $(JAVA_HOME) $(JTREG)
################################################################
# Prime the test run
primecounts: FRC
@rm -f -r $(JTREG_TOTALS_DIR)
@mkdir -p $(JTREG_TOTALS_DIR)
@echo "0" > $(JTREG_FAILED)
@echo "0" > $(JTREG_PASSED)
# Default make rule (runs jtreg_tests)
all: jtreg_tests
@$(ECHO) "Testing completed successfully"
# Run the tests and determine the 'make' command exit status
# Ultimately we determine the make exit code based on the passed/failed count
tests: primecounts $(TESTDIRS)
@echo "JTREG TOTAL: passed=`cat $(JTREG_PASSED)` failed=`cat $(JTREG_FAILED)`"
zip -q -r $(JPRT_ARCHIVE_BUNDLE) $(JTREG_ALL_OUTPUT_DIRNAME)
@if [ `cat $(JTREG_FAILED)` -ne 0 -o \
`cat $(JTREG_PASSED)` -le 0 ] ; then \
echo "JTREG FAILED"; \
exit 1; \
else \
echo "JTREG PASSED"; \
exit 0; \
fi
# Just make sure these directires exist
$(JT_HOME) $(JAVA_HOME): FRC
@if [ ! -d $@ ] ; then \
echo "ERROR: Directory $@ does not exist"; \
exit 1; \
fi
# Make sure this file exists
$(JTREG): FRC
@if [ ! -f $@ ] ; then \
echo "ERROR: File $@ does not exist"; \
exit 1; \
fi
# Process each test directory one by one, this rule always completes.
# Note that the use of 'tee' tosses the jtreg process exit status, this
# is as expected because even if jtreg fails, we need to save the
# output. So we update the JTREG_PASSED and JTREG_FAILED count files.
# Note that missing the 'results:' line in the last few lines of output
# will indicate a failure (or a bump by one of the JTREG_FAILED file.
# Note that passed: 0 or no passed: indication means a failure.
# Note that any indication of the word 'failed' indicates failure.
# Ultimately if the contents of JTREG_FAILED is not 0, we have failed
# tests, and if the contents of JTREG_PASSED is 0, we consider that a
# failure.
$(TESTDIRS): FRC
@if [ ! -d $@ ] ; then \
echo "ERROR: Directory $@ does not exist"; \
exit 1; \
fi
@echo "---------------------------------------------------"
@rm -f -r $(JTREG_TEST_OUTPUT_DIR)
@mkdir -p $(JTREG_TEST_OUTPUT_DIR)
@mkdir -p $(JTREG_TEST_WORK_DIR)
@mkdir -p $(JTREG_TEST_WORK_DIR)/scratch
@mkdir -p $(JTREG_TEST_REPORT_DIR)
@mkdir -p $(JTREG_TEST_TEMP_DIR)
@echo "Testing $@"
@echo "Using JAVA_HOME=$(JAVA_HOME)"
@echo "Using JAVA_ARGS=$(JAVA_ARGS)"
@if [ "`$(JTREG) -help 2>&1 | fgrep -- -vmoption`" != "" ] ; then \
echo "Assume we are using jtreg 3.2.2_01 or newer"; \
echo "$(JTREG) $(JTREG_322_OPTIONS)"; \
$(JTREG) $(JTREG_322_OPTIONS) 2>&1 | tee $(JTREG_TEMP_OUTPUT) ; \
else \
echo "Assume we are using jtreg 2.1.6"; \
echo "$(JTREG) $(JTREG_216_OPTIONS)"; \
$(JTREG) $(JTREG_216_OPTIONS) 2>&1 | tee $(JTREG_TEMP_OUTPUT) ; \
fi
@echo "---------------------------------------------------"
@echo "Extracting passed and failed counts from jtreg output"
@tail -10 $(JTREG_TEMP_OUTPUT) | fgrep -i 'results:' | \
tail -1 | tee $(JTREG_TEMP_RESULTS)
@sed -e 's@.*\ passed:\ \([1-9][0-9]*\).*@\1@' $(JTREG_TEMP_RESULTS) \
> $(JTREG_TEMP_PASSED)
@if [ "`cat $(JTREG_TEMP_PASSED)`" = "" ] ; then \
echo "ERROR: No passed indication in results"; \
expr `cat $(JTREG_FAILED)` '+' 1 > $(JTREG_FAILED); \
elif [ `cat $(JTREG_TEMP_PASSED)` -le 0 ] ; then \
echo "ERROR: Passed count appears to be 0"; \
expr `cat $(JTREG_FAILED)` '+' 1 > $(JTREG_FAILED); \
elif [ "`fgrep -i failed $(JTREG_TEMP_RESULTS)`" = "" ] ; then \
echo "No indication anything failed"; \
expr `cat $(JTREG_PASSED)` '+' `cat $(JTREG_TEMP_PASSED)` \
> $(JTREG_PASSED); \
else \
sed -e 's@.*\ failed:\ \([1-9][0-9]*\).*@\1@' $(JTREG_TEMP_FAILED) \
> $(JTREG_TEMP_FAILED); \
if [ "`cat $(JTREG_TEMP_FAILED)`" = "" ] ; then \
echo "ERROR: Failed pattern but no failed count in results"; \
expr `cat $(JTREG_FAILED)` '+' 1 > $(JTREG_FAILED); \
elif [ `cat $(JTREG_TEMP_FAILED)` -le 0 ] ; then \
echo "ERROR: Failed count is 0, did something failed or not?"; \
expr `cat $(JTREG_FAILED)` '+' 1 > $(JTREG_FAILED); \
else \
expr `cat $(JTREG_FAILED)` '+' `cat $(JTREG_TEMP_FAILED)` \
> $(JTREG_FAILED); \
fi; \
fi
@echo "---------------------------------------------------"
@echo "Summary: "
@if [ -f $(JTREG_TEST_SUMMARY) ] ; then \
cat $(JTREG_TEST_SUMMARY) ; \
else \
echo "ERROR: Missing $(JTREG_TEST_SUMMARY)"; \
fi
@echo "---------------------------------------------------"
# Prep for output
prep: clean
@$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR)
@$(MKDIR) -p `dirname $(ARCHIVE_BUNDLE)`
# Cleanup
clean:
rm -f -r $(JTREG_ALL_OUTPUT_DIR)
rm -f $(JPRT_ARCHIVE_BUNDLE)
$(RM) -r $(ABS_TEST_OUTPUT_DIR)
$(RM) $(ARCHIVE_BUNDLE)
FRC:
################################################################
# jtreg tests
# Expect JT_HOME to be set for jtreg tests. (home for jtreg)
JT_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg
ifdef JPRT_JTREG_HOME
JT_HOME = $(JPRT_JTREG_HOME)
endif
# Expect JPRT to set TESTDIRS to the jtreg test dirs
JTREG_TESTDIRS = demo/jvmti/gctest demo/jvmti/hprof
ifdef TESTDIRS
JTREG_TESTDIRS = $(TESTDIRS)
endif
# Default JTREG to run (win32 script works for everybody)
JTREG = $(JT_HOME)/win32/bin/jtreg
# Option to tell jtreg to not run tests marked with "ignore"
ifeq ($(PLATFORM), windows)
JTREG_KEY_OPTION = -k:!ignore
else
JTREG_KEY_OPTION = -k:\!ignore
endif
#EXTRA_JTREG_OPTIONS =
jtreg_tests: prep $(JT_HOME) $(PRODUCT_HOME) $(JTREG)
$(JTREG) -a -v:fail,error \
$(JTREG_KEY_OPTION) \
$(EXTRA_JTREG_OPTIONS) \
-r:$(ABS_TEST_OUTPUT_DIR)/JTreport \
-w:$(ABS_TEST_OUTPUT_DIR)/JTwork \
-jdk:$(PRODUCT_HOME) \
$(JAVA_OPTIONS:%=-vmoption:%) \
$(JTREG_TESTDIRS) \
|| $(BUNDLE_UP_FAILED)
$(BUNDLE_UP)
PHONY_LIST += jtreg_tests
################################################################
# packtest
# Expect JPRT to set JPRT_PACKTEST_HOME.
PACKTEST_HOME = /net/jprt-web.sfbay.sun.com/jprt/allproducts/packtest
ifdef JPRT_PACKTEST_HOME
PACKTEST_HOME = $(JPRT_PACKTEST_HOME)
endif
#EXTRA_PACKTEST_OPTIONS =
packtest: prep $(PACKTEST_HOME)/ptest $(PRODUCT_HOME)
( $(CD) $(PACKTEST_HOME) && \
$(PACKTEST_HOME)/ptest \
-t "$(PRODUCT_HOME)" \
$(PACKTEST_STRESS_OPTION) \
$(EXTRA_PACKTEST_OPTIONS) \
-W $(ABS_TEST_OUTPUT_DIR) \
$(JAVA_OPTIONS:%=-J %) \
) || $(BUNDLE_UP_FAILED)
$(BUNDLE_UP)
packtest_stress: PACKTEST_STRESS_OPTION=-s
packtest_stress: packtest
PHONY_LIST += packtest packtest_stress
################################################################
# Phony targets (e.g. these are not filenames)
.PHONY: all clean prep $(PHONY_LIST)
################################################################

View File

@ -9,3 +9,4 @@ b7474b739d13bacd9972f88ac91f6350b7b0be12 jdk7-b31
c51121419e30eac5f0fbbce45ff1711c4ce0de28 jdk7-b32
fa4c0a6cdd25d97d4e6f5d7aa180bcbb0e0d56af jdk7-b33
434055a0716ee44bca712ebca02fc04b20e6e288 jdk7-b34
cf4894b78ceb966326e93bf221db0c2d14d59218 jdk7-b35

View File

@ -704,7 +704,20 @@ endif
# Install of imported file (JDK_IMPORT_PATH, or some other external location)
define install-import-file
@$(ECHO) "ASSEMBLY_IMPORT: $@"
$(install-file)
$(prep-target)
$(CP) $< $@
@if [ "$(PLATFORM)" = "linux" -a "$(@F)" = "libjvm.so" ] ; then \
if [ -x /usr/sbin/selinuxenabled ] ; then \
/usr/sbin/selinuxenabled; \
if [ $$? = 0 ] ; then \
$(ECHO) "/usr/bin/chcon -t textrel_shlib_t $@"; \
/usr/bin/chcon -t textrel_shlib_t $@; \
if [ $$? != 0 ]; then \
echo "ERROR: Cannot chcon $@"; \
fi; \
fi; \
fi; \
fi
endef
.PHONY: all build clean clobber

View File

@ -1,5 +1,5 @@
#
# Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
# Copyright 2001-2008 Sun Microsystems, Inc. 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
@ -70,7 +70,6 @@ sanity-base: pre-sanity \
sane-compiler \
sane-cacerts \
sane-ant_version \
sane-findbugs_version \
sane-zip_version \
sane-msvcrt_path

View File

@ -352,30 +352,6 @@ else
HOTSPOT_DOCS_IMPORT_PATH :=$(call DirExists,$(HOTSPOT_IMPORT_PATH)/docs,$(PROMOTED_BUILD_BASEDIR)/docs,/NO_DOCS_DIR)
endif
# PREVIOUS_JDK_FILE: filename of install bundle for previous JDK
ifdef ALT_PREVIOUS_JDK_FILE
PREVIOUS_JDK_FILE =$(ALT_PREVIOUS_JDK_FILE)
else
PREVIOUS_JDK_FILE = jdk-$(PREVIOUS_JDK_UNDERSCORE_VERSION)-$(PLATFORM)-$(ARCH)$(BUNDLE_FILE_SUFFIX)
endif
export PREVIOUS_JDK_FILE
PREVIOUS_JDK_FILE:=$(call AltCheckSpaces,PREVIOUS_JDK_FILE)
PREVIOUS_JDK_FILE:=$(call AltCheckValue,PREVIOUS_JDK_FILE)
# PREVIOUS_JRE_FILE: filename of install bundle for previous JRE
ifdef ALT_PREVIOUS_JRE_FILE
PREVIOUS_JRE_FILE =$(ALT_PREVIOUS_JRE_FILE)
else
PREVIOUS_JRE_FILE = jre-$(PREVIOUS_JDK_UNDERSCORE_VERSION)-$(PLATFORM)-$(ARCH)$(BUNDLE_FILE_SUFFIX)
endif
export PREVIOUS_JRE_FILE
PREVIOUS_JRE_FILE:=$(call AltCheckSpaces,PREVIOUS_JRE_FILE)
PREVIOUS_JRE_FILE:=$(call AltCheckValue,PREVIOUS_JRE_FILE)
# Set here as shared variables
PREVIOUS_JRE_BUNDLE = $(PREVIOUS_RELEASE_PATH)/$(PREVIOUS_JRE_FILE)
PREVIOUS_JDK_BUNDLE = $(PREVIOUS_RELEASE_PATH)/$(PREVIOUS_JDK_FILE)
# These are the same on all platforms but require the above platform include 1st
# BOOTDIR: Bootstrap JDK, previous released JDK.
@ -389,19 +365,70 @@ export BOOTDIR
BOOTDIR:=$(call AltCheckSpaces,BOOTDIR)
BOOTDIR:=$(call AltCheckValue,BOOTDIR)
# PREVIOUS_RELEASE_PATH: path to where previous release bundles are
ifdef ALT_PREVIOUS_RELEASE_PATH
PREVIOUS_RELEASE_PATH :=$(call OptFullPath,$(ALT_PREVIOUS_RELEASE_PATH))
else
PREVIOUS_RELEASE_PATH =$(SLASH_JAVA)/re/jdk/$(PREVIOUS_JDK_VERSION)/archive/fcs/bundles/$(PLATFORM)-$(ARCH)
endif
export PREVIOUS_RELEASE_PATH
PREVIOUS_RELEASE_PATH:=$(call AltCheckSpaces,PREVIOUS_RELEASE_PATH)
PREVIOUS_RELEASE_PATH:=$(call AltCheckValue,PREVIOUS_RELEASE_PATH)
# PREVIOUS_FCS_RE_AREA: re path to where previous release binaries/bundles are
PREVIOUS_FCS_RE_AREA = $(SLASH_JAVA)/re/jdk/$(PREVIOUS_JDK_VERSION)/archive/fcs
# PREVIOUS_RELEASE_IMAGE: Previous install image to compare against
ifdef ALT_PREVIOUS_RELEASE_IMAGE
# Explicit image provided, no bundle access needed
PREVIOUS_RELEASE_IMAGE :=$(call FullPath,$(ALT_PREVIOUS_RELEASE_IMAGE))
else
# PREVIOUS_RELEASE_PATH: path to where previous release bundles are
ifdef ALT_PREVIOUS_RELEASE_PATH
PREVIOUS_RELEASE_PATH :=$(call OptFullPath,$(ALT_PREVIOUS_RELEASE_PATH))
else
PREVIOUS_RELEASE_PATH := \
$(call DirExists,$(PREVIOUS_FCS_RE_AREA)/bundles/$(PLATFORM)-$(ARCH),,)
endif
# Depending on if we have access to these bundles
ifeq ($(PREVIOUS_RELEASE_PATH),)
# Use images in re area or BOOTDIR (which is normally the previous release)
PREVIOUS_RELEASE_IMAGE := \
$(call DirExists,$(PREVIOUS_FCS_RE_AREA)/binaries/$(PLATFORM)-$(ARCH),$(BOOTDIR),)
else
# Get names of and paths to bundles
PREVIOUS_RELEASE_PATH:=$(call AltCheckSpaces,PREVIOUS_RELEASE_PATH)
PREVIOUS_RELEASE_PATH:=$(call AltCheckValue,PREVIOUS_RELEASE_PATH)
export PREVIOUS_RELEASE_PATH
# PREVIOUS_JDK_FILE: filename of install bundle for previous JDK
ifdef ALT_PREVIOUS_JDK_FILE
PREVIOUS_JDK_FILE =$(ALT_PREVIOUS_JDK_FILE)
else
PREVIOUS_JDK_FILE = \
jdk-$(PREVIOUS_JDK_UNDERSCORE_VERSION)-$(PLATFORM)-$(ARCH)$(BUNDLE_FILE_SUFFIX)
endif
export PREVIOUS_JDK_FILE
PREVIOUS_JDK_FILE:=$(call AltCheckSpaces,PREVIOUS_JDK_FILE)
PREVIOUS_JDK_FILE:=$(call AltCheckValue,PREVIOUS_JDK_FILE)
# PREVIOUS_JRE_FILE: filename of install bundle for previous JRE
ifdef ALT_PREVIOUS_JRE_FILE
PREVIOUS_JRE_FILE =$(ALT_PREVIOUS_JRE_FILE)
else
PREVIOUS_JRE_FILE = \
jre-$(PREVIOUS_JDK_UNDERSCORE_VERSION)-$(PLATFORM)-$(ARCH)$(BUNDLE_FILE_SUFFIX)
endif
export PREVIOUS_JRE_FILE
PREVIOUS_JRE_FILE:=$(call AltCheckSpaces,PREVIOUS_JRE_FILE)
PREVIOUS_JRE_FILE:=$(call AltCheckValue,PREVIOUS_JRE_FILE)
# Paths to these bundles
PREVIOUS_JRE_BUNDLE = $(PREVIOUS_RELEASE_PATH)/$(PREVIOUS_JRE_FILE)
PREVIOUS_JDK_BUNDLE = $(PREVIOUS_RELEASE_PATH)/$(PREVIOUS_JDK_FILE)
endif
endif
# Indicate we are using an image comparison
ifneq ($(PREVIOUS_RELEASE_IMAGE),)
PREVIOUS_RELEASE_PATH = USING-PREVIOUS_RELEASE_IMAGE
PREVIOUS_JRE_BUNDLE = USING-PREVIOUS_RELEASE_IMAGE
PREVIOUS_JDK_BUNDLE = USING-PREVIOUS_RELEASE_IMAGE
endif
# CACERTS_FILE: if OPENJDK is false and the internal version of the file
@ -513,23 +540,17 @@ JDK_CUPS_HEADERS_PATH=$(JDK_DEVTOOLS_DIR)/share/cups/include
endif
endif
# Utilities ant and findbugs
ifeq ($(ANT_HOME),)
ANT_HOME := $(call DirExists,/usr/share/ant,$(JDK_DEVTOOLS_DIR)/share/ant/latest,)
# Utilities ant
ifeq ($(PLATFORM), windows)
ifeq ($(ANT_HOME),)
ANT_HOME := $(call DirExists,$(JDK_DEVTOOLS_DIR)/share/ant/latest,,)
endif
endif
ifeq ($(ANT_HOME),)
ANT = ant
else
ANT = $(ANT_HOME)/bin/ant
endif
ifeq ($(FINDBUGS_HOME),)
FINDBUGS_HOME := $(call DirExists,/usr/share/findbugs,$(JDK_DEVTOOLS_DIR)/share/findbugs/latest,)
endif
ifeq ($(FINDBUGS_HOME),)
FINDBUGS = findbugs
else
FINDBUGS = $(FINDBUGS_HOME)/bin/findbugs
endif
ifdef ALT_COPYRIGHT_YEAR
COPYRIGHT_YEAR = $(ALT_COPYRIGHT_YEAR)

View File

@ -1,5 +1,5 @@
#
# Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
# Copyright 2005-2008 Sun Microsystems, Inc. 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
@ -79,7 +79,6 @@ ALL_SETTINGS+=$(call addAltSetting,SLASH_JAVA)
ALL_SETTINGS+=$(call addRequiredSetting,VARIANT)
ALL_SETTINGS+=$(call addAltSetting,JDK_DEVTOOLS_DIR)
ALL_SETTINGS+=$(call addOptionalSetting,ANT_HOME)
ALL_SETTINGS+=$(call addOptionalSetting,FINDBUGS_HOME)
ALL_SETTINGS+=$(call addAltSetting,UNIXCOMMAND_PATH)
ALL_SETTINGS+=$(call addAltSetting,COMPILER_PATH)
ALL_SETTINGS+=$(call addAltSetting,DEVTOOLS_PATH)
@ -119,7 +118,6 @@ ifeq ($(PLATFORM),windows)
ALL_SETTINGS+=$(call addRequiredVersionSetting,LINK_VER)
endif
ALL_SETTINGS+=$(call addRequiredVersionSetting,ANT_VER)
ALL_SETTINGS+=$(call addRequiredVersionSetting,FINDBUGS_VER)
ALL_SETTINGS+=$(call addRequiredSetting,TEMPDIR)

View File

@ -107,21 +107,9 @@ UNZIP_VER :=$(call GetVersion,"$(_UNZIP_VER)")
BOOT_VER :=$(call GetVersion,"$(_BOOT_VER)")
REQUIRED_ANT_VER := 1.6.3
ifeq ($(ANT_HOME),)
_ANT_VER:=$(shell JAVACMD="$(BOOTDIR)/bin/java" $(ANT) -version 2>&1 )
else
_ANT_VER:=$(shell JAVACMD="$(BOOTDIR)/bin/java" ANT_HOME="$(ANT_HOME)" $(ANT) -version 2>&1 )
endif
_ANT_VER:=$(shell $(ANT) -version 2>&1 )
ANT_VER:=$(call GetVersion,"$(_ANT_VER)")
REQUIRED_FINDBUGS_VER := 1.2
ifeq ($(FINDBUGS_HOME),)
_FINDBUGS_VER:=$(shell $(FINDBUGS) -javahome "$(BOOTDIR)" -textui -version 2>&1 )
else
_FINDBUGS_VER:=$(shell FINDBUGS_HOME="$(FINDBUGS_HOME)" $(FINDBUGS) -javahome "$(BOOTDIR)" -textui -version 2>&1 )
endif
FINDBUGS_VER:=$(call GetVersion,"$(_FINDBUGS_VER)")
ifdef ALT_BINDIR
ALT_BINDIR_VERSION := $(shell $(ALT_BINDIR)/java$(EXE_SUFFIX) -version 2>&1 | $(NAWK) -F'"' '{ print $$2 }')
ALT_BINDIR_OK := $(shell $(ECHO) $(ALT_BINDIR_VERSION) | $(EGREP) -c '^$(JDK_MAJOR_VERSION).$(JDK_MINOR_VERSION)')
@ -182,7 +170,6 @@ include $(JDK_MAKE_SHARED_DIR)/Sanity-Settings.gmk
sane-alsa-versioncheck \
sane-alsa-headers \
sane-ant_version \
sane-findbugs_version \
sane-zip_version \
sane-unzip_version \
sane-msvcrt_path \
@ -1216,19 +1203,6 @@ sane-ant_version:
"" >> $(WARNING_FILE) ; \
fi
######################################################
# Check the findbugs version
######################################################
FINDBUGS_CHECK :=$(call CheckVersions,$(FINDBUGS_VER),$(REQUIRED_FINDBUGS_VER))
sane-findbugs_version:
@if [ "$(FINDBUGS_CHECK)" != "same" \
-a "$(FINDBUGS_CHECK)" != "newer" ]; then \
$(ECHO) "WARNING: The version of findbugs being used is older than \n" \
" the required version of '$(REQUIRED_FINDBUGS_VER)'. \n" \
" The version of findbugs found was '$(FINDBUGS_VER)'. \n" \
"" >> $(WARNING_FILE) ; \
fi
######################################################
# Check the zip file version
######################################################

View File

@ -158,6 +158,7 @@ CORE_PKGS = \
javax.management.event \
javax.management.loading \
javax.management.monitor \
javax.management.namespace \
javax.management.relation \
javax.management.openmbean \
javax.management.timer \

View File

@ -449,6 +449,7 @@ JAVA_JAVA_java = \
sun/misc/JavaLangAccess.java \
sun/misc/JavaIOAccess.java \
sun/misc/JavaIODeleteOnExitAccess.java \
sun/misc/JavaIOFileDescriptorAccess.java
sun/misc/JavaIOFileDescriptorAccess.java \
sun/misc/JavaNioAccess.java
FILES_java = $(JAVA_JAVA_java)

View File

@ -222,8 +222,6 @@ SUNWprivate_1.1 {
Java_java_lang_UNIXProcess_waitForProcessExit;
Java_java_lang_UNIXProcess_forkAndExec;
Java_java_lang_UNIXProcess_destroyProcess;
Java_java_nio_Bits_copyFromByteArray;
Java_java_nio_Bits_copyToByteArray;
Java_java_nio_Bits_copyFromShortArray;
Java_java_nio_Bits_copyToShortArray;
Java_java_nio_Bits_copyFromIntArray;

View File

@ -113,7 +113,11 @@ ifeq ($(PLATFORM), windows)
JAVALIB =
OTHER_LCF = -export:JLI_Launch \
-export:JLI_ManifestIterate \
-export:JLI_SetTraceLauncher
-export:JLI_SetTraceLauncher \
-export:JLI_ReportErrorMessage \
-export:JLI_ReportErrorMessageSys \
-export:JLI_ReportMessage \
-export:JLI_ReportExceptionDescription
endif

View File

@ -1,5 +1,5 @@
#
# Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
# Copyright 2005-2008 Sun Microsystems, Inc. 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
@ -30,6 +30,10 @@ SUNWprivate_1.1 {
JLI_Launch;
JLI_ManifestIterate;
JLI_SetTraceLauncher;
JLI_ReportErrorMessage;
JLI_ReportErrorMessageSys;
JLI_ReportMessage;
JLI_ReportExceptionDescription;
local:
*;
};

View File

@ -26,6 +26,7 @@
FILES_src = \
java/nio/Bits.java \
java/nio/Buffer.java \
java/nio/BufferPoolMXBean.java \
java/nio/ByteOrder.java \
java/nio/MappedByteBuffer.java \
java/nio/StringCharBuffer.java \
@ -38,6 +39,9 @@ FILES_src = \
java/nio/channels/FileLock.java \
java/nio/channels/GatheringByteChannel.java \
java/nio/channels/InterruptibleChannel.java \
java/nio/channels/MembershipKey.java \
java/nio/channels/MulticastChannel.java \
java/nio/channels/NetworkChannel.java \
java/nio/channels/ReadableByteChannel.java \
java/nio/channels/ScatteringByteChannel.java \
java/nio/channels/SelectableChannel.java \
@ -72,6 +76,7 @@ FILES_src = \
sun/nio/ch/DatagramSocketAdaptor.java \
sun/nio/ch/DefaultSelectorProvider.java \
sun/nio/ch/DirectBuffer.java \
sun/nio/ch/ExtendedSocketOption.java \
sun/nio/ch/FileChannelImpl.java \
sun/nio/ch/FileDispatcher.java \
sun/nio/ch/FileKey.java \
@ -79,12 +84,14 @@ FILES_src = \
sun/nio/ch/IOUtil.java \
sun/nio/ch/IOStatus.java \
sun/nio/ch/IOVecWrapper.java \
sun/nio/ch/MembershipKeyImpl.java \
sun/nio/ch/MembershipRegistry.java \
sun/nio/ch/NativeDispatcher.java \
sun/nio/ch/NativeObject.java \
sun/nio/ch/NativeThread.java \
sun/nio/ch/NativeThreadSet.java \
sun/nio/ch/Net.java \
sun/nio/ch/OptionAdaptor.java \
sun/nio/ch/OptionKey.java \
sun/nio/ch/PipeImpl.java \
sun/nio/ch/PollArrayWrapper.java \
sun/nio/ch/Reflect.java \
@ -98,8 +105,7 @@ FILES_src = \
sun/nio/ch/SocketAdaptor.java \
sun/nio/ch/SocketChannelImpl.java \
sun/nio/ch/SocketDispatcher.java \
sun/nio/ch/SocketOpts.java \
sun/nio/ch/SocketOptsImpl.java \
sun/nio/ch/SocketOptionRegistry.java \
sun/nio/ch/SourceChannelImpl.java \
sun/nio/ch/Util.java \
\
@ -239,6 +245,7 @@ FILES_gen_ex = \
java/nio/InvalidMarkException.java \
java/nio/ReadOnlyBufferException.java \
\
java/nio/channels/AlreadyBoundException.java \
java/nio/channels/AlreadyConnectedException.java \
java/nio/channels/AsynchronousCloseException.java \
java/nio/channels/ClosedByInterruptException.java \
@ -257,14 +264,15 @@ FILES_gen_ex = \
java/nio/channels/UnresolvedAddressException.java \
java/nio/channels/UnsupportedAddressTypeException.java \
\
sun/nio/ch/AlreadyBoundException.java \
\
java/nio/charset/CharacterCodingException.java \
java/nio/charset/IllegalCharsetNameException.java \
java/nio/charset/UnsupportedCharsetException.java
FILES_gen_csp = sun/nio/cs/StandardCharsets.java
FILES_gen = $(FILES_gen_coder) $(FILES_gen_buffer) $(FILES_gen_ex) $(FILES_gen_csp)
FILES_gen_sor = sun/nio/ch/SocketOptionRegistry.java
FILES_gen = $(FILES_gen_coder) $(FILES_gen_buffer) $(FILES_gen_ex) \
$(FILES_gen_csp) $(FILES_gen_sor)
FILES_java = $(FILES_src) $(FILES_gen)

View File

@ -56,18 +56,18 @@ FILES_java += \
sun/nio/ch/DevPollSelectorProvider.java \
sun/nio/ch/InheritedChannel.java \
sun/nio/ch/PollSelectorProvider.java \
sun/nio/ch/PollSelectorImpl.java
sun/nio/ch/PollSelectorImpl.java
FILES_c += \
DevPollArrayWrapper.c \
InheritedChannel.c \
PollArrayWrapper.c \
NativeThread.c
NativeThread.c \
PollArrayWrapper.c
FILES_export += \
sun/nio/ch/DevPollArrayWrapper.java \
sun/nio/ch/InheritedChannel.java \
sun/nio/ch/NativeThread.java
sun/nio/ch/NativeThread.java
endif # PLATFORM = solaris
ifeq ($(PLATFORM), windows)
@ -94,14 +94,14 @@ FILES_java += \
FILES_c += \
EPollArrayWrapper.c \
PollArrayWrapper.c \
InheritedChannel.c \
NativeThread.c
NativeThread.c \
PollArrayWrapper.c
FILES_export += \
sun/nio/ch/EPollArrayWrapper.java \
sun/nio/ch/InheritedChannel.java \
sun/nio/ch/NativeThread.java
sun/nio/ch/NativeThread.java
endif # PLATFORM = linux
# Find platform-specific C source files
@ -618,12 +618,6 @@ $(BUF_GEN)/%Exception.java: genExceptions.sh $(BUF_SRC)/exceptions
@$(RM) $@.temp
$(GEN_EX_CMD) $(BUF_SRC)/exceptions $(BUF_GEN)
$(SCH_GEN)/%Exception.java: genExceptions.sh $(SCH_SRC)/exceptions
$(prep-target)
@$(RM) $@.temp
$(GEN_EX_CMD) $(SCH_SRC)/exceptions $(SCH_GEN)
#
# Generated charset-provider classes
#
@ -638,4 +632,29 @@ $(SCS_GEN)/StandardCharsets.java: genCharsetProvider.sh \
HASHER="$(BOOT_JAVA_CMD) -jar $(HASHER_JARFILE)" \
$(SH) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN)
#
# Generated channel implementation classes.
# C source is compiled in TEMPDIR to avoid turds left by Windows compilers.
#
GENSOR_SRC = $(SHARE_SRC)/native/sun/nio/ch/genSocketOptionRegistry.c
GENSOR_EXE = $(TEMPDIR)/genSocketOptionRegistry$(EXE_SUFFIX)
SOR_COPYRIGHT_YEARS = $(shell $(CAT) $(GENSOR_SRC) | \
$(NAWK) '/^.*Copyright.*Sun/ { print $$3 }')
$(TEMPDIR)/$(GENSOR_SRC) : $(GENSOR_SRC)
$(install-file)
$(GENSOR_EXE) : $(TEMPDIR)/$(GENSOR_SRC)
$(prep-target)
($(CD) $(TEMPDIR); $(CC) $(CPPFLAGS) $(LDDFLAGS) \
-o genSocketOptionRegistry$(EXE_SUFFIX) $(GENSOR_SRC))
$(SCH_GEN)/SocketOptionRegistry.java: $(GENSOR_EXE)
$(prep-target)
NAWK="$(NAWK)" SH="$(SH)" $(SH) -e addNotices.sh $(SOR_COPYRIGHT_YEARS) > $@
$(GENSOR_EXE) >> $@
.PHONY: sources

View File

@ -1,3 +1,27 @@
#
# Copyright 2001-2008 Sun Microsystems, Inc. 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. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
SUNWprivate_1.1 {
global:
@ -18,6 +42,8 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_EPollArrayWrapper_fdLimit;
Java_sun_nio_ch_EPollArrayWrapper_init;
Java_sun_nio_ch_EPollArrayWrapper_interrupt;
Java_sun_nio_ch_EPollArrayWrapper_offsetofData;
Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent;
Java_sun_nio_ch_FileChannelImpl_close0;
Java_sun_nio_ch_FileChannelImpl_force0;
Java_sun_nio_ch_FileChannelImpl_initIDs;
@ -59,20 +85,29 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_NativeThread_init;
Java_sun_nio_ch_NativeThread_signal;
Java_sun_nio_ch_Net_socket0;
Java_sun_nio_ch_Net_bind;
Java_sun_nio_ch_Net_connect;
Java_sun_nio_ch_Net_bind0;
Java_sun_nio_ch_Net_connect0;
Java_sun_nio_ch_Net_listen;
Java_sun_nio_ch_Net_localPort;
Java_sun_nio_ch_Net_localInetAddress;
Java_sun_nio_ch_Net_getIntOption0;
Java_sun_nio_ch_Net_setIntOption0;
Java_sun_nio_ch_Net_initIDs;
Java_sun_nio_ch_Net_isIPv6Available0;
Java_sun_nio_ch_Net_joinOrDrop4;
Java_sun_nio_ch_Net_blockOrUnblock4;
Java_sun_nio_ch_Net_joinOrDrop6;
Java_sun_nio_ch_Net_blockOrUnblock6;
Java_sun_nio_ch_Net_setInterface4;
Java_sun_nio_ch_Net_getInterface4;
Java_sun_nio_ch_Net_setInterface6;
Java_sun_nio_ch_Net_getInterface6;
Java_sun_nio_ch_Net_shutdown;
Java_sun_nio_ch_PollArrayWrapper_interrupt;
Java_sun_nio_ch_PollArrayWrapper_poll0;
Java_sun_nio_ch_ServerSocketChannelImpl_accept0;
Java_sun_nio_ch_ServerSocketChannelImpl_initIDs;
Java_sun_nio_ch_ServerSocketChannelImpl_listen;
Java_sun_nio_ch_SocketChannelImpl_checkConnect;
Java_sun_nio_ch_SocketChannelImpl_shutdown;
local:
*;

View File

@ -1,3 +1,27 @@
#
# Copyright 2001-2008 Sun Microsystems, Inc. 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. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
SUNWprivate_1.1 {
global:
@ -59,20 +83,29 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_NativeThread_init;
Java_sun_nio_ch_NativeThread_signal;
Java_sun_nio_ch_Net_socket0;
Java_sun_nio_ch_Net_bind;
Java_sun_nio_ch_Net_connect;
Java_sun_nio_ch_Net_bind0;
Java_sun_nio_ch_Net_connect0;
Java_sun_nio_ch_Net_listen;
Java_sun_nio_ch_Net_localPort;
Java_sun_nio_ch_Net_localInetAddress;
Java_sun_nio_ch_Net_getIntOption0;
Java_sun_nio_ch_Net_setIntOption0;
Java_sun_nio_ch_Net_initIDs;
Java_sun_nio_ch_Net_isIPv6Available0;
Java_sun_nio_ch_Net_joinOrDrop4;
Java_sun_nio_ch_Net_blockOrUnblock4;
Java_sun_nio_ch_Net_joinOrDrop6;
Java_sun_nio_ch_Net_blockOrUnblock6;
Java_sun_nio_ch_Net_setInterface4;
Java_sun_nio_ch_Net_getInterface4;
Java_sun_nio_ch_Net_setInterface6;
Java_sun_nio_ch_Net_getInterface6;
Java_sun_nio_ch_Net_shutdown;
Java_sun_nio_ch_PollArrayWrapper_interrupt;
Java_sun_nio_ch_PollArrayWrapper_poll0;
Java_sun_nio_ch_ServerSocketChannelImpl_accept0;
Java_sun_nio_ch_ServerSocketChannelImpl_initIDs;
Java_sun_nio_ch_ServerSocketChannelImpl_listen;
Java_sun_nio_ch_SocketChannelImpl_checkConnect;
Java_sun_nio_ch_SocketChannelImpl_shutdown;
local:
*;

View File

@ -100,20 +100,16 @@ share="${jdk_devtools}/share"
# Needed for langtools, maybe other parts of the build
ANT_HOME="${share}/ant/latest"
export ANT_HOME
FINDBUGS_HOME="${share}/findbugs/latest"
export FINDBUGS_HOME
# The 3 bin directories in common to all platforms
sharebin="${share}/bin"
antbin="${ANT_HOME}/bin"
findbugsbin="${FINDBUGS_HOME}/bin"
# Check input
dirMustExist "${bootdir}" ALT_BOOTDIR
dirMustExist "${slashjava}" ALT_SLASH_JAVA
dirMustExist "${jdk_import}" ALT_JDK_IMPORT_PATH
dirMustExist "${ANT_HOME}" ANT_HOME
dirMustExist "${FINDBUGS_HOME}" FINDBUGS_HOME
# Use the JDK import for now (FIXME: use the binary plugs?)
if [ "${OPENJDK}" = true ] ; then
@ -143,7 +139,7 @@ if [ "${osname}" = SunOS ] ; then
ALT_COMPILER_PATH="${compiler_path}"
export ALT_COMPILER_PATH
dirMustExist "${compiler_path}" ALT_COMPILER_PATH
path4sdk=${compiler_path}:${sharebin}:${antbin}:${findbugsbin}
path4sdk=${compiler_path}:${sharebin}:${antbin}
# Add basic solaris system paths
path4sdk=${path4sdk}:/usr/ccs/bin:/usr/ccs/lib:/usr/bin:/bin:/usr/sfw/bin
@ -180,7 +176,7 @@ elif [ "${osname}" = Linux ] ; then
ALT_COMPILER_PATH="${compiler_path}"
export ALT_COMPILER_PATH
dirMustExist "${compiler_path}" ALT_COMPILER_PATH
path4sdk=${compiler_path}:${sharebin}:${antbin}:${findbugsbin}
path4sdk=${compiler_path}:${sharebin}:${antbin}
# Add basic paths
path4sdk=${path4sdk}:/usr/bin:/bin:/usr/sbin:/sbin
@ -228,7 +224,7 @@ else
dosname="${mkshome}/mksnt/dosname -s"
# Most unix utilities are in the mksnt directory of ROOTDIR
unixcommand_path="${mkshome}/mksnt"
path4sdk="${sharebin};${antbin};${findbugsbin};${unixcommand_path}"
path4sdk="${sharebin};${antbin};${unixcommand_path}"
dirMustExist "${unixcommand_path}" ALT_UNIXCOMMAND_PATH
devtools_path="${jdk_devtools}/win32/bin"
path4sdk="${devtools_path};${path4sdk}"
@ -246,7 +242,7 @@ else
dosname="/usr/bin/cygpath -a -m -s"
# Most unix utilities are in the /usr/bin
unixcommand_path="/usr/bin"
path4sdk="${sharebin};${antbin};${findbugsbin};${unixcommand_path}"
path4sdk="${sharebin};${antbin};${unixcommand_path}"
dirMustExist "${unixcommand_path}" ALT_UNIXCOMMAND_PATH
# Find GNU make
make="${unixcommand_path}/make.exe"

View File

@ -31,7 +31,7 @@ BUILDDIR = ../..
PRODUCT = java
include $(BUILDDIR)/common/Defs.gmk
SUBDIRS = server
SUBDIRS = multicast server
all build clean clobber::
$(SUBDIRS-loop)

View File

@ -1,5 +1,5 @@
#
# Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
# Copyright 2007 Sun Microsystems, Inc. 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
@ -23,17 +23,30 @@
# have any questions.
#
# Generated exception classes for sun.nio.ch
#
# Makefile for the nio/multicast sample code
#
SINCE=1.4
PACKAGE=sun.nio.ch
# This year should only change if the generated source is modified.
COPYRIGHT_YEARS=2000-2007
BUILDDIR = ../../..
PRODUCT = java
SUPER=IllegalStateException
include $(BUILDDIR)/common/Defs.gmk
gen AlreadyBoundException "
* Unchecked exception thrown when an attempt is made to bind a {@link
* SocketChannel} that is already bound." \
9002280723481772026L
SAMPLE_SRC_DIR = $(SHARE_SRC)/sample/nio/multicast
SAMPLE_DST_DIR = $(SAMPLEDIR)/nio/multicast
SAMPLE_FILES = \
$(SAMPLE_DST_DIR)/Reader.java \
$(SAMPLE_DST_DIR)/Sender.java \
$(SAMPLE_DST_DIR)/MulticastAddress.java
all build: $(SAMPLE_FILES)
$(SAMPLE_DST_DIR)/%: $(SAMPLE_SRC_DIR)/%
$(install-file)
clean clobber:
$(RM) -r $(SAMPLE_DST_DIR)
.PHONY: all build clean clobber

View File

@ -142,59 +142,59 @@ FILES_2D_c = \
# These files rely on motif to be built, and should not be included
# in a headless build.
FILES_MOTIF_c = \
awt_AWTEvent.c \
awt_Button.c \
awt_Canvas.c \
awt_Checkbox.c \
awt_Component.c \
awt_Cursor.c \
awt_DataTransferer.c \
awt_DrawingSurface.c \
awt_Event.c \
awt_FileDialog.c \
awt_GlobalCursorManager.c \
awt_GraphicsEnv.c \
awt_InputMethod.c \
awt_Insets.c \
awt_KeyboardFocusManager.c \
awt_Label.c \
awt_List.c \
awt_Menu.c \
awt_MenuBar.c \
awt_MenuComponent.c \
awt_MenuItem.c \
awt_motif.c \
awt_Plugin.c \
awt_PopupMenu.c \
awt_Robot.c \
awt_Scrollbar.c \
awt_ScrollPane.c \
awt_Selection.c \
awt_UNIXToolkit.c \
awt_TextArea.c \
awt_TextField.c \
awt_TopLevel.c \
awt_mgrsel.c \
awt_util.c \
awt_wm.c \
awt_XmDnD.c \
awt_dnd.c \
awt_dnd_ds.c \
awt_dnd_dt.c \
canvas.c \
cursor.c \
multi_font.c \
robot_common.c \
list.c \
multiVis.c \
XDrawingArea.c \
MouseInfo.c \
awt_xembed.c \
awt_xembed_server.c \
gtk2_interface.c \
swing_GTKEngine.c \
swing_GTKStyle.c
#FILES_MOTIF_c = \
#keep awt_AWTEvent.c \
# awt_Button.c \
# awt_Canvas.c \
# awt_Checkbox.c \
#keep .h awt_Component.c \
#keep .h awt_Cursor.c \
# awt_DataTransferer.c \
# awt_DrawingSurface.c \
# awt_Event.c \
# awt_FileDialog.c \
# awt_GlobalCursorManager.c \
# awt_GraphicsEnv.c \
# awt_InputMethod.c \
#keep awt_Insets.c \
# awt_KeyboardFocusManager.c \
# awt_Label.c \
# awt_List.c \
# awt_Menu.c \
# awt_MenuBar.c \
# awt_MenuComponent.c \
# awt_MenuItem.c \
# awt_motif.c \
# awt_Plugin.c \
# awt_PopupMenu.c \
# awt_Robot.c \
# awt_Scrollbar.c \
# awt_ScrollPane.c \
# awt_Selection.c \
# awt_UNIXToolkit.c \
# awt_TextArea.c \
# awt_TextField.c \
# awt_TopLevel.c \
# awt_mgrsel.c \
# awt_util.c \
# awt_wm.c \
# awt_XmDnD.c \
# awt_dnd.c \
# awt_dnd_ds.c \
# awt_dnd_dt.c \
# canvas.c \
# cursor.c \
# multi_font.c \
# robot_common.c \
# list.c \
# multiVis.c \
# XDrawingArea.c \
# MouseInfo.c \
# awt_xembed.c \
# awt_xembed_server.c \
# gtk2_interface.c \
# swing_GTKEngine.c \
# swing_GTKStyle.c
# These files are required to be built, with or without motif. Some of

View File

@ -60,48 +60,15 @@ FILES_export = \
sun/awt/image/DataBufferNative.java \
\
sun/awt/motif/X11FontMetrics.java \
sun/awt/motif/X11Clipboard.java \
sun/awt/motif/X11Selection.java \
sun/awt/motif/X11SelectionHolder.java \
sun/awt/X11InputMethod.java \
sun/awt/motif/MInputMethod.java \
sun/awt/motif/MInputMethodControl.java \
sun/awt/motif/MCustomCursor.java \
sun/awt/motif/MFontConfiguration.java \
sun/awt/motif/MFontPeer.java \
sun/awt/motif/MToolkit.java \
sun/awt/motif/MComponentPeer.java \
sun/awt/motif/MButtonPeer.java \
sun/awt/motif/MCanvasPeer.java \
sun/awt/motif/MCheckboxPeer.java \
sun/awt/motif/MFileDialogPeer.java \
sun/awt/motif/MGlobalCursorManager.java \
sun/awt/motif/MTextFieldPeer.java \
sun/awt/motif/MLabelPeer.java \
sun/awt/motif/MListPeer.java \
sun/awt/motif/MWindowPeer.java \
sun/awt/motif/MMenuBarPeer.java \
sun/awt/motif/MMenuPeer.java \
sun/awt/motif/MPopupMenuPeer.java \
sun/awt/motif/MDialogPeer.java \
sun/awt/motif/MMenuItemPeer.java \
sun/awt/motif/MCheckboxMenuItemPeer.java \
sun/awt/motif/MChoicePeer.java \
sun/awt/motif/MTextAreaPeer.java \
sun/awt/motif/MScrollbarPeer.java \
sun/awt/motif/MScrollPanePeer.java \
sun/awt/motif/MFramePeer.java \
sun/awt/DebugSettings.java \
sun/awt/EmbeddedFrame.java \
sun/awt/motif/MEmbeddedFramePeer.java \
sun/awt/PlatformFont.java \
sun/awt/FontDescriptor.java \
sun/awt/NativeLibLoader.java \
sun/awt/motif/MDropTargetContextPeer.java \
sun/awt/motif/MDragSourceContextPeer.java \
sun/awt/motif/MRobotPeer.java \
sun/awt/motif/X11DragSourceContextPeer.java \
sun/awt/motif/X11DropTargetContextPeer.java \
sun/awt/X11GraphicsEnvironment.java \
sun/awt/X11GraphicsDevice.java \
sun/awt/X11GraphicsConfig.java \
@ -124,7 +91,6 @@ FILES_export = \
sun/java2d/cmm/ColorTransform.java \
sun/awt/datatransfer/DataTransferer.java \
sun/awt/dnd/SunDragSourceContextPeer.java \
sun/awt/motif/MDataTransferer.java \
sun/awt/motif/MToolkitThreadBlockedHandler.java \
sun/java2d/opengl/OGLBlitLoops.java \
sun/java2d/opengl/OGLContext.java \
@ -220,6 +186,5 @@ FILES_export2 = \
java/awt/event/NativeLibLoader.java \
java/awt/peer/ComponentPeer.java \
java/awt/dnd/DnDConstants.java \
sun/awt/CausedFocusEvent.java \
sun/awt/motif/MEmbedCanvasPeer.java
sun/awt/CausedFocusEvent.java

View File

@ -31,7 +31,7 @@ SUNWprivate_1.1 {
global:
JNI_OnLoad;
Java_sun_awt_motif_MComponentPeer_restoreFocus;
#Java_sun_awt_motif_MComponentPeer_restoreFocus;
Java_sun_awt_DefaultMouseInfoPeer_fillPointWithCoords;
Java_sun_awt_DefaultMouseInfoPeer_isWindowUnderMouse;
Java_java_awt_AWTEvent_nativeSetSource;
@ -56,163 +56,163 @@ SUNWprivate_1.1 {
Java_sun_awt_UNIXToolkit_load_1stock_1icon;
Java_sun_awt_UNIXToolkit_load_1gtk_1icon;
Java_sun_awt_UNIXToolkit_nativeSync;
Java_sun_awt_motif_MButtonPeer_create;
Java_sun_awt_motif_MButtonPeer_setLabel;
Java_sun_awt_motif_MPanelPeer_pEnsureIndex;
Java_sun_awt_motif_MPanelPeer_pRestack;
Java_sun_awt_motif_MCanvasPeer_create;
Java_sun_awt_motif_MCanvasPeer_initIDs;
Java_sun_awt_motif_MCanvasPeer_resetTargetGC;
Java_sun_awt_motif_MCheckboxMenuItemPeer_pSetState;
Java_sun_awt_motif_MCheckboxPeer_create;
Java_sun_awt_motif_MCheckboxPeer_setCheckboxGroup;
Java_sun_awt_motif_MCheckboxPeer_setLabel;
Java_sun_awt_motif_MCheckboxPeer_pSetState;
Java_sun_awt_motif_MCheckboxPeer_pGetState;
Java_sun_awt_motif_MChoicePeer_addItem;
Java_sun_awt_motif_MChoicePeer_appendItems;
Java_sun_awt_motif_MChoicePeer_create;
Java_sun_awt_motif_MChoicePeer_pReshape;
Java_sun_awt_motif_MChoicePeer_remove;
Java_sun_awt_motif_MChoicePeer_removeAll;
Java_sun_awt_motif_MChoicePeer_setBackground;
Java_sun_awt_motif_MChoicePeer_pSelect;
Java_sun_awt_motif_MChoicePeer_setFont;
Java_sun_awt_motif_MChoicePeer_setForeground;
Java_sun_awt_motif_MComponentPeer_addNativeDropTarget;
Java_sun_awt_motif_MComponentPeer_getNativeColor;
Java_sun_awt_motif_MComponentPeer_getWindow;
Java_sun_awt_motif_MComponentPeer_pDisable;
Java_sun_awt_motif_MComponentPeer_pDispose;
Java_sun_awt_motif_MComponentPeer_pEnable;
Java_sun_awt_motif_MComponentPeer_pGetLocationOnScreen;
Java_sun_awt_motif_MComponentPeer_pGetLocationOnScreen2;
Java_sun_awt_motif_MComponentPeer_pHide;
Java_sun_awt_motif_MComponentPeer_pInitialize;
Java_sun_awt_motif_MComponentPeer_pMakeCursorVisible;
Java_sun_awt_motif_MComponentPeer_pReshape;
Java_sun_awt_motif_MComponentPeer_pShow;
Java_sun_awt_motif_MComponentPeer_removeNativeDropTarget;
Java_sun_awt_motif_MComponentPeer_pSetBackground;
Java_sun_awt_motif_MComponentPeer_pSetFont;
Java_sun_awt_motif_MComponentPeer_processSynchronousLightweightTransfer;
Java_sun_awt_motif_MComponentPeer__1requestFocus;
Java_sun_awt_motif_MComponentPeer_getNativeFocusedWindow;
Java_sun_awt_motif_MCheckboxMenuItemPeer_getState;
Java_sun_awt_motif_MComponentPeer_pSetForeground;
Java_sun_awt_motif_MDragSourceContextPeer_startDrag;
Java_sun_awt_motif_MDragSourceContextPeer_setNativeCursor;
Java_sun_awt_motif_MDropTargetContextPeer_addTransfer;
Java_sun_awt_motif_MDropTargetContextPeer_dropDone;
Java_sun_awt_motif_MDropTargetContextPeer_startTransfer;
Java_sun_awt_motif_X11DragSourceContextPeer_startDrag;
Java_sun_awt_motif_X11DragSourceContextPeer_setNativeCursor;
Java_sun_awt_motif_X11DropTargetContextPeer_sendResponse;
Java_sun_awt_motif_X11DropTargetContextPeer_dropDone;
Java_sun_awt_motif_X11DropTargetContextPeer_getData;
Java_sun_awt_motif_MEmbeddedFramePeer_NEFcreate;
Java_sun_awt_motif_MEmbeddedFramePeer_pShowImpl;
Java_sun_awt_motif_MEmbeddedFramePeer_requestXEmbedFocus;
Java_sun_awt_motif_MEmbeddedFramePeer_isXEmbedApplicationActive;
Java_sun_awt_motif_MEmbeddedFramePeer_isXEmbedActive;
Java_sun_awt_motif_MEmbeddedFramePeer_synthesizeFocusInOut;
Java_sun_awt_motif_MEmbeddedFramePeer_pReshapePrivate;
Java_sun_awt_motif_MEmbeddedFramePeer_getBoundsPrivate;
Java_sun_awt_motif_MEmbeddedFrame_getWidget;
Java_sun_awt_motif_MEmbeddedFrame_mapWidget;
Java_sun_awt_motif_MEmbedCanvasPeer_forwardEventToEmbedded;
Java_sun_awt_motif_MFramePeer_pSetIconImage___3B_3I_3SII;
Java_sun_awt_motif_MFileDialogPeer_create;
Java_sun_awt_motif_MFileDialogPeer_pDispose;
Java_sun_awt_motif_MFileDialogPeer_pHide;
Java_sun_awt_motif_MFileDialogPeer_pReshape;
Java_sun_awt_motif_MFileDialogPeer_pShow;
Java_sun_awt_motif_MFileDialogPeer_setFileEntry;
Java_sun_awt_motif_MFileDialogPeer_setFont;
Java_sun_awt_motif_MFramePeer_pGetIconSize;
Java_sun_awt_motif_MGlobalCursorManager_cacheInit;
Java_sun_awt_motif_MGlobalCursorManager_findComponentAt;
Java_sun_awt_motif_MGlobalCursorManager_findHeavyweightUnderCursor;
Java_sun_awt_motif_MGlobalCursorManager_getCursorPos;
Java_sun_awt_motif_MGlobalCursorManager_getLocationOnScreen;
Java_sun_awt_motif_MLabelPeer_create;
Java_sun_awt_motif_MLabelPeer_setAlignment;
Java_sun_awt_motif_MLabelPeer_setText;
Java_sun_awt_motif_MListPeer_addItem;
Java_sun_awt_motif_MListPeer_create;
Java_sun_awt_motif_MListPeer_delItems;
Java_sun_awt_motif_MListPeer_deselect;
Java_sun_awt_motif_MListPeer_isSelected;
Java_sun_awt_motif_MListPeer_makeVisible;
Java_sun_awt_motif_MListPeer_nativeHandleMouseWheel;
Java_sun_awt_motif_MListPeer_select;
Java_sun_awt_motif_MListPeer_setMultipleSelections;
Java_sun_awt_motif_MMenuBarPeer_create;
Java_sun_awt_motif_MMenuItemPeer_createMenuItem;
Java_sun_awt_motif_MMenuItemPeer_pDisable;
Java_sun_awt_motif_MMenuItemPeer_pDispose;
Java_sun_awt_motif_MMenuItemPeer_pEnable;
Java_sun_awt_motif_MMenuItemPeer_pSetLabel;
Java_sun_awt_motif_MMenuPeer_createMenu;
Java_sun_awt_motif_MMenuPeer_createSubMenu;
Java_sun_awt_motif_MMenuPeer_pDispose;
Java_sun_awt_motif_MPopupMenuPeer_createMenu;
Java_sun_awt_motif_MPopupMenuPeer_pDispose;
Java_sun_awt_motif_MPopupMenuPeer_pShow;
Java_sun_awt_motif_MRobotPeer_getRGBPixelsImpl;
Java_sun_awt_motif_MRobotPeer_keyPressImpl;
Java_sun_awt_motif_MRobotPeer_keyReleaseImpl;
Java_sun_awt_motif_MRobotPeer_mouseMoveImpl;
Java_sun_awt_motif_MRobotPeer_mousePressImpl;
Java_sun_awt_motif_MRobotPeer_mouseReleaseImpl;
Java_sun_awt_motif_MRobotPeer_mouseWheelImpl;
Java_sun_awt_motif_MRobotPeer_setup;
Java_sun_awt_motif_MScrollbarPeer_create;
Java_sun_awt_motif_MScrollbarPeer_setLineIncrement;
Java_sun_awt_motif_MScrollbarPeer_setPageIncrement;
Java_sun_awt_motif_MScrollbarPeer_pSetValues;
Java_sun_awt_motif_MScrollPanePeer_create;
Java_sun_awt_motif_MScrollPanePeer_pGetBlockIncrement;
Java_sun_awt_motif_MScrollPanePeer_pGetScrollbarSpace;
Java_sun_awt_motif_MScrollPanePeer_pGetShadow;
Java_sun_awt_motif_MScrollPanePeer_pInsets;
Java_sun_awt_motif_MScrollPanePeer_pSetIncrement;
Java_sun_awt_motif_MScrollPanePeer_pSetScrollChild;
Java_sun_awt_motif_MScrollPanePeer_setScrollPosition;
Java_sun_awt_motif_MScrollPanePeer_setTypedValue;
Java_sun_awt_motif_MTextAreaPeer_initIDs;
Java_sun_awt_motif_MTextAreaPeer_pCreate;
Java_sun_awt_motif_MTextAreaPeer_getCaretPosition;
Java_sun_awt_motif_MTextAreaPeer_getExtraHeight;
Java_sun_awt_motif_MTextAreaPeer_getExtraWidth;
Java_sun_awt_motif_MTextAreaPeer_getSelectionEnd;
Java_sun_awt_motif_MTextAreaPeer_getSelectionStart;
Java_sun_awt_motif_MTextAreaPeer_getText;
Java_sun_awt_motif_MTextAreaPeer_insert;
Java_sun_awt_motif_MTextAreaPeer_nativeHandleMouseWheel;
Java_sun_awt_motif_MTextAreaPeer_pMakeCursorVisible;
Java_sun_awt_motif_MTextAreaPeer_pSetEditable;
Java_sun_awt_motif_MTextAreaPeer_pShow2;
Java_sun_awt_motif_MTextAreaPeer_replaceRange;
Java_sun_awt_motif_MTextAreaPeer_select;
Java_sun_awt_motif_MTextAreaPeer_setCaretPosition;
Java_sun_awt_motif_MTextAreaPeer_setFont;
Java_sun_awt_motif_MTextAreaPeer_setText;
Java_sun_awt_motif_MTextAreaPeer_setTextBackground;
Java_sun_awt_motif_MTextFieldPeer_initIDs;
Java_sun_awt_motif_MTextFieldPeer_pCreate;
Java_sun_awt_motif_MTextFieldPeer_getCaretPosition;
Java_sun_awt_motif_MTextFieldPeer_getSelectionEnd;
Java_sun_awt_motif_MTextFieldPeer_getSelectionStart;
Java_sun_awt_motif_MTextFieldPeer_getText;
Java_sun_awt_motif_MTextFieldPeer_insertReplaceText;
Java_sun_awt_motif_MTextFieldPeer_preDispose;
Java_sun_awt_motif_MTextFieldPeer_pSetEditable;
Java_sun_awt_motif_MTextFieldPeer_select;
Java_sun_awt_motif_MTextFieldPeer_setCaretPosition;
Java_sun_awt_motif_MTextFieldPeer_setEchoChar;
Java_sun_awt_motif_MTextFieldPeer_setFont;
Java_sun_awt_motif_MTextFieldPeer_setText;
#Java_sun_awt_motif_MButtonPeer_create;
#Java_sun_awt_motif_MButtonPeer_setLabel;
#Java_sun_awt_motif_MPanelPeer_pEnsureIndex;
#Java_sun_awt_motif_MPanelPeer_pRestack;
#Java_sun_awt_motif_MCanvasPeer_create;
#Java_sun_awt_motif_MCanvasPeer_initIDs;
#Java_sun_awt_motif_MCanvasPeer_resetTargetGC;
#Java_sun_awt_motif_MCheckboxMenuItemPeer_pSetState;
#Java_sun_awt_motif_MCheckboxPeer_create;
#Java_sun_awt_motif_MCheckboxPeer_setCheckboxGroup;
#Java_sun_awt_motif_MCheckboxPeer_setLabel;
#Java_sun_awt_motif_MCheckboxPeer_pSetState;
#Java_sun_awt_motif_MCheckboxPeer_pGetState;
#Java_sun_awt_motif_MChoicePeer_addItem;
#Java_sun_awt_motif_MChoicePeer_appendItems;
#Java_sun_awt_motif_MChoicePeer_create;
#Java_sun_awt_motif_MChoicePeer_pReshape;
#Java_sun_awt_motif_MChoicePeer_remove;
#Java_sun_awt_motif_MChoicePeer_removeAll;
#Java_sun_awt_motif_MChoicePeer_setBackground;
#Java_sun_awt_motif_MChoicePeer_pSelect;
#Java_sun_awt_motif_MChoicePeer_setFont;
#Java_sun_awt_motif_MChoicePeer_setForeground;
#Java_sun_awt_motif_MComponentPeer_addNativeDropTarget;
#Java_sun_awt_motif_MComponentPeer_getNativeColor;
#Java_sun_awt_motif_MComponentPeer_getWindow;
#Java_sun_awt_motif_MComponentPeer_pDisable;
#Java_sun_awt_motif_MComponentPeer_pDispose;
#Java_sun_awt_motif_MComponentPeer_pEnable;
#Java_sun_awt_motif_MComponentPeer_pGetLocationOnScreen;
#Java_sun_awt_motif_MComponentPeer_pGetLocationOnScreen2;
#Java_sun_awt_motif_MComponentPeer_pHide;
#Java_sun_awt_motif_MComponentPeer_pInitialize;
#Java_sun_awt_motif_MComponentPeer_pMakeCursorVisible;
#Java_sun_awt_motif_MComponentPeer_pReshape;
#Java_sun_awt_motif_MComponentPeer_pShow;
#Java_sun_awt_motif_MComponentPeer_removeNativeDropTarget;
#Java_sun_awt_motif_MComponentPeer_pSetBackground;
#Java_sun_awt_motif_MComponentPeer_pSetFont;
#Java_sun_awt_motif_MComponentPeer_processSynchronousLightweightTransfer;
#Java_sun_awt_motif_MComponentPeer__1requestFocus;
#Java_sun_awt_motif_MComponentPeer_getNativeFocusedWindow;
#Java_sun_awt_motif_MCheckboxMenuItemPeer_getState;
#Java_sun_awt_motif_MComponentPeer_pSetForeground;
#Java_sun_awt_motif_MDragSourceContextPeer_startDrag;
#Java_sun_awt_motif_MDragSourceContextPeer_setNativeCursor;
#Java_sun_awt_motif_MDropTargetContextPeer_addTransfer;
#Java_sun_awt_motif_MDropTargetContextPeer_dropDone;
#Java_sun_awt_motif_MDropTargetContextPeer_startTransfer;
#Java_sun_awt_motif_X11DragSourceContextPeer_startDrag;
#Java_sun_awt_motif_X11DragSourceContextPeer_setNativeCursor;
#Java_sun_awt_motif_X11DropTargetContextPeer_sendResponse;
#Java_sun_awt_motif_X11DropTargetContextPeer_dropDone;
#Java_sun_awt_motif_X11DropTargetContextPeer_getData;
#Java_sun_awt_motif_MEmbeddedFramePeer_NEFcreate;
#Java_sun_awt_motif_MEmbeddedFramePeer_pShowImpl;
#Java_sun_awt_motif_MEmbeddedFramePeer_requestXEmbedFocus;
#Java_sun_awt_motif_MEmbeddedFramePeer_isXEmbedApplicationActive;
#Java_sun_awt_motif_MEmbeddedFramePeer_isXEmbedActive;
#Java_sun_awt_motif_MEmbeddedFramePeer_synthesizeFocusInOut;
#Java_sun_awt_motif_MEmbeddedFramePeer_pReshapePrivate;
#Java_sun_awt_motif_MEmbeddedFramePeer_getBoundsPrivate;
#Java_sun_awt_motif_MEmbeddedFrame_getWidget;
#Java_sun_awt_motif_MEmbeddedFrame_mapWidget;
#Java_sun_awt_motif_MEmbedCanvasPeer_forwardEventToEmbedded;
#Java_sun_awt_motif_MFramePeer_pSetIconImage___3B_3I_3SII;
#Java_sun_awt_motif_MFileDialogPeer_create;
#Java_sun_awt_motif_MFileDialogPeer_pDispose;
#Java_sun_awt_motif_MFileDialogPeer_pHide;
#Java_sun_awt_motif_MFileDialogPeer_pReshape;
#Java_sun_awt_motif_MFileDialogPeer_pShow;
#Java_sun_awt_motif_MFileDialogPeer_setFileEntry;
#Java_sun_awt_motif_MFileDialogPeer_setFont;
#Java_sun_awt_motif_MFramePeer_pGetIconSize;
#Java_sun_awt_motif_MGlobalCursorManager_cacheInit;
#Java_sun_awt_motif_MGlobalCursorManager_findComponentAt;
#Java_sun_awt_motif_MGlobalCursorManager_findHeavyweightUnderCursor;
#Java_sun_awt_motif_MGlobalCursorManager_getCursorPos;
#Java_sun_awt_motif_MGlobalCursorManager_getLocationOnScreen;
#Java_sun_awt_motif_MLabelPeer_create;
#Java_sun_awt_motif_MLabelPeer_setAlignment;
#Java_sun_awt_motif_MLabelPeer_setText;
#Java_sun_awt_motif_MListPeer_addItem;
#Java_sun_awt_motif_MListPeer_create;
#Java_sun_awt_motif_MListPeer_delItems;
#Java_sun_awt_motif_MListPeer_deselect;
#Java_sun_awt_motif_MListPeer_isSelected;
#Java_sun_awt_motif_MListPeer_makeVisible;
#Java_sun_awt_motif_MListPeer_nativeHandleMouseWheel;
#Java_sun_awt_motif_MListPeer_select;
#Java_sun_awt_motif_MListPeer_setMultipleSelections;
#Java_sun_awt_motif_MMenuBarPeer_create;
#Java_sun_awt_motif_MMenuItemPeer_createMenuItem;
#Java_sun_awt_motif_MMenuItemPeer_pDisable;
#Java_sun_awt_motif_MMenuItemPeer_pDispose;
#Java_sun_awt_motif_MMenuItemPeer_pEnable;
#Java_sun_awt_motif_MMenuItemPeer_pSetLabel;
#Java_sun_awt_motif_MMenuPeer_createMenu;
#Java_sun_awt_motif_MMenuPeer_createSubMenu;
#Java_sun_awt_motif_MMenuPeer_pDispose;
#Java_sun_awt_motif_MPopupMenuPeer_createMenu;
#Java_sun_awt_motif_MPopupMenuPeer_pDispose;
#Java_sun_awt_motif_MPopupMenuPeer_pShow;
#Java_sun_awt_motif_MRobotPeer_getRGBPixelsImpl;
#Java_sun_awt_motif_MRobotPeer_keyPressImpl;
#Java_sun_awt_motif_MRobotPeer_keyReleaseImpl;
#Java_sun_awt_motif_MRobotPeer_mouseMoveImpl;
#Java_sun_awt_motif_MRobotPeer_mousePressImpl;
#Java_sun_awt_motif_MRobotPeer_mouseReleaseImpl;
#Java_sun_awt_motif_MRobotPeer_mouseWheelImpl;
#Java_sun_awt_motif_MRobotPeer_setup;
#Java_sun_awt_motif_MScrollbarPeer_create;
#Java_sun_awt_motif_MScrollbarPeer_setLineIncrement;
#Java_sun_awt_motif_MScrollbarPeer_setPageIncrement;
#Java_sun_awt_motif_MScrollbarPeer_pSetValues;
#Java_sun_awt_motif_MScrollPanePeer_create;
#Java_sun_awt_motif_MScrollPanePeer_pGetBlockIncrement;
#Java_sun_awt_motif_MScrollPanePeer_pGetScrollbarSpace;
#Java_sun_awt_motif_MScrollPanePeer_pGetShadow;
#Java_sun_awt_motif_MScrollPanePeer_pInsets;
#Java_sun_awt_motif_MScrollPanePeer_pSetIncrement;
#Java_sun_awt_motif_MScrollPanePeer_pSetScrollChild;
#Java_sun_awt_motif_MScrollPanePeer_setScrollPosition;
#Java_sun_awt_motif_MScrollPanePeer_setTypedValue;
#Java_sun_awt_motif_MTextAreaPeer_initIDs;
#Java_sun_awt_motif_MTextAreaPeer_pCreate;
#Java_sun_awt_motif_MTextAreaPeer_getCaretPosition;
#Java_sun_awt_motif_MTextAreaPeer_getExtraHeight;
#Java_sun_awt_motif_MTextAreaPeer_getExtraWidth;
#Java_sun_awt_motif_MTextAreaPeer_getSelectionEnd;
#Java_sun_awt_motif_MTextAreaPeer_getSelectionStart;
#Java_sun_awt_motif_MTextAreaPeer_getText;
#Java_sun_awt_motif_MTextAreaPeer_insert;
#Java_sun_awt_motif_MTextAreaPeer_nativeHandleMouseWheel;
#Java_sun_awt_motif_MTextAreaPeer_pMakeCursorVisible;
#Java_sun_awt_motif_MTextAreaPeer_pSetEditable;
#Java_sun_awt_motif_MTextAreaPeer_pShow2;
#Java_sun_awt_motif_MTextAreaPeer_replaceRange;
#Java_sun_awt_motif_MTextAreaPeer_select;
#Java_sun_awt_motif_MTextAreaPeer_setCaretPosition;
#Java_sun_awt_motif_MTextAreaPeer_setFont;
#Java_sun_awt_motif_MTextAreaPeer_setText;
#Java_sun_awt_motif_MTextAreaPeer_setTextBackground;
#Java_sun_awt_motif_MTextFieldPeer_initIDs;
#Java_sun_awt_motif_MTextFieldPeer_pCreate;
#Java_sun_awt_motif_MTextFieldPeer_getCaretPosition;
#Java_sun_awt_motif_MTextFieldPeer_getSelectionEnd;
#Java_sun_awt_motif_MTextFieldPeer_getSelectionStart;
#Java_sun_awt_motif_MTextFieldPeer_getText;
#Java_sun_awt_motif_MTextFieldPeer_insertReplaceText;
#Java_sun_awt_motif_MTextFieldPeer_preDispose;
#Java_sun_awt_motif_MTextFieldPeer_pSetEditable;
#Java_sun_awt_motif_MTextFieldPeer_select;
#Java_sun_awt_motif_MTextFieldPeer_setCaretPosition;
#Java_sun_awt_motif_MTextFieldPeer_setEchoChar;
#Java_sun_awt_motif_MTextFieldPeer_setFont;
#Java_sun_awt_motif_MTextFieldPeer_setText;
Java_sun_awt_motif_MToolkit_beep;
Java_sun_awt_motif_MToolkit_getLockingKeyStateNative;
Java_sun_awt_motif_MToolkit_getMulticlickTime;
@ -236,30 +236,30 @@ SUNWprivate_1.1 {
Java_sun_awt_motif_MToolkit_nativeGrab;
Java_sun_awt_motif_MToolkit_getWMName;
Java_sun_awt_motif_MWindowAttributes_initIDs;
Java_sun_awt_motif_MWindowPeer_pDispose;
Java_sun_awt_motif_MWindowPeer_pHide;
Java_sun_awt_motif_MWindowPeer_pReshape;
Java_sun_awt_motif_MWindowPeer_pSetTitle;
Java_sun_awt_motif_MWindowPeer_pShow;
Java_sun_awt_motif_MWindowPeer_setResizable;
Java_sun_awt_motif_MWindowPeer_toBack;
Java_sun_awt_motif_MWindowPeer_addTextComponentNative;
Java_sun_awt_motif_MWindowPeer_getState;
Java_sun_awt_motif_MWindowPeer_pSetIMMOption;
Java_sun_awt_motif_MWindowPeer_pSetMenuBar;
Java_sun_awt_motif_MWindowPeer_pShowModal;
Java_sun_awt_motif_MWindowPeer_removeTextComponentNative;
Java_sun_awt_motif_MWindowPeer_setSaveUnder;
Java_sun_awt_motif_MWindowPeer_setState;
Java_sun_awt_motif_MWindowPeer_resetTargetGC;
Java_sun_awt_motif_MWindowPeer_registerX11DropTarget;
Java_sun_awt_motif_MWindowPeer_unregisterX11DropTarget;
Java_sun_awt_motif_MWindowPeer_updateAlwaysOnTop;
Java_sun_awt_motif_MWindowPeer_setFocusableWindow;
Java_sun_awt_motif_MWindowPeer_pToFront;
Java_sun_awt_motif_MCustomCursor_cacheInit;
Java_sun_awt_motif_MCustomCursor_createCursor;
Java_sun_awt_motif_MCustomCursor_queryBestCursor;
#Java_sun_awt_motif_MWindowPeer_pDispose;
#Java_sun_awt_motif_MWindowPeer_pHide;
#Java_sun_awt_motif_MWindowPeer_pReshape;
#Java_sun_awt_motif_MWindowPeer_pSetTitle;
#Java_sun_awt_motif_MWindowPeer_pShow;
#Java_sun_awt_motif_MWindowPeer_setResizable;
#Java_sun_awt_motif_MWindowPeer_toBack;
#Java_sun_awt_motif_MWindowPeer_addTextComponentNative;
#Java_sun_awt_motif_MWindowPeer_getState;
#Java_sun_awt_motif_MWindowPeer_pSetIMMOption;
#Java_sun_awt_motif_MWindowPeer_pSetMenuBar;
#Java_sun_awt_motif_MWindowPeer_pShowModal;
#Java_sun_awt_motif_MWindowPeer_removeTextComponentNative;
#Java_sun_awt_motif_MWindowPeer_setSaveUnder;
#Java_sun_awt_motif_MWindowPeer_setState;
#Java_sun_awt_motif_MWindowPeer_resetTargetGC;
#Java_sun_awt_motif_MWindowPeer_registerX11DropTarget;
#Java_sun_awt_motif_MWindowPeer_unregisterX11DropTarget;
#Java_sun_awt_motif_MWindowPeer_updateAlwaysOnTop;
#Java_sun_awt_motif_MWindowPeer_setFocusableWindow;
#Java_sun_awt_motif_MWindowPeer_pToFront;
#Java_sun_awt_motif_MCustomCursor_cacheInit;
#Java_sun_awt_motif_MCustomCursor_createCursor;
#Java_sun_awt_motif_MCustomCursor_queryBestCursor;
Java_sun_awt_motif_X11FontMetrics_bytesWidth;
Java_sun_awt_motif_X11FontMetrics_getMFCharsWidth;
Java_sun_awt_motif_X11FontMetrics_init;
@ -268,18 +268,18 @@ SUNWprivate_1.1 {
Java_sun_awt_X11InputMethod_resetXIC;
Java_sun_awt_X11InputMethod_setCompositionEnabledNative;
Java_sun_awt_X11InputMethod_turnoffStatusWindow;
Java_sun_awt_motif_MInputMethod_openXIMNative;
Java_sun_awt_motif_MInputMethod_configureStatusAreaNative;
Java_sun_awt_motif_MInputMethod_createXICNative;
Java_sun_awt_motif_MInputMethod_reconfigureXICNative;
Java_sun_awt_motif_MInputMethod_setXICFocusNative;
Java_sun_awt_motif_X11Clipboard_getClipboardData;
Java_sun_awt_motif_X11Clipboard_getClipboardFormats;
Java_sun_awt_motif_X11Clipboard_registerClipboardViewer;
Java_sun_awt_motif_X11Clipboard_unregisterClipboardViewer;
Java_sun_awt_motif_X11Selection_init;
Java_sun_awt_motif_X11Selection_pGetSelectionOwnership;
Java_sun_awt_motif_X11Selection_clearNativeContext;
#Java_sun_awt_motif_MInputMethod_openXIMNative;
#Java_sun_awt_motif_MInputMethod_configureStatusAreaNative;
#Java_sun_awt_motif_MInputMethod_createXICNative;
#Java_sun_awt_motif_MInputMethod_reconfigureXICNative;
#Java_sun_awt_motif_MInputMethod_setXICFocusNative;
#Java_sun_awt_motif_X11Clipboard_getClipboardData;
#Java_sun_awt_motif_X11Clipboard_getClipboardFormats;
#Java_sun_awt_motif_X11Clipboard_registerClipboardViewer;
#Java_sun_awt_motif_X11Clipboard_unregisterClipboardViewer;
#Java_sun_awt_motif_X11Selection_init;
#Java_sun_awt_motif_X11Selection_pGetSelectionOwnership;
#Java_sun_awt_motif_X11Selection_clearNativeContext;
Java_sun_awt_SunToolkit_closeSplashScreen;
Java_sun_awt_PlatformFont_initIDs;
Java_sun_awt_X11GraphicsConfig_init;
@ -311,25 +311,25 @@ SUNWprivate_1.1 {
Java_sun_awt_X11GraphicsEnvironment_initGLX;
Java_sun_awt_X11GraphicsEnvironment_pRunningXinerama;
Java_sun_awt_X11GraphicsEnvironment_getXineramaCenterPoint;
Java_sun_awt_motif_MEmbedCanvasPeer_initXEmbedServer;
Java_sun_awt_motif_MEmbedCanvasPeer_destroyXEmbedServer;
Java_sun_awt_motif_MEmbedCanvasPeer_isXEmbedActive;
Java_sun_awt_motif_MEmbedCanvasPeer_initDispatching;
Java_sun_awt_motif_MEmbedCanvasPeer_endDispatching;
Java_sun_awt_motif_MEmbedCanvasPeer_embedChild;
Java_sun_awt_motif_MEmbedCanvasPeer_childDestroyed;
Java_sun_awt_motif_MEmbedCanvasPeer_getEmbedPreferredSize;
Java_sun_awt_motif_MEmbedCanvasPeer_getEmbedMinimumSize;
Java_sun_awt_motif_MEmbedCanvasPeer_getClientBounds;
Java_sun_awt_motif_MEmbedCanvasPeer_notifyChildEmbedded;
Java_sun_awt_motif_MEmbedCanvasPeer_detachChild;
Java_sun_awt_motif_MEmbedCanvasPeer_forwardKeyEvent;
Java_sun_awt_motif_MEmbedCanvasPeer_getAWTKeyCodeForKeySym;
Java_sun_awt_motif_MEmbedCanvasPeer_sendMessage__I;
Java_sun_awt_motif_MEmbedCanvasPeer_sendMessage__IJJJ;
Java_sun_awt_motif_MEmbedCanvasPeer_getWindow;
Java_sun_awt_motif_GrabbedKey_initKeySymAndModifiers;
Java_sun_awt_motif_MEmbeddedFramePeer_traverseOut;
#Java_sun_awt_motif_MEmbedCanvasPeer_initXEmbedServer;
#Java_sun_awt_motif_MEmbedCanvasPeer_destroyXEmbedServer;
#Java_sun_awt_motif_MEmbedCanvasPeer_isXEmbedActive;
#Java_sun_awt_motif_MEmbedCanvasPeer_initDispatching;
#Java_sun_awt_motif_MEmbedCanvasPeer_endDispatching;
#Java_sun_awt_motif_MEmbedCanvasPeer_embedChild;
#Java_sun_awt_motif_MEmbedCanvasPeer_childDestroyed;
#Java_sun_awt_motif_MEmbedCanvasPeer_getEmbedPreferredSize;
#Java_sun_awt_motif_MEmbedCanvasPeer_getEmbedMinimumSize;
#Java_sun_awt_motif_MEmbedCanvasPeer_getClientBounds;
#Java_sun_awt_motif_MEmbedCanvasPeer_notifyChildEmbedded;
#Java_sun_awt_motif_MEmbedCanvasPeer_detachChild;
#Java_sun_awt_motif_MEmbedCanvasPeer_forwardKeyEvent;
#Java_sun_awt_motif_MEmbedCanvasPeer_getAWTKeyCodeForKeySym;
#Java_sun_awt_motif_MEmbedCanvasPeer_sendMessage__I;
#Java_sun_awt_motif_MEmbedCanvasPeer_sendMessage__IJJJ;
#Java_sun_awt_motif_MEmbedCanvasPeer_getWindow;
#Java_sun_awt_motif_GrabbedKey_initKeySymAndModifiers;
#Java_sun_awt_motif_MEmbeddedFramePeer_traverseOut;
Java_java_awt_AWTEvent_initIDs;
Java_java_awt_Button_initIDs;
Java_java_awt_Container_initIDs;
@ -343,39 +343,39 @@ SUNWprivate_1.1 {
Java_java_awt_Insets_initIDs;
Java_java_awt_TextField_initIDs;
Java_java_awt_Window_initIDs;
Java_sun_awt_motif_MCheckboxPeer_getIndicatorSize;
Java_sun_awt_motif_MCheckboxPeer_getSpacing;
Java_sun_awt_motif_MChoicePeer_freeNativeData;
Java_sun_awt_motif_MComponentPeer_getComponents_1NoClientCode;
Java_sun_awt_motif_MComponentPeer_getParent_1NoClientCode;
Java_sun_awt_motif_MComponentPeer_initIDs;
Java_sun_awt_motif_MComponentPeer_nativeHandleEvent;
Java_sun_awt_motif_MComponentPeer_pSetCursor;
Java_sun_awt_motif_MComponentPeer_pSetInnerForeground;
Java_sun_awt_motif_MComponentPeer_pSetScrollbarBackground;
Java_sun_awt_motif_MComponentPeer_setTargetBackground;
Java_sun_awt_motif_MDataTransferer_dragQueryFile;
Java_sun_awt_motif_MDataTransferer_getAtomForTarget;
Java_sun_awt_motif_MDataTransferer_getTargetNameForAtom;
Java_sun_awt_motif_MFileDialogPeer_insertReplaceFileDialogText;
#Java_sun_awt_motif_MCheckboxPeer_getIndicatorSize;
#Java_sun_awt_motif_MCheckboxPeer_getSpacing;
#Java_sun_awt_motif_MChoicePeer_freeNativeData;
#Java_sun_awt_motif_MComponentPeer_getComponents_1NoClientCode;
#Java_sun_awt_motif_MComponentPeer_getParent_1NoClientCode;
#Java_sun_awt_motif_MComponentPeer_initIDs;
#Java_sun_awt_motif_MComponentPeer_nativeHandleEvent;
#Java_sun_awt_motif_MComponentPeer_pSetCursor;
#Java_sun_awt_motif_MComponentPeer_pSetInnerForeground;
#Java_sun_awt_motif_MComponentPeer_pSetScrollbarBackground;
#Java_sun_awt_motif_MComponentPeer_setTargetBackground;
#Java_sun_awt_motif_MDataTransferer_dragQueryFile;
#Java_sun_awt_motif_MDataTransferer_getAtomForTarget;
#Java_sun_awt_motif_MDataTransferer_getTargetNameForAtom;
#Java_sun_awt_motif_MFileDialogPeer_insertReplaceFileDialogText;
Java_sun_awt_motif_MFontPeer_initIDs;
Java_sun_awt_motif_MListPeer_setBackground;
Java_sun_awt_motif_MMenuBarPeer_initIDs;
Java_sun_awt_motif_MMenuBarPeer_pDispose;
Java_sun_awt_motif_MMenuItemPeer_getParent_1NoClientCode;
Java_sun_awt_motif_MMenuItemPeer_initIDs;
Java_sun_awt_motif_MMenuItemPeer_pSetShortcut;
Java_sun_awt_motif_MPopupMenuPeer_initIDs;
Java_sun_awt_motif_MScrollbarPeer_initIDs;
Java_sun_awt_motif_MScrollPanePeer_initIDs;
Java_sun_awt_motif_MTextAreaPeer_pSetCursor;
#Java_sun_awt_motif_MListPeer_setBackground;
#Java_sun_awt_motif_MMenuBarPeer_initIDs;
#Java_sun_awt_motif_MMenuBarPeer_pDispose;
#Java_sun_awt_motif_MMenuItemPeer_getParent_1NoClientCode;
#Java_sun_awt_motif_MMenuItemPeer_initIDs;
#Java_sun_awt_motif_MMenuItemPeer_pSetShortcut;
#Java_sun_awt_motif_MPopupMenuPeer_initIDs;
#Java_sun_awt_motif_MScrollbarPeer_initIDs;
#Java_sun_awt_motif_MScrollPanePeer_initIDs;
#Java_sun_awt_motif_MTextAreaPeer_pSetCursor;
Java_sun_awt_motif_MToolkit_shutdown;
Java_sun_awt_motif_MWindowPeer_initIDs;
Java_sun_awt_motif_MWindowPeer_pCreate;
Java_sun_awt_motif_MWindowPeer_wrapInSequenced;
#Java_sun_awt_motif_MWindowPeer_initIDs;
#Java_sun_awt_motif_MWindowPeer_pCreate;
#Java_sun_awt_motif_MWindowPeer_wrapInSequenced;
Java_sun_awt_motif_X11FontMetrics_initIDs;
Java_sun_awt_X11InputMethod_initIDs;
Java_sun_awt_motif_X11Selection_initIDs;
#Java_sun_awt_X11InputMethod_initIDs;
#Java_sun_awt_motif_X11Selection_initIDs;
Java_sun_awt_motif_MToolkitThreadBlockedHandler_enter;
Java_sun_awt_motif_MToolkitThreadBlockedHandler_exit;
Java_sun_awt_X11GraphicsConfig_init;

View File

@ -170,7 +170,7 @@ SUNWprivate_1.1 {
GrPrim_Sg2dGetPixel;
GrPrim_Sg2dGetLCDTextContrast;
Java_sun_awt_motif_MComponentPeer_restoreFocus;
#Java_sun_awt_motif_MComponentPeer_restoreFocus;
Java_sun_awt_DefaultMouseInfoPeer_fillPointWithCoords;
Java_sun_awt_DefaultMouseInfoPeer_isWindowUnderMouse;
Java_java_awt_AWTEvent_nativeSetSource;
@ -189,158 +189,158 @@ SUNWprivate_1.1 {
Java_java_awt_ScrollPane_initIDs;
Java_java_awt_TextArea_initIDs;
Java_sun_awt_FontDescriptor_initIDs;
Java_sun_awt_motif_MButtonPeer_create;
Java_sun_awt_motif_MButtonPeer_setLabel;
Java_sun_awt_motif_MCanvasPeer_create;
Java_sun_awt_motif_MCanvasPeer_initIDs;
Java_sun_awt_motif_MCanvasPeer_resetTargetGC;
Java_sun_awt_motif_MCheckboxMenuItemPeer_pSetState;
Java_sun_awt_motif_MCheckboxPeer_create;
Java_sun_awt_motif_MCheckboxPeer_setCheckboxGroup;
Java_sun_awt_motif_MCheckboxPeer_setLabel;
Java_sun_awt_motif_MCheckboxPeer_pSetState;
Java_sun_awt_motif_MCheckboxPeer_pGetState;
Java_sun_awt_motif_MChoicePeer_addItem;
Java_sun_awt_motif_MChoicePeer_appendItems;
Java_sun_awt_motif_MChoicePeer_create;
Java_sun_awt_motif_MChoicePeer_pReshape;
Java_sun_awt_motif_MChoicePeer_remove;
Java_sun_awt_motif_MChoicePeer_removeAll;
Java_sun_awt_motif_MChoicePeer_setBackground;
Java_sun_awt_motif_MChoicePeer_pSelect;
Java_sun_awt_motif_MChoicePeer_setFont;
Java_sun_awt_motif_MChoicePeer_setForeground;
Java_sun_awt_motif_MComponentPeer_addNativeDropTarget;
Java_sun_awt_motif_MComponentPeer_createBackBuffer;
Java_sun_awt_motif_MComponentPeer_destroyBackBuffer;
Java_sun_awt_motif_MComponentPeer_getNativeColor;
Java_sun_awt_motif_MComponentPeer_getWindow;
Java_sun_awt_motif_MComponentPeer_pDisable;
Java_sun_awt_motif_MComponentPeer_pDispose;
Java_sun_awt_motif_MComponentPeer_pEnable;
Java_sun_awt_motif_MComponentPeer_pGetLocationOnScreen;
Java_sun_awt_motif_MComponentPeer_pGetLocationOnScreen2;
Java_sun_awt_motif_MComponentPeer_pHide;
Java_sun_awt_motif_MComponentPeer_pInitialize;
Java_sun_awt_motif_MComponentPeer_pMakeCursorVisible;
Java_sun_awt_motif_MComponentPeer_pReshape;
Java_sun_awt_motif_MComponentPeer_pShow;
Java_sun_awt_motif_MComponentPeer_removeNativeDropTarget;
Java_sun_awt_motif_MComponentPeer_swapBuffers;
Java_sun_awt_motif_MComponentPeer_pSetBackground;
Java_sun_awt_motif_MComponentPeer_pSetFont;
Java_sun_awt_motif_MComponentPeer_processSynchronousLightweightTransfer;
Java_sun_awt_motif_MComponentPeer__1requestFocus;
Java_sun_awt_motif_MCheckboxMenuItemPeer_getState;
Java_sun_awt_motif_MComponentPeer_pSetForeground;
Java_sun_awt_motif_MDragSourceContextPeer_startDrag;
Java_sun_awt_motif_MDragSourceContextPeer_setNativeCursor;
Java_sun_awt_motif_MDropTargetContextPeer_addTransfer;
Java_sun_awt_motif_MDropTargetContextPeer_dropDone;
Java_sun_awt_motif_MDropTargetContextPeer_startTransfer;
Java_sun_awt_motif_X11DragSourceContextPeer_startDrag;
Java_sun_awt_motif_X11DragSourceContextPeer_setNativeCursor;
Java_sun_awt_motif_X11DropTargetContextPeer_sendResponse;
Java_sun_awt_motif_X11DropTargetContextPeer_dropDone;
Java_sun_awt_motif_X11DropTargetContextPeer_getData;
Java_sun_awt_motif_MEmbeddedFramePeer_NEFcreate;
Java_sun_awt_motif_MEmbeddedFramePeer_pShowImpl;
Java_sun_awt_motif_MEmbeddedFramePeer_pReshapePrivate;
Java_sun_awt_motif_MEmbeddedFramePeer_getBoundsPrivate;
Java_sun_awt_motif_MFramePeer_pSetIconImage___3B_3I_3SII;
Java_sun_awt_motif_MEmbeddedFramePeer_requestXEmbedFocus;
Java_sun_awt_motif_MEmbeddedFramePeer_isXEmbedApplicationActive;
Java_sun_awt_motif_MEmbeddedFramePeer_isXEmbedActive;
Java_sun_awt_motif_MEmbeddedFrame_getWidget;
Java_sun_awt_motif_MEmbeddedFrame_mapWidget;
Java_sun_awt_motif_MFileDialogPeer_create;
Java_sun_awt_motif_MFileDialogPeer_pDispose;
Java_sun_awt_motif_MFileDialogPeer_pHide;
Java_sun_awt_motif_MFileDialogPeer_pReshape;
Java_sun_awt_motif_MFileDialogPeer_pShow;
Java_sun_awt_motif_MFileDialogPeer_setFileEntry;
Java_sun_awt_motif_MFileDialogPeer_setFont;
Java_sun_awt_motif_MFramePeer_pGetIconSize;
Java_sun_awt_motif_MGlobalCursorManager_cacheInit;
Java_sun_awt_motif_MGlobalCursorManager_findComponentAt;
Java_sun_awt_motif_MGlobalCursorManager_findHeavyweightUnderCursor;
Java_sun_awt_motif_MGlobalCursorManager_getCursorPos;
Java_sun_awt_motif_MGlobalCursorManager_getLocationOnScreen;
Java_sun_awt_motif_MLabelPeer_create;
Java_sun_awt_motif_MLabelPeer_setAlignment;
Java_sun_awt_motif_MLabelPeer_setText;
Java_sun_awt_motif_MListPeer_addItem;
Java_sun_awt_motif_MListPeer_create;
Java_sun_awt_motif_MListPeer_delItems;
Java_sun_awt_motif_MListPeer_deselect;
Java_sun_awt_motif_MListPeer_isSelected;
Java_sun_awt_motif_MListPeer_makeVisible;
Java_sun_awt_motif_MListPeer_select;
Java_sun_awt_motif_MListPeer_setMultipleSelections;
Java_sun_awt_motif_MMenuBarPeer_create;
Java_sun_awt_motif_MMenuItemPeer_createMenuItem;
Java_sun_awt_motif_MMenuItemPeer_pDisable;
Java_sun_awt_motif_MMenuItemPeer_pDispose;
Java_sun_awt_motif_MMenuItemPeer_pEnable;
Java_sun_awt_motif_MMenuItemPeer_pSetLabel;
Java_sun_awt_motif_MMenuPeer_createMenu;
Java_sun_awt_motif_MMenuPeer_createSubMenu;
Java_sun_awt_motif_MMenuPeer_pDispose;
Java_sun_awt_motif_MPopupMenuPeer_createMenu;
Java_sun_awt_motif_MPopupMenuPeer_pDispose;
Java_sun_awt_motif_MPopupMenuPeer_pShow;
Java_sun_awt_motif_MRobotPeer_getRGBPixelsImpl;
Java_sun_awt_motif_MRobotPeer_keyPressImpl;
Java_sun_awt_motif_MRobotPeer_keyReleaseImpl;
Java_sun_awt_motif_MRobotPeer_mouseMoveImpl;
Java_sun_awt_motif_MRobotPeer_mousePressImpl;
Java_sun_awt_motif_MRobotPeer_mouseReleaseImpl;
Java_sun_awt_motif_MRobotPeer_mouseWheelImpl;
Java_sun_awt_motif_MRobotPeer_setup;
Java_sun_awt_motif_MScrollbarPeer_create;
Java_sun_awt_motif_MScrollbarPeer_setLineIncrement;
Java_sun_awt_motif_MScrollbarPeer_setPageIncrement;
Java_sun_awt_motif_MScrollbarPeer_pSetValues;
Java_sun_awt_motif_MScrollPanePeer_create;
Java_sun_awt_motif_MScrollPanePeer_pGetBlockIncrement;
Java_sun_awt_motif_MScrollPanePeer_pGetScrollbarSpace;
Java_sun_awt_motif_MScrollPanePeer_pGetShadow;
Java_sun_awt_motif_MScrollPanePeer_pInsets;
Java_sun_awt_motif_MScrollPanePeer_pSetIncrement;
Java_sun_awt_motif_MScrollPanePeer_pSetScrollChild;
Java_sun_awt_motif_MScrollPanePeer_setScrollPosition;
Java_sun_awt_motif_MTextAreaPeer_initIDs;
Java_sun_awt_motif_MTextAreaPeer_pCreate;
Java_sun_awt_motif_MTextAreaPeer_getCaretPosition;
Java_sun_awt_motif_MTextAreaPeer_getExtraHeight;
Java_sun_awt_motif_MTextAreaPeer_getExtraWidth;
Java_sun_awt_motif_MTextAreaPeer_getSelectionEnd;
Java_sun_awt_motif_MTextAreaPeer_getSelectionStart;
Java_sun_awt_motif_MTextAreaPeer_getText;
Java_sun_awt_motif_MTextAreaPeer_insert;
Java_sun_awt_motif_MTextAreaPeer_pMakeCursorVisible;
Java_sun_awt_motif_MTextAreaPeer_pSetEditable;
Java_sun_awt_motif_MTextAreaPeer_pShow2;
Java_sun_awt_motif_MTextAreaPeer_replaceRange;
Java_sun_awt_motif_MTextAreaPeer_select;
Java_sun_awt_motif_MTextAreaPeer_setCaretPosition;
Java_sun_awt_motif_MTextAreaPeer_setFont;
Java_sun_awt_motif_MTextAreaPeer_setText;
Java_sun_awt_motif_MTextAreaPeer_setTextBackground;
Java_sun_awt_motif_MTextFieldPeer_initIDs;
Java_sun_awt_motif_MTextFieldPeer_pCreate;
Java_sun_awt_motif_MTextFieldPeer_getCaretPosition;
Java_sun_awt_motif_MTextFieldPeer_getSelectionEnd;
Java_sun_awt_motif_MTextFieldPeer_getSelectionStart;
Java_sun_awt_motif_MTextFieldPeer_getText;
Java_sun_awt_motif_MTextFieldPeer_insertReplaceText;
Java_sun_awt_motif_MTextFieldPeer_preDispose;
Java_sun_awt_motif_MTextFieldPeer_pSetEditable;
Java_sun_awt_motif_MTextFieldPeer_select;
Java_sun_awt_motif_MTextFieldPeer_setCaretPosition;
Java_sun_awt_motif_MTextFieldPeer_setEchoChar;
Java_sun_awt_motif_MTextFieldPeer_setFont;
Java_sun_awt_motif_MTextFieldPeer_setText;
#Java_sun_awt_motif_MButtonPeer_create;
#Java_sun_awt_motif_MButtonPeer_setLabel;
#Java_sun_awt_motif_MCanvasPeer_create;
#Java_sun_awt_motif_MCanvasPeer_initIDs;
#Java_sun_awt_motif_MCanvasPeer_resetTargetGC;
#Java_sun_awt_motif_MCheckboxMenuItemPeer_pSetState;
#Java_sun_awt_motif_MCheckboxPeer_create;
#Java_sun_awt_motif_MCheckboxPeer_setCheckboxGroup;
#Java_sun_awt_motif_MCheckboxPeer_setLabel;
#Java_sun_awt_motif_MCheckboxPeer_pSetState;
#Java_sun_awt_motif_MCheckboxPeer_pGetState;
#Java_sun_awt_motif_MChoicePeer_addItem;
#Java_sun_awt_motif_MChoicePeer_appendItems;
#Java_sun_awt_motif_MChoicePeer_create;
#Java_sun_awt_motif_MChoicePeer_pReshape;
#Java_sun_awt_motif_MChoicePeer_remove;
#Java_sun_awt_motif_MChoicePeer_removeAll;
#Java_sun_awt_motif_MChoicePeer_setBackground;
#Java_sun_awt_motif_MChoicePeer_pSelect;
#Java_sun_awt_motif_MChoicePeer_setFont;
#Java_sun_awt_motif_MChoicePeer_setForeground;
#Java_sun_awt_motif_MComponentPeer_addNativeDropTarget;
#Java_sun_awt_motif_MComponentPeer_createBackBuffer;
#Java_sun_awt_motif_MComponentPeer_destroyBackBuffer;
#Java_sun_awt_motif_MComponentPeer_getNativeColor;
#Java_sun_awt_motif_MComponentPeer_getWindow;
#Java_sun_awt_motif_MComponentPeer_pDisable;
#Java_sun_awt_motif_MComponentPeer_pDispose;
#Java_sun_awt_motif_MComponentPeer_pEnable;
#Java_sun_awt_motif_MComponentPeer_pGetLocationOnScreen;
#Java_sun_awt_motif_MComponentPeer_pGetLocationOnScreen2;
#Java_sun_awt_motif_MComponentPeer_pHide;
#Java_sun_awt_motif_MComponentPeer_pInitialize;
#Java_sun_awt_motif_MComponentPeer_pMakeCursorVisible;
#Java_sun_awt_motif_MComponentPeer_pReshape;
#Java_sun_awt_motif_MComponentPeer_pShow;
#Java_sun_awt_motif_MComponentPeer_removeNativeDropTarget;
#Java_sun_awt_motif_MComponentPeer_swapBuffers;
#Java_sun_awt_motif_MComponentPeer_pSetBackground;
#Java_sun_awt_motif_MComponentPeer_pSetFont;
#Java_sun_awt_motif_MComponentPeer_processSynchronousLightweightTransfer;
#Java_sun_awt_motif_MComponentPeer__1requestFocus;
#Java_sun_awt_motif_MCheckboxMenuItemPeer_getState;
#Java_sun_awt_motif_MComponentPeer_pSetForeground;
#Java_sun_awt_motif_MDragSourceContextPeer_startDrag;
#Java_sun_awt_motif_MDragSourceContextPeer_setNativeCursor;
#Java_sun_awt_motif_MDropTargetContextPeer_addTransfer;
#Java_sun_awt_motif_MDropTargetContextPeer_dropDone;
#Java_sun_awt_motif_MDropTargetContextPeer_startTransfer;
#Java_sun_awt_motif_X11DragSourceContextPeer_startDrag;
#Java_sun_awt_motif_X11DragSourceContextPeer_setNativeCursor;
#Java_sun_awt_motif_X11DropTargetContextPeer_sendResponse;
#Java_sun_awt_motif_X11DropTargetContextPeer_dropDone;
#Java_sun_awt_motif_X11DropTargetContextPeer_getData;
#Java_sun_awt_motif_MEmbeddedFramePeer_NEFcreate;
#Java_sun_awt_motif_MEmbeddedFramePeer_pShowImpl;
#Java_sun_awt_motif_MEmbeddedFramePeer_pReshapePrivate;
#Java_sun_awt_motif_MEmbeddedFramePeer_getBoundsPrivate;
#Java_sun_awt_motif_MFramePeer_pSetIconImage___3B_3I_3SII;
#Java_sun_awt_motif_MEmbeddedFramePeer_requestXEmbedFocus;
#Java_sun_awt_motif_MEmbeddedFramePeer_isXEmbedApplicationActive;
#Java_sun_awt_motif_MEmbeddedFramePeer_isXEmbedActive;
#Java_sun_awt_motif_MEmbeddedFrame_getWidget;
#Java_sun_awt_motif_MEmbeddedFrame_mapWidget;
#Java_sun_awt_motif_MFileDialogPeer_create;
#Java_sun_awt_motif_MFileDialogPeer_pDispose;
#Java_sun_awt_motif_MFileDialogPeer_pHide;
#Java_sun_awt_motif_MFileDialogPeer_pReshape;
#Java_sun_awt_motif_MFileDialogPeer_pShow;
#Java_sun_awt_motif_MFileDialogPeer_setFileEntry;
#Java_sun_awt_motif_MFileDialogPeer_setFont;
#Java_sun_awt_motif_MFramePeer_pGetIconSize;
#Java_sun_awt_motif_MGlobalCursorManager_cacheInit;
#Java_sun_awt_motif_MGlobalCursorManager_findComponentAt;
#Java_sun_awt_motif_MGlobalCursorManager_findHeavyweightUnderCursor;
#Java_sun_awt_motif_MGlobalCursorManager_getCursorPos;
#Java_sun_awt_motif_MGlobalCursorManager_getLocationOnScreen;
#Java_sun_awt_motif_MLabelPeer_create;
#Java_sun_awt_motif_MLabelPeer_setAlignment;
#Java_sun_awt_motif_MLabelPeer_setText;
#Java_sun_awt_motif_MListPeer_addItem;
#Java_sun_awt_motif_MListPeer_create;
#Java_sun_awt_motif_MListPeer_delItems;
#Java_sun_awt_motif_MListPeer_deselect;
#Java_sun_awt_motif_MListPeer_isSelected;
#Java_sun_awt_motif_MListPeer_makeVisible;
#Java_sun_awt_motif_MListPeer_select;
#Java_sun_awt_motif_MListPeer_setMultipleSelections;
#Java_sun_awt_motif_MMenuBarPeer_create;
#Java_sun_awt_motif_MMenuItemPeer_createMenuItem;
#Java_sun_awt_motif_MMenuItemPeer_pDisable;
#Java_sun_awt_motif_MMenuItemPeer_pDispose;
#Java_sun_awt_motif_MMenuItemPeer_pEnable;
#Java_sun_awt_motif_MMenuItemPeer_pSetLabel;
#Java_sun_awt_motif_MMenuPeer_createMenu;
#Java_sun_awt_motif_MMenuPeer_createSubMenu;
#Java_sun_awt_motif_MMenuPeer_pDispose;
#Java_sun_awt_motif_MPopupMenuPeer_createMenu;
#Java_sun_awt_motif_MPopupMenuPeer_pDispose;
#Java_sun_awt_motif_MPopupMenuPeer_pShow;
#Java_sun_awt_motif_MRobotPeer_getRGBPixelsImpl;
#Java_sun_awt_motif_MRobotPeer_keyPressImpl;
#Java_sun_awt_motif_MRobotPeer_keyReleaseImpl;
#Java_sun_awt_motif_MRobotPeer_mouseMoveImpl;
#Java_sun_awt_motif_MRobotPeer_mousePressImpl;
#Java_sun_awt_motif_MRobotPeer_mouseReleaseImpl;
#Java_sun_awt_motif_MRobotPeer_mouseWheelImpl;
#Java_sun_awt_motif_MRobotPeer_setup;
#Java_sun_awt_motif_MScrollbarPeer_create;
#Java_sun_awt_motif_MScrollbarPeer_setLineIncrement;
#Java_sun_awt_motif_MScrollbarPeer_setPageIncrement;
#Java_sun_awt_motif_MScrollbarPeer_pSetValues;
#Java_sun_awt_motif_MScrollPanePeer_create;
#Java_sun_awt_motif_MScrollPanePeer_pGetBlockIncrement;
#Java_sun_awt_motif_MScrollPanePeer_pGetScrollbarSpace;
#Java_sun_awt_motif_MScrollPanePeer_pGetShadow;
#Java_sun_awt_motif_MScrollPanePeer_pInsets;
#Java_sun_awt_motif_MScrollPanePeer_pSetIncrement;
#Java_sun_awt_motif_MScrollPanePeer_pSetScrollChild;
#Java_sun_awt_motif_MScrollPanePeer_setScrollPosition;
#Java_sun_awt_motif_MTextAreaPeer_initIDs;
#Java_sun_awt_motif_MTextAreaPeer_pCreate;
#Java_sun_awt_motif_MTextAreaPeer_getCaretPosition;
#Java_sun_awt_motif_MTextAreaPeer_getExtraHeight;
#Java_sun_awt_motif_MTextAreaPeer_getExtraWidth;
#Java_sun_awt_motif_MTextAreaPeer_getSelectionEnd;
#Java_sun_awt_motif_MTextAreaPeer_getSelectionStart;
#Java_sun_awt_motif_MTextAreaPeer_getText;
#Java_sun_awt_motif_MTextAreaPeer_insert;
#Java_sun_awt_motif_MTextAreaPeer_pMakeCursorVisible;
#Java_sun_awt_motif_MTextAreaPeer_pSetEditable;
#Java_sun_awt_motif_MTextAreaPeer_pShow2;
#Java_sun_awt_motif_MTextAreaPeer_replaceRange;
#Java_sun_awt_motif_MTextAreaPeer_select;
#Java_sun_awt_motif_MTextAreaPeer_setCaretPosition;
#Java_sun_awt_motif_MTextAreaPeer_setFont;
#Java_sun_awt_motif_MTextAreaPeer_setText;
#Java_sun_awt_motif_MTextAreaPeer_setTextBackground;
#Java_sun_awt_motif_MTextFieldPeer_initIDs;
#Java_sun_awt_motif_MTextFieldPeer_pCreate;
#Java_sun_awt_motif_MTextFieldPeer_getCaretPosition;
#Java_sun_awt_motif_MTextFieldPeer_getSelectionEnd;
#Java_sun_awt_motif_MTextFieldPeer_getSelectionStart;
#Java_sun_awt_motif_MTextFieldPeer_getText;
#Java_sun_awt_motif_MTextFieldPeer_insertReplaceText;
#Java_sun_awt_motif_MTextFieldPeer_preDispose;
#Java_sun_awt_motif_MTextFieldPeer_pSetEditable;
#Java_sun_awt_motif_MTextFieldPeer_select;
#Java_sun_awt_motif_MTextFieldPeer_setCaretPosition;
#Java_sun_awt_motif_MTextFieldPeer_setEchoChar;
#Java_sun_awt_motif_MTextFieldPeer_setFont;
#Java_sun_awt_motif_MTextFieldPeer_setText;
Java_sun_awt_motif_MToolkit_beep;
Java_sun_awt_motif_MToolkit_getLockingKeyStateNative;
Java_sun_awt_motif_MToolkit_getMulticlickTime;
@ -357,28 +357,28 @@ SUNWprivate_1.1 {
Java_sun_awt_motif_MToolkit_sync;
Java_sun_awt_motif_MToolkit_isAlwaysOnTopSupported;
Java_sun_awt_motif_MWindowAttributes_initIDs;
Java_sun_awt_motif_MWindowPeer_pDispose;
Java_sun_awt_motif_MWindowPeer_pHide;
Java_sun_awt_motif_MWindowPeer_pReshape;
Java_sun_awt_motif_MWindowPeer_pSetTitle;
Java_sun_awt_motif_MWindowPeer_pShow;
Java_sun_awt_motif_MWindowPeer_setResizable;
Java_sun_awt_motif_MWindowPeer_toBack;
Java_sun_awt_motif_MWindowPeer_addTextComponentNative;
Java_sun_awt_motif_MWindowPeer_getState;
Java_sun_awt_motif_MWindowPeer_pSetIMMOption;
Java_sun_awt_motif_MWindowPeer_pSetMenuBar;
Java_sun_awt_motif_MWindowPeer_pShowModal;
Java_sun_awt_motif_MWindowPeer_removeTextComponentNative;
Java_sun_awt_motif_MWindowPeer_setSaveUnder;
Java_sun_awt_motif_MWindowPeer_setState;
Java_sun_awt_motif_MWindowPeer_resetTargetGC;
Java_sun_awt_motif_MWindowPeer_registerX11DropTarget;
Java_sun_awt_motif_MWindowPeer_unregisterX11DropTarget;
Java_sun_awt_motif_MWindowPeer_updateAlwaysOnTop;
Java_sun_awt_motif_X11CustomCursor_cacheInit;
Java_sun_awt_motif_X11CustomCursor_createCursor;
Java_sun_awt_motif_X11CustomCursor_queryBestCursor;
#Java_sun_awt_motif_MWindowPeer_pDispose;
#Java_sun_awt_motif_MWindowPeer_pHide;
#Java_sun_awt_motif_MWindowPeer_pReshape;
#Java_sun_awt_motif_MWindowPeer_pSetTitle;
#Java_sun_awt_motif_MWindowPeer_pShow;
#Java_sun_awt_motif_MWindowPeer_setResizable;
#Java_sun_awt_motif_MWindowPeer_toBack;
#Java_sun_awt_motif_MWindowPeer_addTextComponentNative;
#Java_sun_awt_motif_MWindowPeer_getState;
#Java_sun_awt_motif_MWindowPeer_pSetIMMOption;
#Java_sun_awt_motif_MWindowPeer_pSetMenuBar;
#Java_sun_awt_motif_MWindowPeer_pShowModal;
#Java_sun_awt_motif_MWindowPeer_removeTextComponentNative;
#Java_sun_awt_motif_MWindowPeer_setSaveUnder;
#Java_sun_awt_motif_MWindowPeer_setState;
#Java_sun_awt_motif_MWindowPeer_resetTargetGC;
#Java_sun_awt_motif_MWindowPeer_registerX11DropTarget;
#Java_sun_awt_motif_MWindowPeer_unregisterX11DropTarget;
#Java_sun_awt_motif_MWindowPeer_updateAlwaysOnTop;
#Java_sun_awt_motif_X11CustomCursor_cacheInit;
#Java_sun_awt_motif_X11CustomCursor_createCursor;
#Java_sun_awt_motif_X11CustomCursor_queryBestCursor;
Java_sun_awt_motif_X11FontMetrics_bytesWidth;
Java_sun_awt_motif_X11FontMetrics_getMFCharsWidth;
Java_sun_awt_motif_X11FontMetrics_init;
@ -387,18 +387,18 @@ SUNWprivate_1.1 {
Java_sun_awt_X11InputMethod_resetXIC;
Java_sun_awt_X11InputMethod_setCompositionEnabledNative;
Java_sun_awt_X11InputMethod_turnoffStatusWindow;
Java_sun_awt_motif_MInputMethod_openXIMNative;
Java_sun_awt_motif_MInputMethod_configureStatusAreaNative;
Java_sun_awt_motif_MInputMethod_createXICNative;
Java_sun_awt_motif_MInputMethod_reconfigureXICNative;
Java_sun_awt_motif_MInputMethod_setXICFocusNative;
Java_sun_awt_motif_X11Clipboard_getClipboardData;
Java_sun_awt_motif_X11Clipboard_getClipboardFormats;
Java_sun_awt_motif_X11Clipboard_registerClipboardViewer;
Java_sun_awt_motif_X11Clipboard_unregisterClipboardViewer;
Java_sun_awt_motif_X11Selection_init;
Java_sun_awt_motif_X11Selection_pGetSelectionOwnership;
Java_sun_awt_motif_X11Selection_clearNativeContext;
#Java_sun_awt_motif_MInputMethod_openXIMNative;
#Java_sun_awt_motif_MInputMethod_configureStatusAreaNative;
#Java_sun_awt_motif_MInputMethod_createXICNative;
#Java_sun_awt_motif_MInputMethod_reconfigureXICNative;
#Java_sun_awt_motif_MInputMethod_setXICFocusNative;
#Java_sun_awt_motif_X11Clipboard_getClipboardData;
#Java_sun_awt_motif_X11Clipboard_getClipboardFormats;
#Java_sun_awt_motif_X11Clipboard_registerClipboardViewer;
#Java_sun_awt_motif_X11Clipboard_unregisterClipboardViewer;
#Java_sun_awt_motif_X11Selection_init;
#Java_sun_awt_motif_X11Selection_pGetSelectionOwnership;
#Java_sun_awt_motif_X11Selection_clearNativeContext;
Java_sun_awt_SunToolkit_closeSplashScreen;
Java_sun_awt_PlatformFont_initIDs;
Java_sun_awt_X11GraphicsConfig_init;
@ -442,40 +442,40 @@ SUNWprivate_1.1 {
Java_java_awt_Insets_initIDs;
Java_java_awt_TextField_initIDs;
Java_java_awt_Window_initIDs;
Java_sun_awt_motif_MCheckboxPeer_getIndicatorSize;
Java_sun_awt_motif_MCheckboxPeer_getSpacing;
Java_sun_awt_motif_MChoicePeer_freeNativeData;
Java_sun_awt_motif_MComponentPeer_getComponents_1NoClientCode;
Java_sun_awt_motif_MComponentPeer_getParent_1NoClientCode;
Java_sun_awt_motif_MComponentPeer_initIDs;
Java_sun_awt_motif_MComponentPeer_nativeHandleEvent;
Java_sun_awt_motif_MComponentPeer_pSetCursor;
Java_sun_awt_motif_MComponentPeer_pSetInnerForeground;
Java_sun_awt_motif_MComponentPeer_pSetScrollbarBackground;
Java_sun_awt_motif_MComponentPeer_setTargetBackground;
Java_sun_awt_motif_MDataTransferer_dragQueryFile;
Java_sun_awt_motif_MDataTransferer_getAtomForTarget;
Java_sun_awt_motif_MDataTransferer_getTargetNameForAtom;
Java_sun_awt_motif_MFileDialogPeer_insertReplaceFileDialogText;
#Java_sun_awt_motif_MCheckboxPeer_getIndicatorSize;
#Java_sun_awt_motif_MCheckboxPeer_getSpacing;
#Java_sun_awt_motif_MChoicePeer_freeNativeData;
#Java_sun_awt_motif_MComponentPeer_getComponents_1NoClientCode;
#Java_sun_awt_motif_MComponentPeer_getParent_1NoClientCode;
#Java_sun_awt_motif_MComponentPeer_initIDs;
#Java_sun_awt_motif_MComponentPeer_nativeHandleEvent;
#Java_sun_awt_motif_MComponentPeer_pSetCursor;
#Java_sun_awt_motif_MComponentPeer_pSetInnerForeground;
#Java_sun_awt_motif_MComponentPeer_pSetScrollbarBackground;
#Java_sun_awt_motif_MComponentPeer_setTargetBackground;
#Java_sun_awt_motif_MDataTransferer_dragQueryFile;
#Java_sun_awt_motif_MDataTransferer_getAtomForTarget;
#Java_sun_awt_motif_MDataTransferer_getTargetNameForAtom;
#Java_sun_awt_motif_MFileDialogPeer_insertReplaceFileDialogText;
Java_sun_awt_motif_MFontPeer_initIDs;
Java_sun_awt_motif_MListPeer_setBackground;
Java_sun_awt_motif_MMenuBarPeer_initIDs;
Java_sun_awt_motif_MMenuBarPeer_pDispose;
Java_sun_awt_motif_MMenuItemPeer_getParent_1NoClientCode;
Java_sun_awt_motif_MMenuItemPeer_initIDs;
Java_sun_awt_motif_MMenuItemPeer_pSetShortcut;
Java_sun_awt_motif_MPopupMenuPeer_initIDs;
Java_sun_awt_motif_MScrollbarPeer_initIDs;
Java_sun_awt_motif_MScrollPanePeer_initIDs;
Java_sun_awt_motif_MTextAreaPeer_pSetCursor;
#Java_sun_awt_motif_MListPeer_setBackground;
#Java_sun_awt_motif_MMenuBarPeer_initIDs;
#Java_sun_awt_motif_MMenuBarPeer_pDispose;
#Java_sun_awt_motif_MMenuItemPeer_getParent_1NoClientCode;
#Java_sun_awt_motif_MMenuItemPeer_initIDs;
#Java_sun_awt_motif_MMenuItemPeer_pSetShortcut;
#Java_sun_awt_motif_MPopupMenuPeer_initIDs;
#Java_sun_awt_motif_MScrollbarPeer_initIDs;
#Java_sun_awt_motif_MScrollPanePeer_initIDs;
#Java_sun_awt_motif_MTextAreaPeer_pSetCursor;
Java_sun_awt_motif_MToolkit_shutdown;
Java_sun_awt_motif_MWindowPeer_initIDs;
Java_sun_awt_motif_MWindowPeer_pCreate;
Java_sun_awt_motif_MWindowPeer_wrapInSequenced;
#Java_sun_awt_motif_MWindowPeer_initIDs;
#Java_sun_awt_motif_MWindowPeer_pCreate;
#Java_sun_awt_motif_MWindowPeer_wrapInSequenced;
Java_sun_awt_motif_X11FontMetrics_initIDs;
Java_sun_awt_X11InputMethod_initIDs;
#Java_sun_awt_X11InputMethod_initIDs;
Java_sun_awt_motif_X11OffScreenImage_updateBitmask;
Java_sun_awt_motif_X11Selection_initIDs;
#Java_sun_awt_motif_X11Selection_initIDs;
Java_sun_awt_motif_MToolkitThreadBlockedHandler_enter;
Java_sun_awt_motif_MToolkitThreadBlockedHandler_exit;
Java_sun_awt_X11GraphicsConfig_init;
@ -503,26 +503,26 @@ SUNWprivate_1.1 {
Java_sun_awt_X11SurfaceData_isDgaAvailable;
Java_sun_awt_X11SurfaceData_setInvalid;
Java_sun_awt_X11SurfaceData_flushNativeSurface;
Java_sun_awt_motif_MEmbedCanvasPeer_initXEmbedServer;
Java_sun_awt_motif_MEmbedCanvasPeer_destroyXEmbedServer;
Java_sun_awt_motif_MEmbedCanvasPeer_isXEmbedActive;
Java_sun_awt_motif_MEmbedCanvasPeer_initDispatching;
Java_sun_awt_motif_MEmbedCanvasPeer_endDispatching;
Java_sun_awt_motif_MEmbedCanvasPeer_embedChild;
Java_sun_awt_motif_MEmbedCanvasPeer_childDestroyed;
Java_sun_awt_motif_MEmbedCanvasPeer_getEmbedPreferredSize;
Java_sun_awt_motif_MEmbedCanvasPeer_getEmbedMinimumSize;
Java_sun_awt_motif_MEmbedCanvasPeer_getClientBounds;
Java_sun_awt_motif_MEmbedCanvasPeer_notifyChildEmbedded;
Java_sun_awt_motif_MEmbedCanvasPeer_detachChild;
Java_sun_awt_motif_MEmbedCanvasPeer_forwardKeyEvent;
Java_sun_awt_motif_MEmbedCanvasPeer_getAWTKeyCodeForKeySym;
Java_sun_awt_motif_MEmbedCanvasPeer_sendMessage__I;
Java_sun_awt_motif_MEmbedCanvasPeer_sendMessage__IJJJ;
Java_sun_awt_motif_MEmbedCanvasPeer_getWindow;
Java_sun_awt_motif_MEmbedCanvasPeer_forwardEventToEmbedded;
Java_sun_awt_motif_GrabbedKey_initKeySymAndModifiers;
Java_sun_awt_motif_MEmbeddedFramePeer_traverseOut;
#Java_sun_awt_motif_MEmbedCanvasPeer_initXEmbedServer;
#Java_sun_awt_motif_MEmbedCanvasPeer_destroyXEmbedServer;
#Java_sun_awt_motif_MEmbedCanvasPeer_isXEmbedActive;
#Java_sun_awt_motif_MEmbedCanvasPeer_initDispatching;
#Java_sun_awt_motif_MEmbedCanvasPeer_endDispatching;
#Java_sun_awt_motif_MEmbedCanvasPeer_embedChild;
#Java_sun_awt_motif_MEmbedCanvasPeer_childDestroyed;
#Java_sun_awt_motif_MEmbedCanvasPeer_getEmbedPreferredSize;
#Java_sun_awt_motif_MEmbedCanvasPeer_getEmbedMinimumSize;
#Java_sun_awt_motif_MEmbedCanvasPeer_getClientBounds;
#Java_sun_awt_motif_MEmbedCanvasPeer_notifyChildEmbedded;
#Java_sun_awt_motif_MEmbedCanvasPeer_detachChild;
#Java_sun_awt_motif_MEmbedCanvasPeer_forwardKeyEvent;
#Java_sun_awt_motif_MEmbedCanvasPeer_getAWTKeyCodeForKeySym;
#Java_sun_awt_motif_MEmbedCanvasPeer_sendMessage__I;
#Java_sun_awt_motif_MEmbedCanvasPeer_sendMessage__IJJJ;
#Java_sun_awt_motif_MEmbedCanvasPeer_getWindow;
#Java_sun_awt_motif_MEmbedCanvasPeer_forwardEventToEmbedded;
#Java_sun_awt_motif_GrabbedKey_initKeySymAndModifiers;
#Java_sun_awt_motif_MEmbeddedFramePeer_traverseOut;
awt_display;
awt_lock;
awt_Lock;

View File

@ -28,14 +28,6 @@
#
INIT += $(LIB_LOCATION)
ifndef HEADLESS
ifeq ($(PLATFORM), linux)
ifeq ($(STATIC_MOTIF),false)
INIT += $(LIB_LOCATION)/libXm.so
endif
endif
endif
#
# Files
#
@ -52,13 +44,9 @@ include $(BUILDDIR)/sun/awt/FILES_export_unix.gmk
ifdef HEADLESS
FILES_c = $(FILES_NO_MOTIF_c)
else
FILES_c = $(FILES_MOTIF_c) $(FILES_NO_MOTIF_c)
ifeq ($(MOTIF_VERSION), 2)
FILES_c += awt_motif21.c
FILES_c += awt_Choice21.c
endif
# FILES_c = $(FILES_MOTIF_c) $(FILES_NO_MOTIF_c)
# XXX if in FILES_MOTIF_c there are unrelated to motif stuff, create a separate list!
FILES_c = $(FILES_NO_MOTIF_c)
endif
ifeq ($(PLATFORM), solaris)
@ -93,15 +81,6 @@ include $(BUILDDIR)/common/Library.gmk
$(LIB_LOCATION):
$(MKDIR) -p $@
ifeq ($(PLATFORM), linux)
ifeq ($(STATIC_MOTIF),false)
$(LIB_LOCATION)/libXm.so:
$(CP) $(MOTIF_LIB)/libXm.so $(LIB_LOCATION)/libXm.so
# Automounter problem makes the link fail on Redhat 6.1.
# $(LN) -s $(MOTIF_LIB)/libXm.so $(LIB_LOCATION)/libXm.so
endif
endif
clean::
#
@ -135,33 +114,49 @@ CFLAGS += -DHEADLESS=$(HEADLESS)
CPPFLAGS += -DHEADLESS=$(HEADLESS)
OTHER_LDLIBS =
else
CFLAGS += -DMOTIF_VERSION=$(MOTIF_VERSION)
#CFLAGS += -DMOTIF_VERSION=$(MOTIF_VERSION)
ifeq ($(STATIC_MOTIF),true)
LIBXM = $(MOTIF_LIB)/libXm.a -lXp -lXmu
ifeq ($(PLATFORM), linux)
ifeq ($(ARCH_DATA_MODEL), 64)
LIBXT = -lXt
else
# Allows for builds on Debian GNU Linux, X11 is in a different place
LIBXT = $(firstword $(wildcard /usr/X11R6/lib/libXt.a) \
$(wildcard /usr/lib/libXt.a))
LIBSM = $(firstword $(wildcard /usr/X11R6/lib/libSM.a) \
$(wildcard /usr/lib/libSM.a))
LIBICE = $(firstword $(wildcard /usr/X11R6/lib/libICE.a) \
$(wildcard /usr/lib/libICE.a))
endif
endif
else
LIBXM = -L$(MOTIF_LIB) -lXm -lXp
ifeq ($(PLATFORM), linux)
LIBXT = -lXt
LIBSM =
LIBICE =
endif
endif
#ifeq ($(STATIC_MOTIF),true)
# LIBXM = $(MOTIF_LIB)/libXm.a -lXp -lXmu
# ifeq ($(PLATFORM), linux)
# ifeq ($(ARCH_DATA_MODEL), 64)
# LIBXT = -lXt
# else
# # Allows for builds on Debian GNU Linux, X11 is in a different place
# LIBXT = $(firstword $(wildcard /usr/X11R6/lib/libXt.a) \
# $(wildcard /usr/lib/libXt.a))
# LIBSM = $(firstword $(wildcard /usr/X11R6/lib/libSM.a) \
# $(wildcard /usr/lib/libSM.a))
# LIBICE = $(firstword $(wildcard /usr/X11R6/lib/libICE.a) \
# $(wildcard /usr/lib/libICE.a))
# endif
# endif
#else
# LIBXM = -L$(MOTIF_LIB) -lXm -lXp
# ifeq ($(PLATFORM), linux)
# LIBXT = -lXt
# LIBSM =
# LIBICE =
# endif
#endif
LIBXTST = -lXtst
ifeq ($(PLATFORM), linux)
ifeq ($(ARCH_DATA_MODEL), 64)
# XXX what about the rest of them?
LIBXT = -lXt
else
# Allows for builds on Debian GNU Linux, X11 is in a different place
LIBXT = $(firstword $(wildcard /usr/X11R6/lib/libXt.a) \
$(wildcard /usr/lib/libXt.a))
LIBSM = $(firstword $(wildcard /usr/X11R6/lib/libSM.a) \
$(wildcard /usr/lib/libSM.a))
LIBICE = $(firstword $(wildcard /usr/X11R6/lib/libICE.a) \
$(wildcard /usr/lib/libICE.a))
LIBXTST = $(firstword $(wildcard /usr/X11R6/lib/libXtst.a) \
$(wildcard /usr/lib/libXtst.a))
endif
endif
# Use -lXmu for EditRes support
LIBXMU_DBG = -lXmu
@ -169,14 +164,14 @@ LIBXMU_OPT =
LIBXMU = $(LIBXMU_$(VARIANT))
ifeq ($(PLATFORM), solaris)
OTHER_LDLIBS = $(LIBXM) -lXt -lXext $(LIBXTST) $(LIBXMU) -lX11 -lXi
OTHER_LDLIBS = -lXt -lXext $(LIBXTST) $(LIBXMU) -lX11 -lXi
endif
ifeq ($(PLATFORM), linux)
OTHER_CFLAGS += -DMLIB_NO_LIBSUNMATH
OTHER_CFLAGS += -DMOTIF_VERSION=2
# XXX what is this define below? Isn't it motif-related?
OTHER_CFLAGS += -DXMSTRINGDEFINES=1
OTHER_LDLIBS = $(LIBXM) $(LIBXMU) $(LIBXTST) -lXext $(LIBXT) $(LIBSM) $(LIBICE) -lX11 -lXi
OTHER_LDLIBS = $(LIBXMU) $(LIBXTST) -lXext $(LIBXT) $(LIBSM) $(LIBICE) -lX11 -lXi
endif
endif
@ -199,9 +194,8 @@ endif
CPPFLAGS += -I$(CUPS_HEADERS_PATH)
ifndef HEADLESS
CPPFLAGS += -I$(MOTIF_DIR)/include \
-I$(OPENWIN_HOME)/include
LDFLAGS += -L$(MOTIF_LIB) -L$(OPENWIN_LIB)
CPPFLAGS += -I$(OPENWIN_HOME)/include
LDFLAGS += -L$(OPENWIN_LIB)
endif # !HEADLESS

View File

@ -25,8 +25,8 @@
/*
* This file primarily consists of all the error and warning messages, that
* are used in ReportErrorMessage. All message must be defined here, in order
* to help in I18N/L10N the messages.
* are used in JLI_ReportErrorMessage. All message must be defined here, in
* order to help with localizing the messages.
*/
#ifndef _EMESSAGES_H

View File

@ -148,7 +148,7 @@ static void ShowSplashScreen();
static jboolean IsWildCardEnabled();
#define ARG_CHECK(n, f, a) if (n < 1) { \
ReportErrorMessage(f, a); \
JLI_ReportErrorMessage(f, a); \
printUsage = JNI_TRUE; \
*pret = 1; \
return JNI_TRUE; \
@ -326,15 +326,15 @@ JavaMain(void * _args)
start = CounterGet();
if (!InitializeJVM(&vm, &env, &ifn)) {
ReportErrorMessage(JVM_ERROR1);
JLI_ReportErrorMessage(JVM_ERROR1);
exit(1);
}
if (printVersion || showVersion) {
PrintJavaVersion(env, showVersion);
if ((*env)->ExceptionOccurred(env)) {
ReportExceptionDescription(env);
ReportErrorMessage(JNI_ERROR);
JLI_ReportExceptionDescription(env);
JLI_ReportErrorMessage(JNI_ERROR);
goto leave;
}
if (printVersion) {
@ -347,8 +347,8 @@ JavaMain(void * _args)
if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) {
PrintUsage(env, printXUsage);
if ((*env)->ExceptionOccurred(env)) {
ReportExceptionDescription(env);
ReportErrorMessage(JNI_ERROR);
JLI_ReportExceptionDescription(env);
JLI_ReportErrorMessage(JNI_ERROR);
ret=1;
}
goto leave;
@ -397,43 +397,43 @@ JavaMain(void * _args)
if (jarfile != 0) {
mainClassName = GetMainClassName(env, jarfile);
if ((*env)->ExceptionOccurred(env)) {
ReportExceptionDescription(env);
ReportErrorMessage(JNI_ERROR);
JLI_ReportExceptionDescription(env);
JLI_ReportErrorMessage(JNI_ERROR);
goto leave;
}
if (mainClassName == NULL) {
ReportErrorMessage(JAR_ERROR1,jarfile, GEN_ERROR);
JLI_ReportErrorMessage(JAR_ERROR1,jarfile, GEN_ERROR);
goto leave;
}
classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
if (classname == NULL) {
ReportExceptionDescription(env);
ReportErrorMessage(JNI_ERROR);
JLI_ReportExceptionDescription(env);
JLI_ReportErrorMessage(JNI_ERROR);
goto leave;
}
mainClass = LoadClass(env, classname);
if(mainClass == NULL) { /* exception occured */
ReportExceptionDescription(env);
ReportErrorMessage(CLS_ERROR1, classname);
JLI_ReportExceptionDescription(env);
JLI_ReportErrorMessage(CLS_ERROR1, classname);
goto leave;
}
(*env)->ReleaseStringUTFChars(env, mainClassName, classname);
} else {
mainClassName = NewPlatformString(env, classname);
if (mainClassName == NULL) {
ReportErrorMessage(CLS_ERROR2, classname, GEN_ERROR);
JLI_ReportErrorMessage(CLS_ERROR2, classname, GEN_ERROR);
goto leave;
}
classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
if (classname == NULL) {
ReportExceptionDescription(env);
ReportErrorMessage(JNI_ERROR);
JLI_ReportExceptionDescription(env);
JLI_ReportErrorMessage(JNI_ERROR);
goto leave;
}
mainClass = LoadClass(env, classname);
if(mainClass == NULL) { /* exception occured */
ReportExceptionDescription(env);
ReportErrorMessage(CLS_ERROR1, classname);
JLI_ReportExceptionDescription(env);
JLI_ReportErrorMessage(CLS_ERROR1, classname);
goto leave;
}
(*env)->ReleaseStringUTFChars(env, mainClassName, classname);
@ -444,10 +444,10 @@ JavaMain(void * _args)
"([Ljava/lang/String;)V");
if (mainID == NULL) {
if ((*env)->ExceptionOccurred(env)) {
ReportExceptionDescription(env);
ReportErrorMessage(JNI_ERROR);
JLI_ReportExceptionDescription(env);
JLI_ReportErrorMessage(JNI_ERROR);
} else {
ReportErrorMessage(CLS_ERROR3);
JLI_ReportErrorMessage(CLS_ERROR3);
}
goto leave;
}
@ -459,8 +459,8 @@ JavaMain(void * _args)
mainID, JNI_TRUE);
if( obj == NULL) { /* exception occurred */
ReportExceptionDescription(env);
ReportErrorMessage(JNI_ERROR);
JLI_ReportExceptionDescription(env);
JLI_ReportErrorMessage(JNI_ERROR);
goto leave;
}
@ -469,14 +469,14 @@ JavaMain(void * _args)
(*env)->GetObjectClass(env, obj),
"getModifiers", "()I");
if ((*env)->ExceptionOccurred(env)) {
ReportExceptionDescription(env);
ReportErrorMessage(JNI_ERROR);
JLI_ReportExceptionDescription(env);
JLI_ReportErrorMessage(JNI_ERROR);
goto leave;
}
mods = (*env)->CallIntMethod(env, obj, mid);
if ((mods & 1) == 0) { /* if (!Modifier.isPublic(mods)) ... */
ReportErrorMessage(CLS_ERROR4);
JLI_ReportErrorMessage(CLS_ERROR4);
goto leave;
}
}
@ -484,8 +484,8 @@ JavaMain(void * _args)
/* Build argument array */
mainArgs = NewPlatformStringArray(env, argv, argc);
if (mainArgs == NULL) {
ReportExceptionDescription(env);
ReportErrorMessage(JNI_ERROR);
JLI_ReportExceptionDescription(env);
JLI_ReportErrorMessage(JNI_ERROR);
goto leave;
}
@ -506,7 +506,7 @@ JavaMain(void * _args)
* launcher's return code except by calling System.exit.
*/
if ((*vm)->DetachCurrentThread(vm) != 0) {
ReportErrorMessage(JVM_ERROR2);
JLI_ReportErrorMessage(JVM_ERROR2);
ret = 1;
goto leave;
}
@ -635,7 +635,7 @@ CheckJvmType(int *pargc, char ***argv, jboolean speculative) {
if (loopCount > knownVMsCount) {
if (!speculative) {
ReportErrorMessage(CFG_ERROR1);
JLI_ReportErrorMessage(CFG_ERROR1);
exit(1);
} else {
return "ERROR";
@ -645,7 +645,7 @@ CheckJvmType(int *pargc, char ***argv, jboolean speculative) {
if (nextIdx < 0) {
if (!speculative) {
ReportErrorMessage(CFG_ERROR2, knownVMs[jvmidx].alias);
JLI_ReportErrorMessage(CFG_ERROR2, knownVMs[jvmidx].alias);
exit(1);
} else {
return "ERROR";
@ -660,7 +660,7 @@ CheckJvmType(int *pargc, char ***argv, jboolean speculative) {
switch (knownVMs[jvmidx].flag) {
case VM_WARN:
if (!speculative) {
ReportErrorMessage(CFG_WARN1, jvmtype, knownVMs[0].name + 1);
JLI_ReportErrorMessage(CFG_WARN1, jvmtype, knownVMs[0].name + 1);
}
/* fall through */
case VM_IGNORE:
@ -670,7 +670,7 @@ CheckJvmType(int *pargc, char ***argv, jboolean speculative) {
break;
case VM_ERROR:
if (!speculative) {
ReportErrorMessage(CFG_ERROR3, jvmtype);
JLI_ReportErrorMessage(CFG_ERROR3, jvmtype);
exit(1);
} else {
return "ERROR";
@ -879,9 +879,9 @@ SelectVersion(int argc, char **argv, char **main_class)
if (jarflag && operand) {
if ((res = JLI_ParseManifest(operand, &info)) != 0) {
if (res == -1)
ReportErrorMessage(JAR_ERROR2, operand);
JLI_ReportErrorMessage(JAR_ERROR2, operand);
else
ReportErrorMessage(JAR_ERROR3, operand);
JLI_ReportErrorMessage(JAR_ERROR3, operand);
exit(1);
}
@ -948,7 +948,7 @@ SelectVersion(int argc, char **argv, char **main_class)
* Check for correct syntax of the version specification (JSR 56).
*/
if (!JLI_ValidVersionString(info.jre_version)) {
ReportErrorMessage(SPC_ERROR1, info.jre_version);
JLI_ReportErrorMessage(SPC_ERROR1, info.jre_version);
exit(1);
}
@ -970,7 +970,7 @@ SelectVersion(int argc, char **argv, char **main_class)
JLI_MemFree(new_argv);
return;
} else {
ReportErrorMessage(CFG_ERROR4, info.jre_version);
JLI_ReportErrorMessage(CFG_ERROR4, info.jre_version);
exit(1);
}
}
@ -1040,7 +1040,7 @@ ParseArguments(int *pargc, char ***pargv, char **pjarfile,
* command line options.
*/
} else if (JLI_StrCmp(arg, "-fullversion") == 0) {
ReportMessage("%s full version \"%s\"", _launcher_name, GetFullVersion());
JLI_ReportMessage("%s full version \"%s\"", _launcher_name, GetFullVersion());
return JNI_FALSE;
} else if (JLI_StrCmp(arg, "-verbosegc") == 0) {
AddOption("-verbose:gc", NULL);
@ -1080,7 +1080,7 @@ ParseArguments(int *pargc, char ***pargv, char **pjarfile,
JLI_StrCmp(arg, "-cs") == 0 ||
JLI_StrCmp(arg, "-noasyncgc") == 0) {
/* No longer supported */
ReportErrorMessage(ARG_WARN, arg);
JLI_ReportErrorMessage(ARG_WARN, arg);
} else if (JLI_StrCCmp(arg, "-version:") == 0 ||
JLI_StrCmp(arg, "-no-jre-restrict-search") == 0 ||
JLI_StrCmp(arg, "-jre-restrict-search") == 0 ||
@ -1143,12 +1143,12 @@ InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn)
#define NULL_CHECK0(e) if ((e) == 0) { \
ReportErrorMessage(JNI_ERROR); \
JLI_ReportErrorMessage(JNI_ERROR); \
return 0; \
}
#define NULL_CHECK(e) if ((e) == 0) { \
ReportErrorMessage(JNI_ERROR); \
JLI_ReportErrorMessage(JNI_ERROR); \
return; \
}
@ -1351,7 +1351,7 @@ TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***parg
char *arg = argv[i];
if (arg[0] == '-' && arg[1] == 'J') {
if (arg[2] == '\0') {
ReportErrorMessage(ARG_ERROR3);
JLI_ReportErrorMessage(ARG_ERROR3);
exit(1);
}
*nargv++ = arg + 2;
@ -1418,7 +1418,7 @@ AddApplicationOptions(int cpathc, const char **cpathv)
}
if (!GetApplicationHome(home, sizeof(home))) {
ReportErrorMessage(CFG_ERROR5);
JLI_ReportErrorMessage(CFG_ERROR5);
return JNI_FALSE;
}
@ -1691,7 +1691,7 @@ ReadKnownVMs(const char *jrepath, const char * arch, jboolean speculative)
jvmCfg = fopen(jvmCfgName, "r");
if (jvmCfg == NULL) {
if (!speculative) {
ReportErrorMessage(CFG_ERROR6, jvmCfgName);
JLI_ReportErrorMessage(CFG_ERROR6, jvmCfgName);
exit(1);
} else {
return -1;
@ -1703,7 +1703,7 @@ ReadKnownVMs(const char *jrepath, const char * arch, jboolean speculative)
if (line[0] == '#')
continue;
if (line[0] != '-') {
ReportErrorMessage(CFG_WARN2, lineno, jvmCfgName);
JLI_ReportErrorMessage(CFG_WARN2, lineno, jvmCfgName);
}
if (cnt >= knownVMsLimit) {
GrowKnownVMs(cnt);
@ -1711,13 +1711,13 @@ ReadKnownVMs(const char *jrepath, const char * arch, jboolean speculative)
line[JLI_StrLen(line)-1] = '\0'; /* remove trailing newline */
tmpPtr = line + JLI_StrCSpn(line, whiteSpace);
if (*tmpPtr == 0) {
ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName);
JLI_ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName);
} else {
/* Null-terminate this string for JLI_StringDup below */
*tmpPtr++ = 0;
tmpPtr += JLI_StrSpn(tmpPtr, whiteSpace);
if (*tmpPtr == 0) {
ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName);
JLI_ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName);
} else {
if (!JLI_StrCCmp(tmpPtr, "KNOWN")) {
vmType = VM_KNOWN;
@ -1727,7 +1727,7 @@ ReadKnownVMs(const char *jrepath, const char * arch, jboolean speculative)
tmpPtr += JLI_StrSpn(tmpPtr, whiteSpace);
}
if (*tmpPtr == 0) {
ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName);
JLI_ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName);
} else {
/* Null terminate altVMName */
altVMName = tmpPtr;
@ -1747,7 +1747,7 @@ ReadKnownVMs(const char *jrepath, const char * arch, jboolean speculative)
tmpPtr += JLI_StrSpn(tmpPtr, whiteSpace);
}
if (*tmpPtr == 0) {
ReportErrorMessage(CFG_WARN4, lineno, jvmCfgName);
JLI_ReportErrorMessage(CFG_WARN4, lineno, jvmCfgName);
} else {
/* Null terminate server class VM name */
serverClassVMName = tmpPtr;
@ -1756,7 +1756,7 @@ ReadKnownVMs(const char *jrepath, const char * arch, jboolean speculative)
vmType = VM_IF_SERVER_CLASS;
}
} else {
ReportErrorMessage(CFG_WARN5, lineno, &jvmCfgName[0]);
JLI_ReportErrorMessage(CFG_WARN5, lineno, &jvmCfgName[0]);
vmType = VM_KNOWN;
}
}
@ -2019,7 +2019,7 @@ RemovableOption(char * option)
* A utility procedure to always print to stderr
*/
void
ReportMessage(const char* fmt, ...)
JLI_ReportMessage(const char* fmt, ...)
{
va_list vl;
va_start(vl, fmt);

View File

@ -121,24 +121,20 @@ void CreateExecutionEnvironment(int *_argc,
char jvmpath[],
jint so_jvmpath,
char **original_argv);
/* Reports an error message to stderr or a window as appropriate. */
void JLI_ReportErrorMessage(const char * message, ...);
/* Reports a system error message to stderr or a window */
void JLI_ReportErrorMessageSys(const char * message, ...);
/* Reports an error message only to stderr. */
void JLI_ReportMessage(const char * message, ...);
/*
* Report an error message to stderr or a window as appropriate.
*/
void ReportErrorMessage(const char * message, ...);
void ReportErrorMessageSys(const char * format, ...);
/*
* Report an error message only to stderr.
*/
void ReportMessage(const char * message, ...);
/*
* Report an exception which terminates the vm to stderr or a window
* Reports an exception which terminates the vm to stderr or a window
* as appropriate.
*/
void ReportExceptionDescription(JNIEnv * env);
void JLI_ReportExceptionDescription(JNIEnv * env);
void PrintMachineDependentOptions();
const char *jlong_format_specifier();

View File

@ -176,6 +176,18 @@ public class JmxProperties {
public static final String RELATION_LOGGER_NAME =
"javax.management.relation";
/**
* Logger name for Namespaces.
*/
public static final String NAMESPACE_LOGGER_NAME =
"javax.management.namespace";
/**
* Logger name for Namespaces.
*/
public static final Logger NAMESPACE_LOGGER =
Logger.getLogger(NAMESPACE_LOGGER_NAME);
/**
* Logger for Relation Service.
*/

View File

@ -25,33 +25,49 @@
package com.sun.jmx.interceptor;
// java import
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.Set;
import java.util.HashSet;
import java.util.WeakHashMap;
// JMX RI
import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
import com.sun.jmx.mbeanserver.DynamicMBean2;
import com.sun.jmx.mbeanserver.Introspector;
import com.sun.jmx.mbeanserver.MBeanInjector;
import com.sun.jmx.mbeanserver.MBeanInstantiator;
import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository;
import com.sun.jmx.mbeanserver.NamedObject;
import com.sun.jmx.mbeanserver.NotifySupport;
import com.sun.jmx.mbeanserver.Repository;
import com.sun.jmx.mbeanserver.Repository.RegistrationContext;
import com.sun.jmx.mbeanserver.Util;
import com.sun.jmx.remote.util.EnvHelp;
import java.lang.ref.WeakReference;
import java.security.AccessControlContext;
import java.security.Permission;
import java.security.ProtectionDomain;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.logging.Level;
// JMX import
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.DynamicWrapperMBean;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.JMRuntimeException;
import javax.management.ListenerNotFoundException;
import javax.management.MalformedObjectNameException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanPermission;
@ -64,6 +80,7 @@ import javax.management.MBeanTrustPermission;
import javax.management.NotCompliantMBeanException;
import javax.management.Notification;
import javax.management.NotificationBroadcaster;
import javax.management.NotificationBroadcasterSupport;
import javax.management.NotificationEmitter;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
@ -75,22 +92,7 @@ import javax.management.ReflectionException;
import javax.management.RuntimeErrorException;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException;
// JMX RI
import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
import com.sun.jmx.mbeanserver.DynamicMBean2;
import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository;
import com.sun.jmx.mbeanserver.MBeanInstantiator;
import com.sun.jmx.mbeanserver.Repository;
import com.sun.jmx.mbeanserver.NamedObject;
import com.sun.jmx.mbeanserver.Introspector;
import com.sun.jmx.mbeanserver.MBeanInjector;
import com.sun.jmx.mbeanserver.NotifySupport;
import com.sun.jmx.mbeanserver.Repository.RegistrationContext;
import com.sun.jmx.mbeanserver.Util;
import com.sun.jmx.remote.util.EnvHelp;
import javax.management.DynamicWrapperMBean;
import javax.management.NotificationBroadcasterSupport;
import javax.management.namespace.JMXNamespace;
/**
* This is the default class for MBean manipulation on the agent side. It
@ -113,7 +115,8 @@ import javax.management.NotificationBroadcasterSupport;
*
* @since 1.5
*/
public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
public class DefaultMBeanServerInterceptor
extends MBeanServerInterceptorSupport {
/** The MBeanInstantiator object used by the
* DefaultMBeanServerInterceptor */
@ -123,7 +126,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
* DefaultMBeanServerInterceptor */
private transient MBeanServer server = null;
/** The MBean server object taht associated to the
/** The MBean server delegate object that is associated to the
* DefaultMBeanServerInterceptor */
private final transient MBeanServerDelegate delegate;
@ -138,13 +141,15 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
new WeakHashMap<ListenerWrapper,
WeakReference<ListenerWrapper>>();
private final NamespaceDispatchInterceptor dispatcher;
/** The default domain of the object names */
private final String domain;
/** True if the repository perform queries, false otherwise */
private boolean queryByRepo;
/** The mbeanServerName */
private final String mbeanServerName;
/** The sequence number identifyng the notifications sent */
/** The sequence number identifying the notifications sent */
// Now sequence number is handled by MBeanServerDelegate.
// private int sequenceNumber=0;
@ -162,11 +167,13 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
* @param instantiator The MBeanInstantiator that will be used to
* instantiate MBeans and take care of class loading issues.
* @param repository The repository to use for this MBeanServer.
* @param dispatcher The dispatcher used by this MBeanServer
*/
public DefaultMBeanServerInterceptor(MBeanServer outer,
MBeanServerDelegate delegate,
MBeanInstantiator instantiator,
Repository repository) {
Repository repository,
NamespaceDispatchInterceptor dispatcher) {
if (outer == null) throw new
IllegalArgumentException("outer MBeanServer cannot be null");
if (delegate == null) throw new
@ -181,6 +188,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
this.instantiator = instantiator;
this.repository = repository;
this.domain = repository.getDefaultDomain();
this.dispatcher = dispatcher;
this.mbeanServerName = Util.getMBeanServerSecurityName(delegate);
}
public ObjectInstance createMBean(String className, ObjectName name)
@ -259,8 +268,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
name = nonDefaultDomain(name);
}
checkMBeanPermission(className, null, null, "instantiate");
checkMBeanPermission(className, null, name, "registerMBean");
checkMBeanPermission(mbeanServerName,className, null, null, "instantiate");
checkMBeanPermission(mbeanServerName,className, null, name, "registerMBean");
/* Load the appropriate class. */
if (withDefaultLoaderRepository) {
@ -324,7 +333,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
final String infoClassName = getNewMBeanClassName(object);
checkMBeanPermission(infoClassName, null, name, "registerMBean");
checkMBeanPermission(mbeanServerName,infoClassName, null, name, "registerMBean");
checkMBeanTrustPermission(theClass);
return registerObject(infoClassName, object, name);
@ -433,7 +442,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
DynamicMBean instance = getMBean(name);
// may throw InstanceNotFoundException
checkMBeanPermission(instance, null, name, "unregisterMBean");
checkMBeanPermission(mbeanServerName, instance, null, name,
"unregisterMBean");
if (instance instanceof MBeanRegistration)
preDeregisterInvoke((MBeanRegistration) instance);
@ -467,7 +477,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
name = nonDefaultDomain(name);
DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, null, name, "getObjectInstance");
checkMBeanPermission(mbeanServerName,
instance, null, name, "getObjectInstance");
final String className = getClassName(instance);
@ -479,7 +490,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
if (sm != null) {
// Check if the caller has the right to invoke 'queryMBeans'
//
checkMBeanPermission((String) null, null, null, "queryMBeans");
checkMBeanPermission(mbeanServerName,(String) null, null, null, "queryMBeans");
// Perform query without "query".
//
@ -492,7 +503,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
new HashSet<ObjectInstance>(list.size());
for (ObjectInstance oi : list) {
try {
checkMBeanPermission(oi.getClassName(), null,
checkMBeanPermission(mbeanServerName,oi.getClassName(), null,
oi.getObjectName(), "queryMBeans");
allowedList.add(oi);
} catch (SecurityException e) {
@ -516,11 +527,6 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
//
Set<NamedObject> list = repository.query(name, query);
if (queryByRepo) {
// The repository performs the filtering
query = null;
}
return (objectInstancesFromFilteredNamedObjects(list, query));
}
@ -530,7 +536,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
if (sm != null) {
// Check if the caller has the right to invoke 'queryNames'
//
checkMBeanPermission((String) null, null, null, "queryNames");
checkMBeanPermission(mbeanServerName,(String) null, null, null, "queryNames");
// Perform query without "query".
//
@ -543,7 +549,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
new HashSet<ObjectInstance>(list.size());
for (ObjectInstance oi : list) {
try {
checkMBeanPermission(oi.getClassName(), null,
checkMBeanPermission(mbeanServerName, oi.getClassName(), null,
oi.getObjectName(), "queryNames");
allowedList.add(oi);
} catch (SecurityException e) {
@ -572,11 +578,6 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
//
Set<NamedObject> list = repository.query(name, query);
if (queryByRepo) {
// The repository performs the filtering
query = null;
}
return (objectNamesFromFilteredNamedObjects(list, query));
}
@ -589,8 +590,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
name = nonDefaultDomain(name);
// /* Permission check */
// checkMBeanPermission(null, null, name, "isRegistered");
/* No Permission check */
// isRegistered is always unchecked as per JMX spec.
return (repository.contains(name));
}
@ -600,7 +601,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
if (sm != null) {
// Check if the caller has the right to invoke 'getDomains'
//
checkMBeanPermission((String) null, null, null, "getDomains");
checkMBeanPermission(mbeanServerName, (String) null, null, null, "getDomains");
// Return domains
//
@ -612,8 +613,9 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
List<String> result = new ArrayList<String>(domains.length);
for (int i = 0; i < domains.length; i++) {
try {
ObjectName domain = Util.newObjectName(domains[i] + ":x=x");
checkMBeanPermission((String) null, null, domain, "getDomains");
ObjectName dom =
Util.newObjectName(domains[i] + ":x=x");
checkMBeanPermission(mbeanServerName, (String) null, null, dom, "getDomains");
result.add(domains[i]);
} catch (SecurityException e) {
// OK: Do not add this domain to the list
@ -657,7 +659,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
}
final DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, attribute, name, "getAttribute");
checkMBeanPermission(mbeanServerName, instance, attribute,
name, "getAttribute");
try {
return instance.getAttribute(attribute);
@ -702,7 +705,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
// Check if the caller has the right to invoke 'getAttribute'
//
checkMBeanPermission(classname, null, name, "getAttribute");
checkMBeanPermission(mbeanServerName, classname, null, name, "getAttribute");
// Check if the caller has the right to invoke 'getAttribute'
// on each specific attribute
@ -711,14 +714,15 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
new ArrayList<String>(attributes.length);
for (String attr : attributes) {
try {
checkMBeanPermission(classname, attr,
checkMBeanPermission(mbeanServerName, classname, attr,
name, "getAttribute");
allowedList.add(attr);
} catch (SecurityException e) {
// OK: Do not add this attribute to the list
}
}
allowedAttributes = allowedList.toArray(new String[0]);
allowedAttributes =
allowedList.toArray(new String[allowedList.size()]);
}
try {
@ -756,7 +760,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
}
DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, attribute.getName(),
checkMBeanPermission(mbeanServerName, instance, attribute.getName(),
name, "setAttribute");
try {
@ -799,7 +803,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
// Check if the caller has the right to invoke 'setAttribute'
//
checkMBeanPermission(classname, null, name, "setAttribute");
checkMBeanPermission(mbeanServerName, classname, null, name, "setAttribute");
// Check if the caller has the right to invoke 'setAttribute'
// on each specific attribute
@ -808,7 +812,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
for (Iterator i = attributes.iterator(); i.hasNext();) {
try {
Attribute attribute = (Attribute) i.next();
checkMBeanPermission(classname, attribute.getName(),
checkMBeanPermission(mbeanServerName, classname, attribute.getName(),
name, "setAttribute");
allowedAttributes.add(attribute);
} catch (SecurityException e) {
@ -832,7 +836,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
name = nonDefaultDomain(name);
DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, operationName, name, "invoke");
checkMBeanPermission(mbeanServerName, instance, operationName,
name, "invoke");
try {
return instance.invoke(operationName, params, signature);
} catch (Throwable t) {
@ -934,8 +939,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
"registerMBean", "ObjectName = " + name);
}
ObjectName logicalName = name;
logicalName = preRegister(mbean, server, name);
ObjectName logicalName = preRegister(mbean, server, name);
// preRegister returned successfully, so from this point on we
// must call postRegister(false) if there is any problem.
@ -961,16 +965,17 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
if (logicalName != name && logicalName != null) {
logicalName =
ObjectName.getInstance(nonDefaultDomain(logicalName));
ObjectName.getInstance(nonDefaultDomain(logicalName));
}
checkMBeanPermission(classname, null, logicalName, "registerMBean");
checkMBeanPermission(mbeanServerName, classname, null, logicalName,
"registerMBean");
if (logicalName == null) {
final RuntimeException wrapped =
new IllegalArgumentException("No object name specified");
new IllegalArgumentException("No object name specified");
throw new RuntimeOperationsException(wrapped,
"Exception occurred trying to register the MBean");
"Exception occurred trying to register the MBean");
}
final Object resource = getResource(mbean);
@ -987,13 +992,15 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
//
context = registerWithRepository(resource, mbean, logicalName);
registerFailed = false;
registered = true;
} finally {
try {
postRegister(logicalName, mbean, registered, registerFailed);
} finally {
if (registered) context.done();
if (registered && context!=null) context.done();
}
}
return new ObjectInstance(logicalName, classname);
@ -1001,20 +1008,19 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
private static void throwMBeanRegistrationException(Throwable t, String where)
throws MBeanRegistrationException {
try {
throw t;
} catch (RuntimeException e) {
throw new RuntimeMBeanException(
e, "RuntimeException thrown " + where);
} catch (Error er) {
throw new RuntimeErrorException(er, "Error thrown " + where);
} catch (MBeanRegistrationException r) {
throw r;
} catch (Exception ex) {
throw new MBeanRegistrationException(ex, "Exception thrown " + where);
} catch (Throwable t1) {
throw new RuntimeException(t); // neither Error nor Exception??
}
if (t instanceof RuntimeException) {
throw new RuntimeMBeanException((RuntimeException)t,
"RuntimeException thrown " + where);
} else if (t instanceof Error) {
throw new RuntimeErrorException((Error)t,
"Error thrown " + where);
} else if (t instanceof MBeanRegistrationException) {
throw (MBeanRegistrationException)t;
} else if (t instanceof Exception) {
throw new MBeanRegistrationException((Exception)t,
"Exception thrown " + where);
} else // neither Error nor Exception??
throw new RuntimeException(t);
}
private static ObjectName preRegister(
@ -1230,7 +1236,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
}
DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, null, name, "addNotificationListener");
checkMBeanPermission(mbeanServerName, instance, null,
name, "addNotificationListener");
NotificationBroadcaster broadcaster =
getNotificationBroadcaster(name, instance,
@ -1367,7 +1374,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
}
DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, null, name,
checkMBeanPermission(mbeanServerName, instance, null, name,
"removeNotificationListener");
/* We could simplify the code by assigning broadcaster after
@ -1438,7 +1445,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
throw new JMRuntimeException("MBean " + name +
"has no MBeanInfo");
checkMBeanPermission(mbi.getClassName(), null, name, "getMBeanInfo");
checkMBeanPermission(mbeanServerName, mbi.getClassName(), null, name, "getMBeanInfo");
return mbi;
}
@ -1446,8 +1453,9 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
public boolean isInstanceOf(ObjectName name, String className)
throws InstanceNotFoundException {
DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, null, name, "isInstanceOf");
final DynamicMBean instance = getMBean(name);
checkMBeanPermission(mbeanServerName,
instance, null, name, "isInstanceOf");
try {
Object resource = getResource(instance);
@ -1498,7 +1506,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
throws InstanceNotFoundException {
DynamicMBean instance = getMBean(mbeanName);
checkMBeanPermission(instance, null, mbeanName, "getClassLoaderFor");
checkMBeanPermission(mbeanServerName, instance, null, mbeanName,
"getClassLoaderFor");
return getResourceLoader(instance);
}
@ -1513,12 +1522,13 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
throws InstanceNotFoundException {
if (loaderName == null) {
checkMBeanPermission((String) null, null, null, "getClassLoader");
checkMBeanPermission(mbeanServerName, (String) null, null, null, "getClassLoader");
return server.getClass().getClassLoader();
}
DynamicMBean instance = getMBean(loaderName);
checkMBeanPermission(instance, null, loaderName, "getClassLoader");
checkMBeanPermission(mbeanServerName, instance, null, loaderName,
"getClassLoader");
Object resource = getResource(instance);
@ -1568,7 +1578,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
}
} else {
// Access the filter
MBeanServer oldServer = QueryEval.getMBeanServer();
final MBeanServer oldServer = QueryEval.getMBeanServer();
query.setMBeanServer(server);
try {
for (NamedObject no : list) {
@ -1817,26 +1827,30 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
return mbean.getMBeanInfo().getClassName();
}
private static void checkMBeanPermission(DynamicMBean mbean,
private static void checkMBeanPermission(String mbeanServerName,
DynamicMBean mbean,
String member,
ObjectName objectName,
String actions) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMBeanPermission(safeGetClassName(mbean),
checkMBeanPermission(mbeanServerName,
safeGetClassName(mbean),
member,
objectName,
actions);
}
}
private static void checkMBeanPermission(String classname,
private static void checkMBeanPermission(String mbeanServerName,
String classname,
String member,
ObjectName objectName,
String actions) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
Permission perm = new MBeanPermission(classname,
Permission perm = new MBeanPermission(mbeanServerName,
classname,
member,
objectName,
actions);
@ -1902,6 +1916,12 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
throws InstanceAlreadyExistsException,
MBeanRegistrationException {
// this will throw an exception if the pair (resource, logicalName)
// violates namespace conventions - for instance, if logicalName
// ends with // but resource is not a JMXNamespace.
//
checkResourceObjectNameConstraints(resource, logicalName);
// Creates a registration context, if needed.
//
final ResourceContext context =
@ -1967,6 +1987,57 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
return context;
}
/**
* Checks that the ObjectName is legal with regards to the
* type of the MBean resource.
* If the MBean name is domain:type=JMXDomain, the
* MBean must be a JMXDomain.
* If the MBean name is namespace//:type=JMXNamespace, the
* MBean must be a JMXNamespace.
* If the MBean is a JMXDomain, its name
* must be domain:type=JMXDomain.
* If the MBean is a JMXNamespace, its name
* must be namespace//:type=JMXNamespace.
*/
private void checkResourceObjectNameConstraints(Object resource,
ObjectName logicalName)
throws MBeanRegistrationException {
try {
dispatcher.checkLocallyRegistrable(resource, logicalName);
} catch (Throwable x) {
DefaultMBeanServerInterceptor.throwMBeanRegistrationException(x, "validating ObjectName");
}
}
/**
* Registers a JMXNamespace with the dispatcher.
* This method is called by the ResourceContext from within the
* repository lock.
* @param namespace The JMXNamespace
* @param logicalName The JMXNamespaceMBean ObjectName
* @param postQueue A queue that will be processed after postRegister.
*/
private void addJMXNamespace(JMXNamespace namespace,
final ObjectName logicalName,
final Queue<Runnable> postQueue) {
dispatcher.addNamespace(logicalName, namespace, postQueue);
}
/**
* Unregisters a JMXNamespace from the dispatcher.
* This method is called by the ResourceContext from within the
* repository lock.
* @param namespace The JMXNamespace
* @param logicalName The JMXNamespaceMBean ObjectName
* @param postQueue A queue that will be processed after postDeregister.
*/
private void removeJMXNamespace(JMXNamespace namespace,
final ObjectName logicalName,
final Queue<Runnable> postQueue) {
dispatcher.removeNamespace(logicalName, namespace, postQueue);
}
/**
* Registers a ClassLoader with the CLR.
* This method is called by the ResourceContext from within the
@ -2020,6 +2091,52 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
}
}
/**
* Creates a ResourceContext for a JMXNamespace MBean.
* The resource context makes it possible to add the JMXNamespace to
* (ResourceContext.registering) or resp. remove the JMXNamespace from
* (ResourceContext.unregistered) the NamespaceDispatchInterceptor
* when the associated MBean is added to or resp. removed from the
* repository.
* Note: JMXDomains are special sub classes of JMXNamespaces and
* are also handled by this object.
*
* @param namespace The JMXNamespace MBean being registered or
* unregistered.
* @param logicalName The name of the JMXNamespace MBean.
* @return a ResourceContext that takes in charge the addition or removal
* of the namespace to or from the NamespaceDispatchInterceptor.
*/
private ResourceContext createJMXNamespaceContext(
final JMXNamespace namespace,
final ObjectName logicalName) {
final Queue<Runnable> doneTaskQueue = new LinkedList<Runnable>();
return new ResourceContext() {
public void registering() {
addJMXNamespace(namespace, logicalName, doneTaskQueue);
}
public void unregistered() {
removeJMXNamespace(namespace, logicalName,
doneTaskQueue);
}
public void done() {
for (Runnable r : doneTaskQueue) {
try {
r.run();
} catch (RuntimeException x) {
MBEANSERVER_LOGGER.log(Level.FINE,
"Failed to process post queue for "+
logicalName, x);
}
}
}
};
}
/**
* Creates a ResourceContext for a ClassLoader MBean.
* The resource context makes it possible to add the ClassLoader to
@ -2065,10 +2182,16 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
*/
private ResourceContext makeResourceContextFor(Object resource,
ObjectName logicalName) {
if (resource instanceof JMXNamespace) {
return createJMXNamespaceContext((JMXNamespace) resource,
logicalName);
}
if (resource instanceof ClassLoader) {
return createClassLoaderContext((ClassLoader) resource,
logicalName);
}
return ResourceContext.NONE;
}
}

View File

@ -0,0 +1,547 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.interceptor;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.ReflectionException;
import javax.management.namespace.JMXNamespace;
/**
* A dispatcher that dispatches to MBeanServers.
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
//
// This is the base class for implementing dispatchers. We have two concrete
// dispatcher implementations:
//
// * A NamespaceDispatchInterceptor, which dispatch calls to existing
// namespace interceptors
// * A DomainDispatchInterceptor, which dispatch calls to existing domain
// interceptors.
//
// With the JMX Namespaces feature, the JMX MBeanServer is now structured
// as follows:
//
// The JMX MBeanServer delegates to a NamespaceDispatchInterceptor,
// which either dispatches to a namespace, or delegates to the
// DomainDispatchInterceptor (if the object name contained no namespace).
// The DomainDispatchInterceptor in turn either dispatches to a domain (if
// there is a JMXDomain for that domain) or delegates to the
// DefaultMBeanServerInterceptor (if there is no JMXDomain for that
// domain). This makes the following picture:
//
// JMX MBeanServer (outer shell)
// |
// |
// NamespaceDispatchInterceptor
// / \
// no namespace in object name? \
// / \
// / dispatch to namespace
// DomainDispatchInterceptor
// / \
// no JMXDomain for domain? \
// / \
// / dispatch to domain
// DefaultMBeanServerInterceptor
// /
// invoke locally registered MBean
//
// The logic for maintaining a map of interceptors
// and dispatching to impacted interceptor, is implemented in this
// base class, which both NamespaceDispatchInterceptor and
// DomainDispatchInterceptor extend.
//
public abstract class DispatchInterceptor
<T extends MBeanServer, N extends JMXNamespace>
extends MBeanServerInterceptorSupport {
/**
* This is an abstraction which allows us to handle queryNames
* and queryMBeans with the same algorithm. There are some subclasses
* where we need to override both queryNames & queryMBeans to apply
* the same transformation (usually aggregation of results when
* several namespaces/domains are impacted) to both algorithms.
* Usually the only thing that varies between the algorithm of
* queryNames & the algorithm of queryMBean is the type of objects
* in the returned Set. By using a QueryInvoker we can implement the
* transformation only once and apply it to both queryNames &
* queryMBeans.
* @see QueryInterceptor below, and its subclass in
* {@link DomainDispatcher}.
**/
static abstract class QueryInvoker<T> {
abstract Set<T> query(MBeanServer mbs,
ObjectName pattern, QueryExp query);
}
/**
* Used to perform queryNames. A QueryInvoker that invokes
* queryNames on an MBeanServer.
**/
final static QueryInvoker<ObjectName> queryNamesInvoker =
new QueryInvoker<ObjectName>() {
Set<ObjectName> query(MBeanServer mbs,
ObjectName pattern, QueryExp query) {
return mbs.queryNames(pattern,query);
}
};
/**
* Used to perform queryMBeans. A QueryInvoker that invokes
* queryMBeans on an MBeanServer.
**/
final static QueryInvoker<ObjectInstance> queryMBeansInvoker =
new QueryInvoker<ObjectInstance>() {
Set<ObjectInstance> query(MBeanServer mbs,
ObjectName pattern, QueryExp query) {
return mbs.queryMBeans(pattern,query);
}
};
/**
* We use this class to intercept queries.
* There's a special case for JMXNamespace MBeans, because
* "namespace//*:*" matches both "namespace//domain:k=v" and
* "namespace//:type=JMXNamespace".
* Therefore, queries may need to be forwarded to more than
* on interceptor and the results aggregated...
*/
static class QueryInterceptor {
final MBeanServer wrapped;
QueryInterceptor(MBeanServer mbs) {
wrapped = mbs;
}
<X> Set<X> query(ObjectName pattern, QueryExp query,
QueryInvoker<X> invoker, MBeanServer server) {
return invoker.query(server, pattern, query);
}
public Set<ObjectName> queryNames(ObjectName pattern, QueryExp query) {
return query(pattern,query,queryNamesInvoker,wrapped);
}
public Set<ObjectInstance> queryMBeans(ObjectName pattern,
QueryExp query) {
return query(pattern,query,queryMBeansInvoker,wrapped);
}
}
// We don't need a ConcurrentHashMap here because getkeys() returns
// an array of keys. Therefore there's no risk to have a
// ConcurrentModificationException. We must however take into
// account the fact that there can be no interceptor for
// some of the returned keys if the map is being modified by
// another thread, or by a callback within the same thread...
// See getKeys() in this class and query() in DomainDispatcher.
//
private final Map<String,T> handlerMap =
Collections.synchronizedMap(
new HashMap<String,T>());
// The key at which an interceptor for accessing the named MBean can be
// found in the handlerMap. Note: there doesn't need to be an interceptor
// for that key in the Map.
//
public abstract String getHandlerKey(ObjectName name);
// Returns an interceptor for that name, or null if there's no interceptor
// for that name.
abstract MBeanServer getInterceptorOrNullFor(ObjectName name);
// Returns a QueryInterceptor for that pattern.
abstract QueryInterceptor getInterceptorForQuery(ObjectName pattern);
// Returns the ObjectName of the JMXNamespace (or JMXDomain) for that
// key (a namespace or a domain name).
abstract ObjectName getHandlerNameFor(String key)
throws MalformedObjectNameException;
// Creates an interceptor for the given key, name, JMXNamespace (or
// JMXDomain). Note: this will be either a NamespaceInterceptor
// wrapping a JMXNamespace, if this object is an instance of
// NamespaceDispatchInterceptor, or a DomainInterceptor wrapping a
// JMXDomain, if this object is an instance of DomainDispatchInterceptor.
abstract T createInterceptorFor(String key, ObjectName name,
N jmxNamespace, Queue<Runnable> postRegisterQueue);
//
// The next interceptor in the chain.
//
// For the NamespaceDispatchInterceptor, this the DomainDispatchInterceptor.
// For the DomainDispatchInterceptor, this is the
// DefaultMBeanServerInterceptor.
//
// The logic of when to invoke the next interceptor in the chain depends
// on the logic of the concrete dispatcher class.
//
// For instance, the NamespaceDispatchInterceptor invokes the next
// interceptor when the object name doesn't contain any namespace.
//
// On the other hand, the DomainDispatchInterceptor invokes the
// next interceptor when there's no interceptor for the accessed domain.
//
abstract MBeanServer getNextInterceptor();
// hook for cleanup in subclasses.
void interceptorReleased(T interceptor,
Queue<Runnable> postDeregisterQueue) {
// hook
}
// Hook for subclasses.
MBeanServer getInterceptorForCreate(ObjectName name)
throws MBeanRegistrationException {
final MBeanServer ns = getInterceptorOrNullFor(name);
if (ns == null) // name cannot be null here.
throw new MBeanRegistrationException(
new IllegalArgumentException("No such MBean handler: " +
getHandlerKey(name) + " for " +name));
return ns;
}
// Hook for subclasses.
MBeanServer getInterceptorForInstance(ObjectName name)
throws InstanceNotFoundException {
final MBeanServer ns = getInterceptorOrNullFor(name);
if (ns == null) // name cannot be null here.
throw new InstanceNotFoundException(String.valueOf(name));
return ns;
}
// sanity checks
void validateHandlerNameFor(String key, ObjectName name) {
if (key == null || key.equals(""))
throw new IllegalArgumentException("invalid key for "+name+": "+key);
try {
final ObjectName handlerName = getHandlerNameFor(key);
if (!name.equals(handlerName))
throw new IllegalArgumentException("bad handler name: "+name+
". Should be: "+handlerName);
} catch (MalformedObjectNameException x) {
throw new IllegalArgumentException(name.toString(),x);
}
}
// Called by the DefaultMBeanServerInterceptor when an instance
// of JMXNamespace (or a subclass of it) is registered as an MBean.
// This method is usually invoked from within the repository lock,
// hence the necessity of the postRegisterQueue.
public void addNamespace(ObjectName name, N jmxNamespace,
Queue<Runnable> postRegisterQueue) {
final String key = getHandlerKey(name);
validateHandlerNameFor(key,name);
synchronized (handlerMap) {
final T exists =
handlerMap.get(key);
if (exists != null)
throw new IllegalArgumentException(key+
": handler already exists");
final T ns = createInterceptorFor(key,name,jmxNamespace,
postRegisterQueue);
handlerMap.put(key,ns);
}
}
// Called by the DefaultMBeanServerInterceptor when an instance
// of JMXNamespace (or a subclass of it) is deregistered.
// This method is usually invoked from within the repository lock,
// hence the necessity of the postDeregisterQueue.
public void removeNamespace(ObjectName name, N jmxNamespace,
Queue<Runnable> postDeregisterQueue) {
final String key = getHandlerKey(name);
final T ns;
synchronized(handlerMap) {
ns = handlerMap.remove(key);
}
interceptorReleased(ns,postDeregisterQueue);
}
// Get the interceptor for that key.
T getInterceptor(String key) {
synchronized (handlerMap) {
return handlerMap.get(key);
}
}
// We return an array of keys, which makes it possible to make
// concurrent modifications of the handlerMap, provided that
// the code which loops over the keys is prepared to handle null
// interceptors.
// See declaration of handlerMap above, and see also query() in
// DomainDispatcher
//
public String[] getKeys() {
synchronized (handlerMap) {
final int size = handlerMap.size();
return handlerMap.keySet().toArray(new String[size]);
}
}
// From MBeanServer
public ObjectInstance createMBean(String className, ObjectName name)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException {
return getInterceptorForCreate(name).createMBean(className,name);
}
// From MBeanServer
public ObjectInstance createMBean(String className, ObjectName name,
ObjectName loaderName)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException{
return getInterceptorForCreate(name).createMBean(className,name,loaderName);
}
// From MBeanServer
public ObjectInstance createMBean(String className, ObjectName name,
Object params[], String signature[])
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException{
return getInterceptorForCreate(name).
createMBean(className,name,params,signature);
}
// From MBeanServer
public ObjectInstance createMBean(String className, ObjectName name,
ObjectName loaderName, Object params[],
String signature[])
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException{
return getInterceptorForCreate(name).createMBean(className,name,loaderName,
params,signature);
}
// From MBeanServer
public ObjectInstance registerMBean(Object object, ObjectName name)
throws InstanceAlreadyExistsException, MBeanRegistrationException,
NotCompliantMBeanException {
return getInterceptorForCreate(name).registerMBean(object,name);
}
// From MBeanServer
public void unregisterMBean(ObjectName name)
throws InstanceNotFoundException, MBeanRegistrationException {
getInterceptorForInstance(name).unregisterMBean(name);
}
// From MBeanServer
public ObjectInstance getObjectInstance(ObjectName name)
throws InstanceNotFoundException {
return getInterceptorForInstance(name).getObjectInstance(name);
}
// From MBeanServer
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
final QueryInterceptor mbs =
getInterceptorForQuery(name);
if (mbs == null) return Collections.emptySet();
else return mbs.queryMBeans(name,query);
}
// From MBeanServer
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
final QueryInterceptor mbs =
getInterceptorForQuery(name);
if (mbs == null) return Collections.emptySet();
else return mbs.queryNames(name,query);
}
// From MBeanServer
public boolean isRegistered(ObjectName name) {
final MBeanServer mbs = getInterceptorOrNullFor(name);
if (mbs == null) return false;
else return mbs.isRegistered(name);
}
// From MBeanServer
public Integer getMBeanCount() {
return getNextInterceptor().getMBeanCount();
}
// From MBeanServer
public Object getAttribute(ObjectName name, String attribute)
throws MBeanException, AttributeNotFoundException,
InstanceNotFoundException, ReflectionException {
return getInterceptorForInstance(name).getAttribute(name,attribute);
}
// From MBeanServer
public AttributeList getAttributes(ObjectName name, String[] attributes)
throws InstanceNotFoundException, ReflectionException {
return getInterceptorForInstance(name).getAttributes(name,attributes);
}
// From MBeanServer
public void setAttribute(ObjectName name, Attribute attribute)
throws InstanceNotFoundException, AttributeNotFoundException,
InvalidAttributeValueException, MBeanException,
ReflectionException {
getInterceptorForInstance(name).setAttribute(name,attribute);
}
// From MBeanServer
public AttributeList setAttributes(ObjectName name,
AttributeList attributes)
throws InstanceNotFoundException, ReflectionException {
return getInterceptorForInstance(name).setAttributes(name,attributes);
}
// From MBeanServer
public Object invoke(ObjectName name, String operationName,
Object params[], String signature[])
throws InstanceNotFoundException, MBeanException,
ReflectionException {
return getInterceptorForInstance(name).invoke(name,operationName,params,
signature);
}
// From MBeanServer
public String getDefaultDomain() {
return getNextInterceptor().getDefaultDomain();
}
/**
* Returns the list of domains in which any MBean is currently
* registered.
*/
public abstract String[] getDomains();
// From MBeanServer
public void addNotificationListener(ObjectName name,
NotificationListener listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException {
getInterceptorForInstance(name).addNotificationListener(name,listener,filter,
handback);
}
// From MBeanServer
public void addNotificationListener(ObjectName name,
ObjectName listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException {
getInterceptorForInstance(name).addNotificationListener(name,listener,filter,
handback);
}
// From MBeanServer
public void removeNotificationListener(ObjectName name,
ObjectName listener)
throws InstanceNotFoundException, ListenerNotFoundException {
getInterceptorForInstance(name).removeNotificationListener(name,listener);
}
// From MBeanServer
public void removeNotificationListener(ObjectName name,
ObjectName listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException, ListenerNotFoundException {
getInterceptorForInstance(name).removeNotificationListener(name,listener,filter,
handback);
}
// From MBeanServer
public void removeNotificationListener(ObjectName name,
NotificationListener listener)
throws InstanceNotFoundException, ListenerNotFoundException {
getInterceptorForInstance(name).removeNotificationListener(name,listener);
}
// From MBeanServer
public void removeNotificationListener(ObjectName name,
NotificationListener listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException, ListenerNotFoundException {
getInterceptorForInstance(name).removeNotificationListener(name,listener,filter,
handback);
}
// From MBeanServer
public MBeanInfo getMBeanInfo(ObjectName name)
throws InstanceNotFoundException, IntrospectionException,
ReflectionException {
return getInterceptorForInstance(name).getMBeanInfo(name);
}
// From MBeanServer
public boolean isInstanceOf(ObjectName name, String className)
throws InstanceNotFoundException {
return getInterceptorForInstance(name).isInstanceOf(name,className);
}
// From MBeanServer
public ClassLoader getClassLoaderFor(ObjectName mbeanName)
throws InstanceNotFoundException {
return getInterceptorForInstance(mbeanName).getClassLoaderFor(mbeanName);
}
// From MBeanServer
public ClassLoader getClassLoader(ObjectName loaderName)
throws InstanceNotFoundException {
return getInterceptorForInstance(loaderName).getClassLoader(loaderName);
}
}

View File

@ -0,0 +1,322 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.interceptor;
import com.sun.jmx.defaults.JmxProperties;
import com.sun.jmx.mbeanserver.MBeanInstantiator;
import com.sun.jmx.mbeanserver.Repository;
import com.sun.jmx.mbeanserver.Util;
import com.sun.jmx.namespace.DomainInterceptor;
import java.util.Queue;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.namespace.JMXDomain;
import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
/**
* A dispatcher that dispatch incoming MBeanServer requests to
* DomainInterceptors.
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
//
// See comments in DispatchInterceptor.
//
class DomainDispatchInterceptor
extends DispatchInterceptor<DomainInterceptor, JMXDomain> {
/**
* A logger for this class.
**/
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
private static final ObjectName ALL_DOMAINS =
JMXDomain.getDomainObjectName("*");
/**
* A QueryInterceptor that perform & aggregates queries spanning several
* domains.
*/
final static class AggregatingQueryInterceptor extends QueryInterceptor {
private final DomainDispatchInterceptor parent;
AggregatingQueryInterceptor(DomainDispatchInterceptor dispatcher) {
super(dispatcher.localNamespace);
parent = dispatcher;
}
/**
* Perform queryNames or queryMBeans, depending on which QueryInvoker
* is passed as argument. This is closures without closures.
**/
@Override
<T> Set<T> query(ObjectName pattern, QueryExp query,
QueryInvoker<T> invoker, MBeanServer localNamespace) {
final Set<T> local = invoker.query(localNamespace, pattern, query);
// Add all matching MBeans from local namespace.
final Set<T> res = Util.cloneSet(local);
final boolean all = (pattern == null ||
pattern.getDomain().equals("*"));
if (pattern == null) pattern = ObjectName.WILDCARD;
final String domain = pattern.getDomain();
// If there's no domain pattern, just include the pattern's domain.
// Otherwiae, loop over all virtual domains (parent.getKeys()).
final String[] keys =
(pattern.isDomainPattern() ?
parent.getKeys() : new String[]{domain});
// Add all matching MBeans from each virtual domain
//
for (String key : keys) {
// Only invoke those virtual domain which are selected
// by the domain pattern
//
if (!all && !Util.isDomainSelected(key, domain))
continue;
try {
final MBeanServer mbs = parent.getInterceptor(key);
// mbs can be null if the interceptor was removed
// concurrently...
// See handlerMap and getKeys() in DispatchInterceptor
//
if (mbs == null) continue;
// If the domain is selected, we can replace the pattern
// by the actual domain. This is safer if we want to avoid
// a domain (which could be backed up by an MBeanServer) to
// return names from outside the domain.
// So instead of asking the domain handler for "foo" to
// return all names which match "?o*:type=Bla,*" we're
// going to ask it to return all names which match
// "foo:type=Bla,*"
//
final ObjectName subPattern = pattern.withDomain(key);
res.addAll(invoker.query(mbs, subPattern, query));
} catch (Exception x) {
LOG.finest("Ignoring exception " +
"when attempting to query namespace "+key+": "+x);
continue;
}
}
return res;
}
}
private final DefaultMBeanServerInterceptor localNamespace;
private final String mbeanServerName;
private final MBeanServerDelegate delegate;
/**
* Creates a DomainDispatchInterceptor with the specified
* repository instance.
*
* @param outer A pointer to the MBeanServer object that must be
* passed to the MBeans when invoking their
* {@link javax.management.MBeanRegistration} interface.
* @param delegate A pointer to the MBeanServerDelegate associated
* with the new MBeanServer. The new MBeanServer must register
* this MBean in its MBean repository.
* @param instantiator The MBeanInstantiator that will be used to
* instantiate MBeans and take care of class loading issues.
* @param repository The repository to use for this MBeanServer
*/
public DomainDispatchInterceptor(MBeanServer outer,
MBeanServerDelegate delegate,
MBeanInstantiator instantiator,
Repository repository,
NamespaceDispatchInterceptor namespaces) {
localNamespace = new DefaultMBeanServerInterceptor(outer,
delegate, instantiator,repository,namespaces);
mbeanServerName = Util.getMBeanServerSecurityName(delegate);
this.delegate = delegate;
}
final boolean isLocalHandlerNameFor(String domain,
ObjectName handlerName) {
if (domain == null) return true;
return handlerName.getDomain().equals(domain) &&
JMXDomain.TYPE_ASSIGNMENT.equals(
handlerName.getKeyPropertyListString());
}
@Override
void validateHandlerNameFor(String key, ObjectName name) {
super.validateHandlerNameFor(key,name);
final String[] domains = localNamespace.getDomains();
for (int i=0;i<domains.length;i++) {
if (domains[i].equals(key))
throw new IllegalArgumentException("domain "+key+
" is not empty");
}
}
@Override
final MBeanServer getInterceptorOrNullFor(ObjectName name) {
if (name == null) return localNamespace;
final String domain = name.getDomain();
if (domain.endsWith(NAMESPACE_SEPARATOR)) return localNamespace;
if (domain.contains(NAMESPACE_SEPARATOR)) return null;
final String localDomain = domain;
if (isLocalHandlerNameFor(localDomain,name)) {
LOG.finer("dispatching to local namespace");
return localNamespace;
}
final DomainInterceptor ns = getInterceptor(localDomain);
if (ns == null) {
if (LOG.isLoggable(Level.FINER)) {
LOG.finer("dispatching to local namespace: " + localDomain);
}
return getNextInterceptor();
}
if (LOG.isLoggable(Level.FINER)) {
LOG.finer("dispatching to domain: " + localDomain);
}
return ns;
}
private boolean multipleQuery(ObjectName pattern) {
if (pattern == null) return true;
if (pattern.isDomainPattern()) return true;
try {
// This is a bit of a hack. If there's any chance that a JMXDomain
// MBean name is selected by the given pattern then we must include
// the local namespace in our search.
// Returning true will have this effect.
if (pattern.apply(ALL_DOMAINS.withDomain(pattern.getDomain())))
return true;
} catch (MalformedObjectNameException x) {
// should not happen
throw new IllegalArgumentException(String.valueOf(pattern), x);
}
return false;
}
@Override
final QueryInterceptor getInterceptorForQuery(ObjectName pattern) {
// Check if we need to aggregate.
if (multipleQuery(pattern))
return new AggregatingQueryInterceptor(this);
// We don't need to aggregate: do the "simple" thing...
final String domain = pattern.getDomain();
// Do we have a virtual domain?
final DomainInterceptor ns = getInterceptor(domain);
if (ns != null) {
if (LOG.isLoggable(Level.FINER))
LOG.finer("dispatching to domain: " + domain);
return new QueryInterceptor(ns);
}
// We don't have a virtual domain. Send to local domains.
if (LOG.isLoggable(Level.FINER))
LOG.finer("dispatching to local namespace: " + domain);
return new QueryInterceptor(localNamespace);
}
@Override
final ObjectName getHandlerNameFor(String key)
throws MalformedObjectNameException {
return JMXDomain.getDomainObjectName(key);
}
@Override
final public String getHandlerKey(ObjectName name) {
return name.getDomain();
}
@Override
final DomainInterceptor createInterceptorFor(String key,
ObjectName name, JMXDomain handler,
Queue<Runnable> postRegisterQueue) {
final DomainInterceptor ns =
new DomainInterceptor(mbeanServerName,handler,key);
ns.addPostRegisterTask(postRegisterQueue, delegate);
if (LOG.isLoggable(Level.FINER)) {
LOG.finer("DomainInterceptor created: "+ns);
}
return ns;
}
@Override
final void interceptorReleased(DomainInterceptor interceptor,
Queue<Runnable> postDeregisterQueue) {
interceptor.addPostDeregisterTask(postDeregisterQueue, delegate);
}
@Override
final DefaultMBeanServerInterceptor getNextInterceptor() {
return localNamespace;
}
/**
* Returns the list of domains in which any MBean is currently
* registered.
*/
@Override
public String[] getDomains() {
// A JMXDomain is registered in its own domain.
// Therefore, localNamespace.getDomains() contains all domains.
// In addition, localNamespace will perform the necessary
// MBeanPermission checks for getDomains().
//
return localNamespace.getDomains();
}
/**
* Returns the number of MBeans registered in the MBean server.
*/
@Override
public Integer getMBeanCount() {
int count = getNextInterceptor().getMBeanCount().intValue();
final String[] keys = getKeys();
for (String key:keys) {
final MBeanServer mbs = getInterceptor(key);
if (mbs == null) continue;
count += mbs.getMBeanCount().intValue();
}
return Integer.valueOf(count);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2002-2008 Sun Microsystems, Inc. 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
@ -25,35 +25,14 @@
package com.sun.jmx.interceptor;
import java.util.Set;
// RI import
import javax.management.DynamicMBean;
import javax.management.AttributeNotFoundException;
import javax.management.MBeanException;
import javax.management.ReflectionException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.QueryExp;
import javax.management.NotificationListener;
import javax.management.NotificationFilter;
import javax.management.ListenerNotFoundException;
import javax.management.IntrospectionException;
import javax.management.OperationsException;
import javax.management.MBeanNotificationInfo;
import javax.management.JMRuntimeException;
import java.io.ObjectInputStream;
import javax.management.InstanceNotFoundException;
import javax.management.NotCompliantMBeanException;
import javax.management.MBeanRegistrationException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.ObjectInstance;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.RuntimeOperationsException;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerDelegate;
import javax.management.OperationsException;
import javax.management.ReflectionException;
import javax.management.loading.ClassLoaderRepository;
/**
@ -85,618 +64,67 @@ import javax.management.loading.ClassLoaderRepository;
*
* @since 1.5
*/
public interface MBeanServerInterceptor extends MBeanServerConnection {
public interface MBeanServerInterceptor extends MBeanServer {
/**
* Instantiates and registers an MBean in the MBean server. The
* MBean server will use its {@link
* javax.management.loading.ClassLoaderRepository Default Loader
* Repository} to load the class of the MBean. An object name is
* associated to the MBean. If the object name given is null, the
* MBean must provide its own name by implementing the {@link
* javax.management.MBeanRegistration MBeanRegistration} interface
* and returning the name from the {@link
* javax.management.MBeanRegistration#preRegister preRegister} method.
*
* @param className The class name of the MBean to be instantiated.
* @param name The object name of the MBean. May be null.
* @param params An array containing the parameters of the
* constructor to be invoked.
* @param signature An array containing the signature of the
* constructor to be invoked.
*
* @return An <CODE>ObjectInstance</CODE>, containing the
* <CODE>ObjectName</CODE> and the Java class name of the newly
* instantiated MBean.
*
* @exception ReflectionException Wraps a
* <CODE>java.lang.ClassNotFoundException</CODE> or a
* <CODE>java.lang.Exception</CODE> that occurred when trying to
* invoke the MBean's constructor.
* @exception InstanceAlreadyExistsException The MBean is already
* under the control of the MBean server.
* @exception MBeanRegistrationException The
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
* @exception MBeanException The constructor of the MBean has
* thrown an exception
* @exception RuntimeOperationsException Wraps a
* <CODE>java.lang.IllegalArgumentException</CODE>: The className
* passed in parameter is null, the <CODE>ObjectName</CODE> passed
* in parameter contains a pattern or no <CODE>ObjectName</CODE>
* is specified for the MBean.
* This method should never be called.
* Usually hrows UnsupportedOperationException.
*/
public ObjectInstance createMBean(String className, ObjectName name,
Object params[], String signature[])
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException;
public Object instantiate(String className)
throws ReflectionException, MBeanException;
/**
* This method should never be called.
* Usually throws UnsupportedOperationException.
*/
public Object instantiate(String className, ObjectName loaderName)
throws ReflectionException, MBeanException,
InstanceNotFoundException;
/**
* This method should never be called.
* Usually throws UnsupportedOperationException.
*/
public Object instantiate(String className, Object[] params,
String[] signature) throws ReflectionException, MBeanException;
/**
* Instantiates and registers an MBean in the MBean server. The
* class loader to be used is identified by its object name. An
* object name is associated to the MBean. If the object name of
* the loader is not specified, the ClassLoader that loaded the
* MBean server will be used. If the MBean object name given is
* null, the MBean must provide its own name by implementing the
* {@link javax.management.MBeanRegistration MBeanRegistration}
* interface and returning the name from the {@link
* javax.management.MBeanRegistration#preRegister preRegister} method.
*
* @param className The class name of the MBean to be instantiated.
* @param name The object name of the MBean. May be null.
* @param params An array containing the parameters of the
* constructor to be invoked.
* @param signature An array containing the signature of the
* constructor to be invoked.
* @param loaderName The object name of the class loader to be used.
*
* @return An <CODE>ObjectInstance</CODE>, containing the
* <CODE>ObjectName</CODE> and the Java class name of the newly
* instantiated MBean.
*
* @exception ReflectionException Wraps a
* <CODE>java.lang.ClassNotFoundException</CODE> or a
* <CODE>java.lang.Exception</CODE> that occurred when trying to
* invoke the MBean's constructor.
* @exception InstanceAlreadyExistsException The MBean is already
* under the control of the MBean server.
* @exception MBeanRegistrationException The
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
* @exception MBeanException The constructor of the MBean has
* thrown an exception
* @exception InstanceNotFoundException The specified class loader
* is not registered in the MBean server.
* @exception RuntimeOperationsException Wraps a
* <CODE>java.lang.IllegalArgumentException</CODE>: The className
* passed in parameter is null, the <CODE>ObjectName</CODE> passed
* in parameter contains a pattern or no <CODE>ObjectName</CODE>
* is specified for the MBean.
*
* This method should never be called.
* Usually throws UnsupportedOperationException.
*/
public ObjectInstance createMBean(String className, ObjectName name,
ObjectName loaderName, Object params[],
String signature[])
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException;
public Object instantiate(String className, ObjectName loaderName,
Object[] params, String[] signature)
throws ReflectionException, MBeanException,
InstanceNotFoundException;
/**
* Registers a pre-existing object as an MBean with the MBean
* server. If the object name given is null, the MBean must
* provide its own name by implementing the {@link
* javax.management.MBeanRegistration MBeanRegistration} interface
* and returning the name from the {@link
* javax.management.MBeanRegistration#preRegister preRegister} method.
*
* @param object The MBean to be registered as an MBean.
* @param name The object name of the MBean. May be null.
*
* @return The <CODE>ObjectInstance</CODE> for the MBean that has
* been registered.
*
* @exception InstanceAlreadyExistsException The MBean is already
* under the control of the MBean server.
* @exception MBeanRegistrationException The
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
* @exception NotCompliantMBeanException This object is not a JMX
* compliant MBean
* @exception RuntimeOperationsException Wraps a
* <CODE>java.lang.IllegalArgumentException</CODE>: The object
* passed in parameter is null or no object name is specified.
* This method should never be called.
* Usually throws UnsupportedOperationException.
*/
public ObjectInstance registerMBean(Object object, ObjectName name)
throws InstanceAlreadyExistsException, MBeanRegistrationException,
NotCompliantMBeanException;
@Deprecated
public ObjectInputStream deserialize(ObjectName name, byte[] data)
throws InstanceNotFoundException, OperationsException;
/**
* Unregisters an MBean from the MBean server. The MBean is
* identified by its object name. Once the method has been
* invoked, the MBean may no longer be accessed by its object
* name.
*
* @param name The object name of the MBean to be unregistered.
*
* @exception InstanceNotFoundException The MBean specified is not
* registered in the MBean server.
* @exception MBeanRegistrationException The preDeregister
* ((<CODE>MBeanRegistration</CODE> interface) method of the MBean
* has thrown an exception.
* @exception RuntimeOperationsException Wraps a
* <CODE>java.lang.IllegalArgumentException</CODE>: The object
* name in parameter is null or the MBean you are when trying to
* unregister is the {@link javax.management.MBeanServerDelegate
* MBeanServerDelegate} MBean.
*
* This method should never be called.
* Usually throws UnsupportedOperationException.
*/
public void unregisterMBean(ObjectName name)
throws InstanceNotFoundException, MBeanRegistrationException;
@Deprecated
public ObjectInputStream deserialize(String className, byte[] data)
throws OperationsException, ReflectionException;
/**
* Gets the <CODE>ObjectInstance</CODE> for a given MBean
* registered with the MBean server.
*
* @param name The object name of the MBean.
*
* @return The <CODE>ObjectInstance</CODE> associated to the MBean
* specified by <VAR>name</VAR>.
*
* @exception InstanceNotFoundException The MBean specified is not
* registered in the MBean server.
* This method should never be called.
* Usually hrows UnsupportedOperationException.
*/
public ObjectInstance getObjectInstance(ObjectName name)
throws InstanceNotFoundException;
@Deprecated
public ObjectInputStream deserialize(String className,
ObjectName loaderName, byte[] data)
throws InstanceNotFoundException, OperationsException,
ReflectionException;
/**
* Gets MBeans controlled by the MBean server. This method allows
* any of the following to be obtained: All MBeans, a set of
* MBeans specified by pattern matching on the
* <CODE>ObjectName</CODE> and/or a Query expression, a specific
* MBean. When the object name is null or no domain and key
* properties are specified, all objects are to be selected (and
* filtered if a query is specified). It returns the set of
* <CODE>ObjectInstance</CODE> objects (containing the
* <CODE>ObjectName</CODE> and the Java Class name) for the
* selected MBeans.
*
* @param name The object name pattern identifying the MBeans to
* be retrieved. If null or no domain and key properties are
* specified, all the MBeans registered will be retrieved.
* @param query The query expression to be applied for selecting
* MBeans. If null no query expression will be applied for
* selecting MBeans.
*
* @return A set containing the <CODE>ObjectInstance</CODE>
* objects for the selected MBeans. If no MBean satisfies the
* query an empty list is returned.
* This method should never be called.
* Usually throws UnsupportedOperationException.
*/
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query);
/**
* Gets the names of MBeans controlled by the MBean server. This
* method enables any of the following to be obtained: The names
* of all MBeans, the names of a set of MBeans specified by
* pattern matching on the <CODE>ObjectName</CODE> and/or a Query
* expression, a specific MBean name (equivalent to testing
* whether an MBean is registered). When the object name is null
* or no domain and key properties are specified, all objects are
* selected (and filtered if a query is specified). It returns the
* set of ObjectNames for the MBeans selected.
*
* @param name The object name pattern identifying the MBean names
* to be retrieved. If null oror no domain and key properties are
* specified, the name of all registered MBeans will be retrieved.
* @param query The query expression to be applied for selecting
* MBeans. If null no query expression will be applied for
* selecting MBeans.
*
* @return A set containing the ObjectNames for the MBeans
* selected. If no MBean satisfies the query, an empty list is
* returned.
*/
public Set<ObjectName> queryNames(ObjectName name, QueryExp query);
/**
* Checks whether an MBean, identified by its object name, is
* already registered with the MBean server.
*
* @param name The object name of the MBean to be checked.
*
* @return True if the MBean is already registered in the MBean
* server, false otherwise.
*
* @exception RuntimeOperationsException Wraps a
* <CODE>java.lang.IllegalArgumentException</CODE>: The object
* name in parameter is null.
*/
public boolean isRegistered(ObjectName name);
/**
* Returns the number of MBeans registered in the MBean server.
*/
public Integer getMBeanCount();
/**
* Gets the value of a specific attribute of a named MBean. The MBean
* is identified by its object name.
*
* @param name The object name of the MBean from which the
* attribute is to be retrieved.
* @param attribute A String specifying the name of the attribute
* to be retrieved.
*
* @return The value of the retrieved attribute.
*
* @exception AttributeNotFoundException The attribute specified
* is not accessible in the MBean.
* @exception MBeanException Wraps an exception thrown by the
* MBean's getter.
* @exception InstanceNotFoundException The MBean specified is not
* registered in the MBean server.
* @exception ReflectionException Wraps a
* <CODE>java.lang.Exception</CODE> thrown when trying to invoke
* the setter.
* @exception RuntimeOperationsException Wraps a
* <CODE>java.lang.IllegalArgumentException</CODE>: The object
* name in parameter is null or the attribute in parameter is
* null.
*/
public Object getAttribute(ObjectName name, String attribute)
throws MBeanException, AttributeNotFoundException,
InstanceNotFoundException, ReflectionException;
/**
* Enables the values of several attributes of a named MBean. The MBean
* is identified by its object name.
*
* @param name The object name of the MBean from which the
* attributes are retrieved.
* @param attributes A list of the attributes to be retrieved.
*
* @return The list of the retrieved attributes.
*
* @exception InstanceNotFoundException The MBean specified is not
* registered in the MBean server.
* @exception ReflectionException An exception occurred when
* trying to invoke the getAttributes method of a Dynamic MBean.
* @exception RuntimeOperationsException Wrap a
* <CODE>java.lang.IllegalArgumentException</CODE>: The object
* name in parameter is null or attributes in parameter is null.
*/
public AttributeList getAttributes(ObjectName name, String[] attributes)
throws InstanceNotFoundException, ReflectionException;
/**
* Sets the value of a specific attribute of a named MBean. The MBean
* is identified by its object name.
*
* @param name The name of the MBean within which the attribute is
* to be set.
* @param attribute The identification of the attribute to be set
* and the value it is to be set to.
*
* @exception InstanceNotFoundException The MBean specified is not
* registered in the MBean server.
* @exception AttributeNotFoundException The attribute specified
* is not accessible in the MBean.
* @exception InvalidAttributeValueException The value specified
* for the attribute is not valid.
* @exception MBeanException Wraps an exception thrown by the
* MBean's setter.
* @exception ReflectionException Wraps a
* <CODE>java.lang.Exception</CODE> thrown when trying to invoke
* the setter.
* @exception RuntimeOperationsException Wraps a
* <CODE>java.lang.IllegalArgumentException</CODE>: The object
* name in parameter is null or the attribute in parameter is
* null.
*/
public void setAttribute(ObjectName name, Attribute attribute)
throws InstanceNotFoundException, AttributeNotFoundException,
InvalidAttributeValueException, MBeanException,
ReflectionException;
/**
* Sets the values of several attributes of a named MBean. The MBean is
* identified by its object name.
*
* @param name The object name of the MBean within which the
* attributes are to be set.
* @param attributes A list of attributes: The identification of
* the attributes to be set and the values they are to be set to.
*
* @return The list of attributes that were set, with their new
* values.
*
* @exception InstanceNotFoundException The MBean specified is not
* registered in the MBean server.
* @exception ReflectionException An exception occurred when
* trying to invoke the getAttributes method of a Dynamic MBean.
* @exception RuntimeOperationsException Wraps a
* <CODE>java.lang.IllegalArgumentException</CODE>: The object
* name in parameter is null or attributes in parameter is null.
*/
public AttributeList setAttributes(ObjectName name,
AttributeList attributes)
throws InstanceNotFoundException, ReflectionException;
/**
* Invokes an operation on an MBean.
*
* @param name The object name of the MBean on which the method is
* to be invoked.
* @param operationName The name of the operation to be invoked.
* @param params An array containing the parameters to be set when
* the operation is invoked
* @param signature An array containing the signature of the
* operation. The class objects will be loaded using the same
* class loader as the one used for loading the MBean on which the
* operation was invoked.
*
* @return The object returned by the operation, which represents
* the result ofinvoking the operation on the MBean specified.
*
* @exception InstanceNotFoundException The MBean specified is not
* registered in the MBean server.
* @exception MBeanException Wraps an exception thrown by the
* MBean's invoked method.
* @exception ReflectionException Wraps a
* <CODE>java.lang.Exception</CODE> thrown while trying to invoke
* the method.
*/
public Object invoke(ObjectName name, String operationName,
Object params[], String signature[])
throws InstanceNotFoundException, MBeanException,
ReflectionException;
/**
* Returns the default domain used for naming the MBean.
* The default domain name is used as the domain part in the ObjectName
* of MBeans if no domain is specified by the user.
*/
public String getDefaultDomain();
/**
* Returns the list of domains in which any MBean is currently
* registered.
*/
public String[] getDomains();
/**
* <p>Adds a listener to a registered MBean.</p>
*
* <P> A notification emitted by an MBean will be forwarded by the
* MBeanServer to the listener. If the source of the notification
* is a reference to an MBean object, the MBean server will replace it
* by that MBean's ObjectName. Otherwise the source is unchanged.
*
* @param name The name of the MBean on which the listener should
* be added.
* @param listener The listener object which will handle the
* notifications emitted by the registered MBean.
* @param filter The filter object. If filter is null, no
* filtering will be performed before handling notifications.
* @param handback The context to be sent to the listener when a
* notification is emitted.
*
* @exception InstanceNotFoundException The MBean name provided
* does not match any of the registered MBeans.
*/
public void addNotificationListener(ObjectName name,
NotificationListener listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException;
/**
* <p>Adds a listener to a registered MBean.</p>
*
* <p>A notification emitted by an MBean will be forwarded by the
* MBeanServer to the listener. If the source of the notification
* is a reference to an MBean object, the MBean server will
* replace it by that MBean's ObjectName. Otherwise the source is
* unchanged.</p>
*
* <p>The listener object that receives notifications is the one
* that is registered with the given name at the time this method
* is called. Even if it is subsequently unregistered, it will
* continue to receive notifications.</p>
*
* @param name The name of the MBean on which the listener should
* be added.
* @param listener The object name of the listener which will
* handle the notifications emitted by the registered MBean.
* @param filter The filter object. If filter is null, no
* filtering will be performed before handling notifications.
* @param handback The context to be sent to the listener when a
* notification is emitted.
*
* @exception InstanceNotFoundException The MBean name of the
* notification listener or of the notification broadcaster does
* not match any of the registered MBeans.
* @exception RuntimeOperationsException Wraps an {@link
* IllegalArgumentException}. The MBean named by
* <code>listener</code> exists but does not implement the {@link
* NotificationListener} interface.
* @exception IOException A communication problem occurred when
* talking to the MBean server.
*/
public void addNotificationListener(ObjectName name,
ObjectName listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException;
/**
* Removes a listener from a registered MBean.
*
* <P> If the listener is registered more than once, perhaps with
* different filters or callbacks, this method will remove all
* those registrations.
*
* @param name The name of the MBean on which the listener should
* be removed.
* @param listener The object name of the listener to be removed.
*
* @exception InstanceNotFoundException The MBean name provided
* does not match any of the registered MBeans.
* @exception ListenerNotFoundException The listener is not
* registered in the MBean.
*/
public void removeNotificationListener(ObjectName name,
ObjectName listener)
throws InstanceNotFoundException, ListenerNotFoundException;
/**
* <p>Removes a listener from a registered MBean.</p>
*
* <p>The MBean must have a listener that exactly matches the
* given <code>listener</code>, <code>filter</code>, and
* <code>handback</code> parameters. If there is more than one
* such listener, only one is removed.</p>
*
* <p>The <code>filter</code> and <code>handback</code> parameters
* may be null if and only if they are null in a listener to be
* removed.</p>
*
* @param name The name of the MBean on which the listener should
* be removed.
* @param listener A listener that was previously added to this
* MBean.
* @param filter The filter that was specified when the listener
* was added.
* @param handback The handback that was specified when the
* listener was added.
*
* @exception InstanceNotFoundException The MBean name provided
* does not match any of the registered MBeans.
* @exception ListenerNotFoundException The listener is not
* registered in the MBean, or it is not registered with the given
* filter and handback.
*/
public void removeNotificationListener(ObjectName name,
ObjectName listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException, ListenerNotFoundException;
/**
* <p>Removes a listener from a registered MBean.</p>
*
* <P> If the listener is registered more than once, perhaps with
* different filters or callbacks, this method will remove all
* those registrations.
*
* @param name The name of the MBean on which the listener should
* be removed.
* @param listener The listener object which will handle the
* notifications emitted by the registered MBean.
*
* @exception InstanceNotFoundException The MBean name provided
* does not match any of the registered MBeans.
* @exception ListenerNotFoundException The listener is not
* registered in the MBean.
*/
public void removeNotificationListener(ObjectName name,
NotificationListener listener)
throws InstanceNotFoundException, ListenerNotFoundException;
/**
* <p>Removes a listener from a registered MBean.</p>
*
* <p>The MBean must have a listener that exactly matches the
* given <code>listener</code>, <code>filter</code>, and
* <code>handback</code> parameters. If there is more than one
* such listener, only one is removed.</p>
*
* <p>The <code>filter</code> and <code>handback</code> parameters
* may be null if and only if they are null in a listener to be
* removed.</p>
*
* @param name The name of the MBean on which the listener should
* be removed.
* @param listener A listener that was previously added to this
* MBean.
* @param filter The filter that was specified when the listener
* was added.
* @param handback The handback that was specified when the
* listener was added.
*
* @exception InstanceNotFoundException The MBean name provided
* does not match any of the registered MBeans.
* @exception ListenerNotFoundException The listener is not
* registered in the MBean, or it is not registered with the given
* filter and handback.
*/
public void removeNotificationListener(ObjectName name,
NotificationListener listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException, ListenerNotFoundException;
/**
* This method discovers the attributes and operations that an
* MBean exposes for management.
*
* @param name The name of the MBean to analyze
*
* @return An instance of <CODE>MBeanInfo</CODE> allowing the
* retrieval of all attributes and operations of this MBean.
*
* @exception IntrospectionException An exception occurred during
* introspection.
* @exception InstanceNotFoundException The MBean specified was
* not found.
* @exception ReflectionException An exception occurred when
* trying to invoke the getMBeanInfo of a Dynamic MBean.
*/
public MBeanInfo getMBeanInfo(ObjectName name)
throws InstanceNotFoundException, IntrospectionException,
ReflectionException;
/**
* Returns true if the MBean specified is an instance of the
* specified class, false otherwise.
*
* @param name The <CODE>ObjectName</CODE> of the MBean.
* @param className The name of the class.
*
* @return true if the MBean specified is an instance of the
* specified class, false otherwise.
*
* @exception InstanceNotFoundException The MBean specified is not
* registered in the MBean server.
*/
public boolean isInstanceOf(ObjectName name, String className)
throws InstanceNotFoundException;
/**
* <p>Return the {@link java.lang.ClassLoader} that was used for
* loading the class of the named MBean.
* @param mbeanName The ObjectName of the MBean.
* @return The ClassLoader used for that MBean.
* @exception InstanceNotFoundException if the named MBean is not found.
*/
public ClassLoader getClassLoaderFor(ObjectName mbeanName)
throws InstanceNotFoundException;
/**
* <p>Return the named {@link java.lang.ClassLoader}.
* @param loaderName The ObjectName of the ClassLoader.
* @return The named ClassLoader.
* @exception InstanceNotFoundException if the named ClassLoader is
* not found.
*/
public ClassLoader getClassLoader(ObjectName loaderName)
throws InstanceNotFoundException;
public ClassLoaderRepository getClassLoaderRepository();
}

View File

@ -0,0 +1,127 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.interceptor;
import java.io.ObjectInputStream;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.ObjectName;
import javax.management.OperationsException;
import javax.management.ReflectionException;
import javax.management.loading.ClassLoaderRepository;
/**
* An abstract class for MBeanServerInterceptorSupport.
* Some methods in MBeanServerInterceptor should never be called.
* This base class provides an implementation of these methods that simply
* throw an {@link UnsupportedOperationException}.
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
public abstract class MBeanServerInterceptorSupport
implements MBeanServerInterceptor {
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
public Object instantiate(String className)
throws ReflectionException, MBeanException {
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
public Object instantiate(String className, ObjectName loaderName)
throws ReflectionException, MBeanException,
InstanceNotFoundException {
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
public Object instantiate(String className, Object[] params,
String[] signature) throws ReflectionException, MBeanException {
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
public Object instantiate(String className, ObjectName loaderName,
Object[] params, String[] signature)
throws ReflectionException, MBeanException,
InstanceNotFoundException {
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
@Deprecated
public ObjectInputStream deserialize(ObjectName name, byte[] data)
throws InstanceNotFoundException, OperationsException {
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
@Deprecated
public ObjectInputStream deserialize(String className, byte[] data)
throws OperationsException, ReflectionException {
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
@Deprecated
public ObjectInputStream deserialize(String className,
ObjectName loaderName, byte[] data)
throws InstanceNotFoundException, OperationsException,
ReflectionException {
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
public ClassLoaderRepository getClassLoaderRepository() {
throw new UnsupportedOperationException("Not applicable.");
}
}

View File

@ -0,0 +1,236 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.interceptor;
import com.sun.jmx.defaults.JmxProperties;
import com.sun.jmx.mbeanserver.MBeanInstantiator;
import com.sun.jmx.mbeanserver.Repository;
import com.sun.jmx.mbeanserver.Util;
import com.sun.jmx.namespace.NamespaceInterceptor;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.namespace.JMXDomain;
import javax.management.namespace.JMXNamespace;
import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
/**
* A dispatcher that dispatches to NamespaceInterceptors.
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
public class NamespaceDispatchInterceptor
extends DispatchInterceptor<NamespaceInterceptor, JMXNamespace> {
/**
* A logger for this class.
**/
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
private static final int NAMESPACE_SEPARATOR_LENGTH =
NAMESPACE_SEPARATOR.length();
private final DomainDispatchInterceptor localNamespace;
private final String serverName;
/**
* Creates a NamespaceDispatchInterceptor with the specified
* repository instance.
* <p>Do not forget to call <code>initialize(outer,delegate)</code>
* before using this object.
*
* @param outer A pointer to the MBeanServer object that must be
* passed to the MBeans when invoking their
* {@link javax.management.MBeanRegistration} interface.
* @param delegate A pointer to the MBeanServerDelegate associated
* with the new MBeanServer. The new MBeanServer must register
* this MBean in its MBean repository.
* @param instantiator The MBeanInstantiator that will be used to
* instantiate MBeans and take care of class loading issues.
* @param repository The repository to use for this MBeanServer
*/
public NamespaceDispatchInterceptor(MBeanServer outer,
MBeanServerDelegate delegate,
MBeanInstantiator instantiator,
Repository repository) {
localNamespace = new DomainDispatchInterceptor(outer,delegate,
instantiator,repository,this);
serverName = Util.getMBeanServerSecurityName(delegate);
}
// TODO: Should move that to JMXNamespace? or to ObjectName?
/**
* Get first name space in ObjectName path. Ignore leading namespace
* separators.
**/
public static String getFirstNamespace(ObjectName name) {
if (name == null) return "";
final String domain = name.getDomain();
if (domain.equals("")) return "";
int first = 0;
int end = domain.indexOf(NAMESPACE_SEPARATOR,first);
while (end == first) {
first = end+NAMESPACE_SEPARATOR_LENGTH;
end = domain.indexOf(NAMESPACE_SEPARATOR,first);
if (end == -1) break;
}
if (end == -1) return "";
final String namespace = domain.substring(first,end);
return namespace;
}
/**
* Called by the DefaultMBeanServerInterceptor, just before adding an
* MBean to the repository.
*
* @param resource the MBean to be registered.
* @param logicalName the name of the MBean to be registered.
*/
final void checkLocallyRegistrable(Object resource,
ObjectName logicalName) {
if (!(resource instanceof JMXNamespace) &&
logicalName.getDomain().contains(NAMESPACE_SEPARATOR))
throw new IllegalArgumentException(String.valueOf(logicalName)+
": Invalid ObjectName for an instance of " +
resource.getClass().getName());
}
final boolean isLocalHandlerNameFor(String namespace,
ObjectName handlerName) {
return handlerName.getDomain().equals(namespace+NAMESPACE_SEPARATOR) &&
JMXNamespace.TYPE_ASSIGNMENT.equals(
handlerName.getKeyPropertyListString());
}
@Override
final MBeanServer getInterceptorOrNullFor(ObjectName name) {
final String namespace = getFirstNamespace(name);
if (namespace.equals("") || isLocalHandlerNameFor(namespace,name) ||
name.getDomain().equals(namespace+NAMESPACE_SEPARATOR)) {
LOG.finer("dispatching to local name space");
return localNamespace;
}
final NamespaceInterceptor ns = getInterceptor(namespace);
if (LOG.isLoggable(Level.FINER)) {
if (ns != null) {
LOG.finer("dispatching to name space: " + namespace);
} else {
LOG.finer("no handler for: " + namespace);
}
}
return ns;
}
@Override
final QueryInterceptor getInterceptorForQuery(ObjectName pattern) {
final String namespace = getFirstNamespace(pattern);
if (namespace.equals("") || isLocalHandlerNameFor(namespace,pattern) ||
pattern.getDomain().equals(namespace+NAMESPACE_SEPARATOR)) {
LOG.finer("dispatching to local name space");
return new QueryInterceptor(localNamespace);
}
final NamespaceInterceptor ns = getInterceptor(namespace);
if (LOG.isLoggable(Level.FINER)) {
if (ns != null) {
LOG.finer("dispatching to name space: " + namespace);
} else {
LOG.finer("no handler for: " + namespace);
}
}
if (ns == null) return null;
return new QueryInterceptor(ns);
}
@Override
final ObjectName getHandlerNameFor(String key)
throws MalformedObjectNameException {
return ObjectName.getInstance(key+NAMESPACE_SEPARATOR,
"type", JMXNamespace.TYPE);
}
@Override
final public String getHandlerKey(ObjectName name) {
return getFirstNamespace(name);
}
@Override
final NamespaceInterceptor createInterceptorFor(String key,
ObjectName name, JMXNamespace handler,
Queue<Runnable> postRegisterQueue) {
final NamespaceInterceptor ns =
new NamespaceInterceptor(serverName,handler,key);
if (LOG.isLoggable(Level.FINER)) {
LOG.finer("NamespaceInterceptor created: "+ns);
}
return ns;
}
@Override
final DomainDispatchInterceptor getNextInterceptor() {
return localNamespace;
}
/**
* Returns the list of domains in which any MBean is currently
* registered.
*/
@Override
public String[] getDomains() {
return localNamespace.getDomains();
}
@Override
public void addNamespace(ObjectName name, JMXNamespace handler,
Queue<Runnable> postRegisterQueue) {
if (handler instanceof JMXDomain)
localNamespace.addNamespace(name,
(JMXDomain)handler,postRegisterQueue);
else super.addNamespace(name,handler,postRegisterQueue);
}
@Override
public void removeNamespace(ObjectName name, JMXNamespace handler,
Queue<Runnable> postDeregisterQueue) {
if (handler instanceof JMXDomain)
localNamespace.removeNamespace(name,(JMXDomain)handler,
postDeregisterQueue);
else super.removeNamespace(name,handler,postDeregisterQueue);
}
}

View File

@ -51,6 +51,8 @@ import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.ReflectionException;
import javax.management.namespace.JMXNamespaces;
import javax.management.namespace.MBeanServerSupport;
import javax.management.remote.IdentityMBeanServerForwarder;
public class SingleMBeanForwarder extends IdentityMBeanServerForwarder {
@ -285,14 +287,14 @@ public class SingleMBeanForwarder extends IdentityMBeanServerForwarder {
if (!pattern.apply(mbeanName))
return false;
// final String dompat = pattern.getDomain();
// if (!dompat.contains(JMXNamespaces.NAMESPACE_SEPARATOR))
// return true; // We already checked that patterns apply.
//
// if (mbeanName.getDomain().endsWith(JMXNamespaces.NAMESPACE_SEPARATOR)) {
// // only matches if pattern ends with //
// return dompat.endsWith(JMXNamespaces.NAMESPACE_SEPARATOR);
// }
final String dompat = pattern.getDomain();
if (!dompat.contains(JMXNamespaces.NAMESPACE_SEPARATOR))
return true; // We already checked that patterns apply.
if (mbeanName.getDomain().endsWith(JMXNamespaces.NAMESPACE_SEPARATOR)) {
// only matches if pattern ends with //
return dompat.endsWith(JMXNamespaces.NAMESPACE_SEPARATOR);
}
// should not come here, unless mbeanName contains a // in the
// middle of its domain, which would be weird.

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1999-2008 Sun Microsystems, Inc. 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
@ -25,44 +25,42 @@
package com.sun.jmx.mbeanserver;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.Set;
import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
import com.sun.jmx.interceptor.NamespaceDispatchInterceptor;
import java.io.ObjectInputStream;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedExceptionAction;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
// RI import
import javax.management.MBeanPermission;
import javax.management.AttributeNotFoundException;
import javax.management.MBeanException;
import javax.management.ReflectionException;
import javax.management.MBeanInfo;
import javax.management.QueryExp;
import javax.management.NotificationListener;
import javax.management.NotificationFilter;
import javax.management.ListenerNotFoundException;
import javax.management.IntrospectionException;
import javax.management.OperationsException;
import javax.management.InstanceNotFoundException;
import javax.management.NotCompliantMBeanException;
import javax.management.MBeanRegistrationException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InvalidAttributeValueException;
import javax.management.ObjectName;
import javax.management.ObjectInstance;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.RuntimeOperationsException;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanPermission;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.OperationsException;
import javax.management.QueryExp;
import javax.management.ReflectionException;
import javax.management.RuntimeOperationsException;
import javax.management.loading.ClassLoaderRepository;
import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
import com.sun.jmx.interceptor.DefaultMBeanServerInterceptor;
import com.sun.jmx.interceptor.MBeanServerInterceptor;
/**
* This is the base class for MBean manipulation on the agent side. It
* contains the methods necessary for the creation, registration, and
@ -102,15 +100,14 @@ public final class JmxMBeanServer
/** true if interceptors are enabled **/
private final boolean interceptorsEnabled;
/** Revisit: transient ??? **/
private final transient MBeanServer outerShell;
private final MBeanServer outerShell;
/** Revisit: transient ??? **/
private transient MBeanServerInterceptor mbsInterceptor = null;
private volatile MBeanServer mbsInterceptor = null;
/** Revisit: transient ??? **/
/** The MBeanServerDelegate object representing the MBean Server */
private final transient MBeanServerDelegate mBeanServerDelegateObject;
private final MBeanServerDelegate mBeanServerDelegateObject;
private final String mbeanServerName;
/**
* <b>Package:</b> Creates an MBeanServer with the
@ -243,9 +240,10 @@ public final class JmxMBeanServer
final Repository repository = new Repository(domain,fairLock);
this.mbsInterceptor =
new DefaultMBeanServerInterceptor(outer, delegate, instantiator,
new NamespaceDispatchInterceptor(outer, delegate, instantiator,
repository);
this.interceptorsEnabled = interceptors;
this.mbeanServerName = Util.getMBeanServerSecurityName(delegate);
initialize();
}
@ -941,7 +939,8 @@ public final class JmxMBeanServer
throws ReflectionException, MBeanException {
/* Permission check */
checkMBeanPermission(className, null, null, "instantiate");
checkMBeanPermission(mbeanServerName, className, null, null,
"instantiate");
return instantiator.instantiate(className);
}
@ -978,7 +977,8 @@ public final class JmxMBeanServer
InstanceNotFoundException {
/* Permission check */
checkMBeanPermission(className, null, null, "instantiate");
checkMBeanPermission(mbeanServerName, className, null,
null, "instantiate");
ClassLoader myLoader = outerShell.getClass().getClassLoader();
return instantiator.instantiate(className, loaderName, myLoader);
@ -1016,7 +1016,8 @@ public final class JmxMBeanServer
throws ReflectionException, MBeanException {
/* Permission check */
checkMBeanPermission(className, null, null, "instantiate");
checkMBeanPermission(mbeanServerName, className, null, null,
"instantiate");
ClassLoader myLoader = outerShell.getClass().getClassLoader();
return instantiator.instantiate(className, params, signature,
@ -1059,7 +1060,8 @@ public final class JmxMBeanServer
InstanceNotFoundException {
/* Permission check */
checkMBeanPermission(className, null, null, "instantiate");
checkMBeanPermission(mbeanServerName, className, null,
null, "instantiate");
ClassLoader myLoader = outerShell.getClass().getClassLoader();
return instantiator.instantiate(className,loaderName,params,signature,
@ -1236,7 +1238,7 @@ public final class JmxMBeanServer
"Unexpected exception occurred", e);
}
throw new
IllegalStateException("Can't register delegate.");
IllegalStateException("Can't register delegate.",e);
}
@ -1278,7 +1280,7 @@ public final class JmxMBeanServer
* are not enabled on this object.
* @see #interceptorsEnabled
**/
public synchronized MBeanServerInterceptor getMBeanServerInterceptor() {
public synchronized MBeanServer getMBeanServerInterceptor() {
if (interceptorsEnabled) return mbsInterceptor;
else throw new UnsupportedOperationException(
"MBeanServerInterceptors are disabled.");
@ -1292,7 +1294,7 @@ public final class JmxMBeanServer
* @see #interceptorsEnabled
**/
public synchronized void
setMBeanServerInterceptor(MBeanServerInterceptor interceptor) {
setMBeanServerInterceptor(MBeanServer interceptor) {
if (!interceptorsEnabled) throw new UnsupportedOperationException(
"MBeanServerInterceptors are disabled.");
if (interceptor == null) throw new
@ -1330,7 +1332,8 @@ public final class JmxMBeanServer
**/
public ClassLoaderRepository getClassLoaderRepository() {
/* Permission check */
checkMBeanPermission(null, null, null, "getClassLoaderRepository");
checkMBeanPermission(mbeanServerName, null, null,
null, "getClassLoaderRepository");
return secureClr;
}
@ -1484,14 +1487,16 @@ public final class JmxMBeanServer
// SECURITY CHECKS
//----------------
private static void checkMBeanPermission(String classname,
private static void checkMBeanPermission(String serverName,
String classname,
String member,
ObjectName objectName,
String actions)
throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
Permission perm = new MBeanPermission(classname,
Permission perm = new MBeanPermission(serverName,
classname,
member,
objectName,
actions);

View File

@ -224,7 +224,7 @@ public abstract class MXBeanLookup {
throws InvalidObjectException {
String domain = prefix + name.getDomain();
try {
name = switchDomain(domain, name);
name = name.withDomain(domain);
} catch (MalformedObjectNameException e) {
throw EnvHelp.initCause(
new InvalidObjectException(e.getMessage()), e);
@ -242,7 +242,7 @@ public abstract class MXBeanLookup {
"Proxy's name does not start with " + prefix + ": " + name);
}
try {
name = switchDomain(domain.substring(prefix.length()), name);
name = name.withDomain(domain.substring(prefix.length()));
} catch (MalformedObjectNameException e) {
throw EnvHelp.initCause(new OpenDataException(e.getMessage()), e);
}
@ -269,14 +269,6 @@ public abstract class MXBeanLookup {
currentLookup.set(lookup);
}
// Method temporarily added until we have ObjectName.switchDomain in the
// public API. Note that this method DOES NOT PRESERVE the order of
// keys in the ObjectName so it must not be used in the final release.
static ObjectName switchDomain(String domain, ObjectName name)
throws MalformedObjectNameException {
return new ObjectName(domain, name.getKeyPropertyList());
}
private static final ThreadLocal<MXBeanLookup> currentLookup =
new ThreadLocal<MXBeanLookup>();

View File

@ -45,7 +45,6 @@ import javax.management.QueryExp;
import javax.management.RuntimeOperationsException;
/**
* The RepositorySupport implements the Repository interface.
* This repository does not support persistency.
*
* @since 1.5
@ -197,9 +196,9 @@ public class Repository {
if (isPropertyValuePattern &&
pattern.isPropertyValuePattern(keys[i])) {
// wildmatch key property values
final char[] val_pattern = values[i].toCharArray();
final char[] val_string = v.toCharArray();
if (wildmatch(val_string,val_pattern))
// values[i] is the pattern;
// v is the string
if (Util.wildmatch(v,values[i]))
continue;
else
return false;
@ -236,86 +235,6 @@ public class Repository {
}
}
/** Match a string against a shell-style pattern. The only pattern
characters recognised are <code>?</code>, standing for any one
character, and <code>*</code>, standing for any string of
characters, including the empty string.
@param str the string to match, as a character array.
@param pat the pattern to match the string against, as a
character array.
@return true if and only if the string matches the pattern.
*/
/* The algorithm is a classical one. We advance pointers in
parallel through str and pat. If we encounter a star in pat,
we remember its position and continue advancing. If at any
stage we get a mismatch between str and pat, we look to see if
there is a remembered star. If not, we fail. If so, we
retreat pat to just past that star and str to the position
after the last one we tried, and we let the match advance
again.
Even though there is only one remembered star position, the
algorithm works when there are several stars in the pattern.
When we encounter the second star, we forget the first one.
This is OK, because if we get to the second star in A*B*C
(where A etc are arbitrary strings), we have already seen AXB.
We're therefore setting up a match of *C against the remainder
of the string, which will match if that remainder looks like
YC, so the whole string looks like AXBYC.
*/
public static boolean wildmatch(char[] str, char[] pat) {
int stri; // index in str
int pati; // index in pat
int starstri; // index for backtrack if "*" attempt fails
int starpati; // index for backtrack if "*" attempt fails, +1
final int strlen = str.length;
final int patlen = pat.length;
stri = pati = 0;
starstri = starpati = -1;
/* On each pass through this loop, we either advance pati,
or we backtrack pati and advance starstri. Since starstri
is only ever assigned from pati, the loop must terminate. */
while (true) {
if (pati < patlen) {
final char patc = pat[pati];
switch (patc) {
case '?':
if (stri == strlen)
break;
stri++;
pati++;
continue;
case '*':
pati++;
starpati = pati;
starstri = stri;
continue;
default:
if (stri < strlen && str[stri] == patc) {
stri++;
pati++;
continue;
}
break;
}
} else if (stri == strlen)
return true;
// Mismatched, can we backtrack to a "*"?
if (starpati < 0 || starstri == strlen)
return false;
// Retry the match one position later in str
pati = starpati;
starstri++;
stri = starstri;
}
}
private void addNewDomMoi(final DynamicMBean object,
final String dom,
final ObjectName name,
@ -370,7 +289,7 @@ public class Repository {
if (name.isPattern()) return null;
// Extract the domain name.
String dom= name.getDomain().intern();
String dom = name.getDomain().intern();
// Default domain case
if (dom.length() == 0) {
@ -480,7 +399,7 @@ public class Repository {
name = Util.newObjectName(domain + name.toString());
// Do we have default domain ?
if (dom == domain) {
if (dom == domain) { // ES: OK (dom & domain are interned)
to_default_domain = true;
dom = domain;
} else {
@ -652,10 +571,9 @@ public class Repository {
}
// Pattern matching in the domain name (*, ?)
char[] dom2Match = name.getDomain().toCharArray();
final String dom2Match = name.getDomain();
for (String dom : domainTb.keySet()) {
char[] theDom = dom.toCharArray();
if (wildmatch(theDom, dom2Match)) {
if (Util.wildpathmatch(dom, dom2Match)) {
final Map<String,NamedObject> moiTb = domainTb.get(dom);
if (allNames)
result.addAll(moiTb.values());
@ -726,7 +644,7 @@ public class Repository {
// need to reinstantiate a hashtable because of possible
// big buckets array size inside table, never cleared,
// thus the new !
if (dom == domain)
if (dom == domain) // ES: OK dom and domain are interned.
domainTb.put(domain, new HashMap<String,NamedObject>());
}

View File

@ -28,17 +28,16 @@ package com.sun.jmx.mbeanserver;
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
import com.sun.jmx.interceptor.MBeanServerInterceptor;
/**
* Extends the MBeanServer and MBeanServerInterceptor interface to
* Extends the MBeanServer interface to
* provide methods for getting the MetaData and MBeanServerInstantiator
* objects associated with an MBeanServer.
*
* @since 1.5
*/
public interface SunJmxMBeanServer
extends MBeanServerInterceptor, MBeanServer {
extends MBeanServer {
/**
* Return the MBeanInstantiator associated to this MBeanServer.
@ -68,7 +67,7 @@ public interface SunJmxMBeanServer
* are not enabled on this object.
* @see #interceptorsEnabled
**/
public MBeanServerInterceptor getMBeanServerInterceptor();
public MBeanServer getMBeanServerInterceptor();
/**
* Set the MBeanServerInterceptor.
@ -77,7 +76,7 @@ public interface SunJmxMBeanServer
* are not enabled on this object.
* @see #interceptorsEnabled
**/
public void setMBeanServerInterceptor(MBeanServerInterceptor interceptor);
public void setMBeanServerInterceptor(MBeanServer interceptor);
/**
* <p>Return the MBeanServerDelegate representing the MBeanServer.

View File

@ -25,6 +25,8 @@
package com.sun.jmx.mbeanserver;
import com.sun.jmx.defaults.JmxProperties;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -42,11 +44,22 @@ import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.WeakHashMap;
import java.util.logging.Level;
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.loading.ClassLoaderRepository;
import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
public class Util {
private final static int NAMESPACE_SEPARATOR_LENGTH =
NAMESPACE_SEPARATOR.length();
public final static String ILLEGAL_MBEANSERVER_NAME_CHARS=";:*?";
static <K, V> Map<K, V> newMap() {
return new HashMap<K, V>();
}
@ -145,6 +158,270 @@ public class Util {
return hash;
}
/** Match a part of a string against a shell-style pattern.
The only pattern characters recognized are <code>?</code>,
standing for any one character,
and <code>*</code>, standing for any string of
characters, including the empty string. For instance,
{@code wildmatch("sandwich","sa?d*ch",1,4,1,4)} will match
{@code "and"} against {@code "a?d"}.
@param str the string containing the sequence to match.
@param pat a string containing a pattern to match the sub string
against.
@param stri the index in the string at which matching should begin.
@param strend the index in the string at which the matching should
end.
@param pati the index in the pattern at which matching should begin.
@param patend the index in the pattern at which the matching should
end.
@return true if and only if the string matches the pattern.
*/
/* The algorithm is a classical one. We advance pointers in
parallel through str and pat. If we encounter a star in pat,
we remember its position and continue advancing. If at any
stage we get a mismatch between str and pat, we look to see if
there is a remembered star. If not, we fail. If so, we
retreat pat to just past that star and str to the position
after the last one we tried, and we let the match advance
again.
Even though there is only one remembered star position, the
algorithm works when there are several stars in the pattern.
When we encounter the second star, we forget the first one.
This is OK, because if we get to the second star in A*B*C
(where A etc are arbitrary strings), we have already seen AXB.
We're therefore setting up a match of *C against the remainder
of the string, which will match if that remainder looks like
YC, so the whole string looks like AXBYC.
*/
private static boolean wildmatch(final String str, final String pat,
int stri, final int strend, int pati, final int patend) {
// System.out.println("matching "+pat.substring(pati,patend)+
// " against "+str.substring(stri, strend));
int starstri; // index for backtrack if "*" attempt fails
int starpati; // index for backtrack if "*" attempt fails, +1
starstri = starpati = -1;
/* On each pass through this loop, we either advance pati,
or we backtrack pati and advance starstri. Since starstri
is only ever assigned from pati, the loop must terminate. */
while (true) {
if (pati < patend) {
final char patc = pat.charAt(pati);
switch (patc) {
case '?':
if (stri == strend)
break;
stri++;
pati++;
continue;
case '*':
pati++;
starpati = pati;
starstri = stri;
continue;
default:
if (stri < strend && str.charAt(stri) == patc) {
stri++;
pati++;
continue;
}
break;
}
} else if (stri == strend)
return true;
// Mismatched, can we backtrack to a "*"?
if (starpati < 0 || starstri == strend)
return false;
// Retry the match one position later in str
pati = starpati;
starstri++;
stri = starstri;
}
}
/** Match a string against a shell-style pattern. The only pattern
characters recognized are <code>?</code>, standing for any one
character, and <code>*</code>, standing for any string of
characters, including the empty string.
@param str the string to match.
@param pat the pattern to match the string against.
@return true if and only if the string matches the pattern.
*/
public static boolean wildmatch(String str, String pat) {
return wildmatch(str,pat,0,str.length(),0,pat.length());
}
/**
* Matches a string against a pattern, as a name space path.
* This is a special matching where * and ?? don't match //.
* The string is split in sub-strings separated by //, and the
* pattern is split in sub-patterns separated by //. Each sub-string
* is matched against its corresponding sub-pattern.
* so <elt-1>//<elt2>//...//<elt-n> matches <pat-1>//<pat-2>//...//<pat-q>
* only if n==q and for ( i = 1 => n) elt-i matches pat-i.
*
* In addition, if we encounter a pattern element which is exactly
* **, it can match any number of path-elements - but it must match at
* least one element.
* When we encounter such a meta-wildcard, we remember its position
* and the position in the string path, and we advance both the pattern
* and the string. Later, if we encounter a mismatch in pattern & string,
* we rewind the position in pattern to just after the meta-wildcard,
* and we backtrack the string to i+1 element after the position
* we had when we first encountered the meta-wildcard, i being the
* position when we last backtracked the string.
*
* The backtracking logic is an adaptation of the logic in wildmatch
* above.
* See test/javax/mangement/ObjectName/ApplyWildcardTest.java
*
* Note: this thing is called 'wild' - and that's for a reason ;-)
**/
public static boolean wildpathmatch(String str, String pat) {
final int strlen = str.length();
final int patlen = pat.length();
int stri = 0;
int pati = 0;
int starstri; // index for backtrack if "**" attempt fails
int starpati; // index for backtrack if "**" attempt fails
starstri = starpati = -1;
while (true) {
// System.out.println("pati="+pati+", stri="+stri);
final int strend = str.indexOf(NAMESPACE_SEPARATOR, stri);
final int patend = pat.indexOf(NAMESPACE_SEPARATOR, pati);
// no // remaining in either string or pattern: simple wildmatch
// until end of string.
if (strend == -1 && patend == -1) {
// System.out.println("last sub pattern, last sub element...");
// System.out.println("wildmatch("+str.substring(stri,strlen)+
// ","+pat.substring(pati,patlen)+")");
return wildmatch(str,pat,stri,strlen,pati,patlen);
}
// no // remaining in string, but at least one remaining in
// pattern
// => no match
if (strend == -1) {
// System.out.println("pattern has more // than string...");
return false;
}
// strend is != -1, but patend might.
// detect wildcard **
if (patend == pati+2 && pat.charAt(pati)=='*' &&
pat.charAt(pati+1)=='*') {
// if we reach here we know that neither strend nor patend are
// equals to -1.
stri = strend + NAMESPACE_SEPARATOR_LENGTH;
pati = patend + NAMESPACE_SEPARATOR_LENGTH;
starpati = pati; // position just after **// in pattern
starstri = stri; // we eat 1 element in string, and remember
// the position for backtracking and eating
// one more element if needed.
// System.out.println("starpati="+pati);
continue;
}
// This is a bit hacky: * can match // when // is at the end
// of the string, so we include the // delimiter in the pattern
// matching. Either we're in the middle of the path, so including
// // both at the end of the pattern and at the end of the string
// has no effect - match(*//,dfsd//) is equivalent to match(*,dfsd)
// or we're at the end of the pattern path, in which case
// including // at the end of the string will have the desired
// effect (provided that we detect the end of matching correctly,
// see further on).
//
final int endpat =
((patend > -1)?patend+NAMESPACE_SEPARATOR_LENGTH:patlen);
final int endstr =
((strend > -1)?strend+NAMESPACE_SEPARATOR_LENGTH:strlen);
// if we reach the end of the pattern, or if elt-i & pat-i
// don't match, we have a mismatch.
// Note: we know that strend != -1, therefore patend==-1
// indicates a mismatch unless pattern can match
// a // at the end, and strend+2=strlen.
// System.out.println("wildmatch("+str.substring(stri,endstr)+","+
// pat.substring(pati,endpat)+")");
if (!wildmatch(str,pat,stri,endstr,pati,endpat)) {
// System.out.println("nomatch");
// if we have a mismatch and didn't encounter any meta-wildcard,
// we return false. String & pattern don't match.
if (starpati < 0) return false;
// If we reach here, we had a meta-wildcard.
// We need to backtrack to the wildcard, and make it eat an
// additional string element.
//
stri = str.indexOf(NAMESPACE_SEPARATOR, starstri);
// System.out.println("eating one additional element? "+stri);
// If there's no more elements to eat, string and pattern
// don't match => return false.
if (stri == -1) return false;
// Backtrack to where we were when we last matched against
// the meta-wildcard, make it eat an additional path element,
// remember the new positions, and continue from there...
//
stri = stri + NAMESPACE_SEPARATOR_LENGTH;
starstri = stri;
pati = starpati;
// System.out.println("skiping to stri="+stri);
continue;
}
// Here we know that strend > -1 but we can have patend == -1.
//
// So if we reach here, we know pat-i+//? has matched
// elt-i+//
//
// If patend==-1, we know that there was no delimiter
// at the end of the pattern, that we are at the last pattern,
// and therefore that pat-i has matched elt-i+//
//
// In that case we can consider that we have a match only if
// elt-i is also the last path element in the string, which is
// equivalent to saying that strend+2==strlen.
//
if (patend == -1 && starpati == -1)
return (strend+NAMESPACE_SEPARATOR_LENGTH==strlen);
// patend != -1, or starpati > -1 so there remains something
// to match.
// go to next pair: elt-(i+1) pat-(i+1);
stri = strend + NAMESPACE_SEPARATOR_LENGTH;
pati = (patend==-1)?pati:(patend + NAMESPACE_SEPARATOR_LENGTH);
}
}
/**
* Returns true if the ObjectName's {@code domain} is selected by the
* given {@code pattern}.
*/
public static boolean isDomainSelected(String domain, String pattern) {
if (domain == null || pattern == null)
throw new IllegalArgumentException("null");
return Util.wildpathmatch(domain,pattern);
}
/**
* Filters a set of ObjectName according to a given pattern.
*
@ -167,6 +444,34 @@ public class Util {
return res;
}
/**
* Filters a set of ObjectInstance according to a given pattern.
*
* @param pattern the pattern that the returned names must match.
* @param all the set of instances to filter.
* @return a set of ObjectInstance from which non matching instances
* have been removed.
*/
public static Set<ObjectInstance>
filterMatchingInstances(ObjectName pattern,
Set<ObjectInstance> all) {
// If no pattern, just return all names
if (pattern == null
|| all.isEmpty()
|| ObjectName.WILDCARD.equals(pattern))
return all;
// If there's a pattern, do the matching.
final Set<ObjectInstance> res = equivalentEmptySet(all);
for (ObjectInstance n : all) {
if (n == null) continue;
if (pattern.apply(n.getObjectName()))
res.add(n);
}
return res;
}
/**
* An abstract ClassLoaderRepository that contains a single class loader.
**/
@ -216,6 +521,160 @@ public class Util {
return new SingleClassLoaderRepository(loader);
}
/**
* Returns the name of the given MBeanServer that should be put in a
* permission you need.
* This corresponds to the
* {@code *[;mbeanServerName=<mbeanServerName>[;*]]} property
* embedded in the MBeanServerId attribute of the
* server's {@link MBeanServerDelegate}.
*
* @param server The MBean server
* @return the name of the MBeanServer, or "*" if the name couldn't be
* obtained, or {@value MBeanServerFactory#DEFAULT_MBEANSERVER_NAME}
* if there was no name.
*/
public static String getMBeanServerSecurityName(MBeanServer server) {
final String notfound = "*";
try {
final String mbeanServerId = (String)
server.getAttribute(MBeanServerDelegate.DELEGATE_NAME,
"MBeanServerId");
final String found = extractMBeanServerName(mbeanServerId);
if (found.length()==0)
return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME;
return found;
} catch (Exception x) {
logshort("Failed to retrieve MBeanServerName for server, " +
"using \"*\"",x);
return notfound;
}
}
/**
* Returns the name of the MBeanServer embedded in the given
* mbeanServerId. If the given mbeanServerId doesn't contain any name,
* an empty String is returned.
* The MBeanServerId is expected to be of the form:
* {@code *[;mbeanServerName=<mbeanServerName>[;*]]}
* @param mbeanServerId The MBean server ID
* @return the name of the MBeanServer if found, or "" if the name was
* not present in the mbeanServerId.
*/
public static String extractMBeanServerName(String mbeanServerId) {
if (mbeanServerId==null) return "";
final String beginMarker=";mbeanServerName=";
final String endMarker=";";
final int found = mbeanServerId.indexOf(beginMarker);
if (found < 0) return "";
final int start = found + beginMarker.length();
final int stop = mbeanServerId.indexOf(endMarker, start);
return mbeanServerId.substring(start,
(stop < 0 ? mbeanServerId.length() : stop));
}
/**
* Insert the given mbeanServerName into the given mbeanServerId.
* If mbeanServerName is null, empty, or equals to "-", the returned
* mbeanServerId will not contain any mbeanServerName.
* @param mbeanServerId The mbeanServerId in which to insert
* mbeanServerName
* @param mbeanServerName The mbeanServerName
* @return an mbeanServerId containing the given mbeanServerName
* @throws IllegalArgumentException if mbeanServerId already contains
* a different name, or if the given mbeanServerName is not valid.
*/
public static String insertMBeanServerName(String mbeanServerId,
String mbeanServerName) {
final String found = extractMBeanServerName(mbeanServerId);
if (found.length() > 0 &&
found.equals(checkServerName(mbeanServerName)))
return mbeanServerId;
if (found.length() > 0 && !isMBeanServerNameUndefined(found))
throw new IllegalArgumentException(
"MBeanServerName already defined");
if (isMBeanServerNameUndefined(mbeanServerName))
return mbeanServerId;
final String beginMarker=";mbeanServerName=";
return mbeanServerId+beginMarker+checkServerName(mbeanServerName);
}
/**
* Returns true if the given mbeanServerName corresponds to an
* undefined MBeanServerName.
* The mbeanServerName is considered undefined if it is one of:
* {@code null} or {@value MBeanServerFactory#DEFAULT_MBEANSERVER_NAME}.
* @param mbeanServerName The mbeanServerName, as returned by
* {@link #extractMBeanServerName(String)}.
* @return true if the given name corresponds to one of the forms that
* denotes an undefined MBeanServerName.
*/
public static boolean isMBeanServerNameUndefined(String mbeanServerName) {
return mbeanServerName == null ||
MBeanServerFactory.DEFAULT_MBEANSERVER_NAME.equals(mbeanServerName);
}
/**
* Check that the provided mbeanServername is syntactically valid.
* @param mbeanServerName An mbeanServerName, or {@code null}.
* @return mbeanServerName, or {@value
* MBeanServerFactory#DEFAULT_MBEANSERVER_NAME} if {@code mbeanServerName}
* is {@code null}.
* @throws IllegalArgumentException if mbeanServerName contains illegal
* characters, or is empty, or is {@code "-"}.
* Illegal characters are {@value #ILLEGAL_MBEANSERVER_NAME_CHARS}.
*/
public static String checkServerName(String mbeanServerName) {
if ("".equals(mbeanServerName))
throw new IllegalArgumentException(
"\"\" is not a valid MBean server name");
if ("-".equals(mbeanServerName))
throw new IllegalArgumentException(
"\"-\" is not a valid MBean server name");
if (isMBeanServerNameUndefined(mbeanServerName))
return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME;
for (char c : ILLEGAL_MBEANSERVER_NAME_CHARS.toCharArray()) {
if (mbeanServerName.indexOf(c) >= 0)
throw new IllegalArgumentException(
"invalid character in MBeanServer name: "+c);
}
return mbeanServerName;
}
/**
* Get the MBeanServer name that should be put in a permission you need.
*
* @param delegate The MBeanServerDelegate
* @return The MBeanServer name - or {@value
* MBeanServerFactory#DEFAULT_MBEANSERVER_NAME} if there was no name.
*/
public static String getMBeanServerSecurityName(
MBeanServerDelegate delegate) {
try {
final String serverName = delegate.getMBeanServerName();
if (isMBeanServerNameUndefined(serverName))
return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME;
return serverName;
} catch (Exception x) {
logshort("Failed to retrieve MBeanServerName from delegate, " +
"using \"*\"",x);
return "*";
}
}
// Log the exception and its causes without logging the stack trace.
// Use with care - it is usally preferable to log the whole stack trace!
// We don't want to log the whole stack trace here: logshort() is
// called in those cases where the exception might not be abnormal.
private static void logshort(String msg, Throwable t) {
if (JmxProperties.MISC_LOGGER.isLoggable(Level.FINE)) {
StringBuilder toprint = new StringBuilder(msg);
toprint.append("\nCaused By: ").append(String.valueOf(t));
while ((t=t.getCause())!=null)
toprint.append("\nCaused By: ").append(String.valueOf(t));
JmxProperties.MISC_LOGGER.fine(toprint.toString());
}
}
public static <T> Set<T> cloneSet(Set<T> set) {
if (set instanceof SortedSet) {
@SuppressWarnings("unchecked")
@ -232,10 +691,19 @@ public class Util {
@SuppressWarnings("unchecked")
SortedSet<T> sset = (SortedSet<T>) set;
set = new TreeSet<T>(sset.comparator());
} else if (set != null) {
set = new HashSet<T>(set.size());
} else
set = new HashSet<T>();
return set;
}
// This exception is used when wrapping a class that throws IOException
// in a class that doesn't.
// The typical example for this are JMXNamespaces, when the sub
// MBeanServer can be remote.
//
public static RuntimeException newRuntimeIOException(IOException io) {
final String msg = "Communication failed with underlying resource: "+
io.getMessage();
return new RuntimeException(msg,io);
}
}

View File

@ -0,0 +1,475 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace;
import com.sun.jmx.defaults.JmxProperties;
import com.sun.jmx.mbeanserver.Util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.InstanceNotFoundException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanPermission;
import javax.management.MBeanServerDelegate;
import javax.management.MBeanServerNotification;
import javax.management.MalformedObjectNameException;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.namespace.JMXDomain;
/**
* A DomainInterceptor wraps a JMXDomain.
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
// TODO: Ideally DomainInterceptor should be replaced by
// something at Repository level.
// The problem there will be that we may need to
// reinstantiate the 'queryPerformedByRepos' boolean
// [or we will need to wrap the repository in
// a 'RepositoryInterceptor'?]
// Also there's no real need for a DomainInterceptor to
// extend RewritingMBeanServerConnection.
/**
* A logger for this class.
**/
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
private final String domainName;
private volatile ObjectName ALL;
private final String serverName;
private volatile NotificationListener mbsListener;
private static class PatternNotificationFilter
implements NotificationFilter {
final ObjectName pattern;
public PatternNotificationFilter(ObjectName pattern) {
this.pattern = pattern;
}
public boolean isNotificationEnabled(Notification notification) {
if (!(notification instanceof MBeanServerNotification))
return false;
final MBeanServerNotification mbsn =
(MBeanServerNotification) notification;
if (pattern == null || pattern.apply(mbsn.getMBeanName()))
return true;
return false;
}
static final long serialVersionUID = 7409950927025262111L;
}
/**
* Creates a new instance of NamespaceInterceptor
*/
public DomainInterceptor(String serverName,
JMXDomain handler,
String domainName) {
super(handler);
this.domainName = domainName;
this.serverName = serverName;
}
@Override
public String toString() {
return this.getClass().getName()+"(parent="+serverName+
", domain="+this.domainName+")";
}
public void connectDelegate(final MBeanServerDelegate delegate)
throws InstanceNotFoundException {
final NotificationFilter filter =
new PatternNotificationFilter(getPatternFor(null));
synchronized (this) {
if (mbsListener == null)
mbsListener = new NotificationListener() {
public void handleNotification(Notification notification,
Object handback) {
if (filter.isNotificationEnabled(notification))
delegate.sendNotification(notification);
}
};
}
getNamespace().
addMBeanServerNotificationListener(mbsListener, filter);
}
public void disconnectDelegate()
throws InstanceNotFoundException, ListenerNotFoundException {
final NotificationListener l;
synchronized (this) {
l = mbsListener;
if (l == null) return;
mbsListener = null;
}
getNamespace().removeMBeanServerNotificationListener(l);
}
public void addPostRegisterTask(Queue<Runnable> queue,
final MBeanServerDelegate delegate) {
if (queue == null)
throw new IllegalArgumentException("task queue must not be null");
final Runnable task1 = new Runnable() {
public void run() {
try {
connectDelegate(delegate);
} catch (Exception x) {
throw new UnsupportedOperationException("notification forwarding",x);
}
}
};
queue.add(task1);
}
public void addPostDeregisterTask(Queue<Runnable> queue,
final MBeanServerDelegate delegate) {
if (queue == null)
throw new IllegalArgumentException("task queue must not be null");
final Runnable task1 = new Runnable() {
public void run() {
try {
disconnectDelegate();
} catch (Exception x) {
throw new UnsupportedOperationException("notification forwarding",x);
}
}
};
queue.add(task1);
}
/**
* Throws IllegalArgumentException if targetName.getDomain() is not
* in the domain handled.
**/
@Override
protected ObjectName toSource(ObjectName targetName) {
if (targetName == null) return null;
if (targetName.isDomainPattern()) return targetName;
final String targetDomain = targetName.getDomain();
// TODO: revisit this. RuntimeOperationsException may be better?
//
if (!targetDomain.equals(domainName))
throw new IllegalArgumentException(targetName.toString());
return targetName;
}
@Override
protected ObjectName toTarget(ObjectName sourceName) {
return sourceName;
}
/**
* No rewriting: always return sources - stripping instances for which
* the caller doesn't have permissions.
**/
@Override
Set<ObjectInstance> processOutputInstances(Set<ObjectInstance> sources) {
if (sources == null || sources.isEmpty() || !checkOn())
return sources;
final Set<ObjectInstance> res = Util.equivalentEmptySet(sources);
for (ObjectInstance o : sources) {
if (checkQuery(o.getObjectName(), "queryMBeans"))
res.add(o);
}
return res;
}
/**
* No rewriting: always return sourceNames - stripping names for which
* the caller doesn't have permissions.
**/
@Override
Set<ObjectName> processOutputNames(Set<ObjectName> sourceNames) {
if (sourceNames == null || sourceNames.isEmpty() || !checkOn())
return sourceNames;
final Set<ObjectName> res = Util.equivalentEmptySet(sourceNames);
for (ObjectName o : sourceNames) {
if (checkQuery(o, "queryNames"))
res.add(o);
}
return res;
}
/** No rewriting: always return source **/
@Override
ObjectInstance processOutputInstance(ObjectInstance source) {
return source;
}
@Override
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
try {
// We don't trust the wrapped JMXDomain...
final ObjectName pattern = getPatternFor(name);
final Set<ObjectName> res = super.queryNames(pattern,query);
return Util.filterMatchingNames(pattern,res);
} catch (Exception x) {
if (LOG.isLoggable(Level.FINE))
LOG.fine("Unexpected exception raised in queryNames: "+x);
LOG.log(Level.FINEST,"Unexpected exception raised in queryNames",x);
}
// We reach here only when an exception was raised.
//
final Set<ObjectName> empty = Collections.emptySet();
return empty;
}
private ObjectName getPatternFor(final ObjectName name) {
try {
if (ALL == null) ALL = ObjectName.getInstance(domainName + ":*");
if (name == null) return ALL;
if (name.getDomain().equals(domainName)) return name;
return name.withDomain(domainName);
} catch (MalformedObjectNameException x) {
throw new IllegalArgumentException(String.valueOf(name),x);
}
}
@Override
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
try {
// We don't trust the wrapped JMXDomain...
final ObjectName pattern = getPatternFor(name);
final Set<ObjectInstance> res = super.queryMBeans(pattern,query);
return Util.filterMatchingInstances(pattern,res);
} catch (Exception x) {
if (LOG.isLoggable(Level.FINE))
LOG.fine("Unexpected exception raised in queryNames: "+x);
LOG.log(Level.FINEST,"Unexpected exception raised in queryNames",x);
}
// We reach here only when an exception was raised.
//
final Set<ObjectInstance> empty = Collections.emptySet();
return empty;
}
@Override
public String getDefaultDomain() {
return domainName;
}
@Override
public String[] getDomains() {
return new String[] {domainName};
}
// We call getMBeanCount() on the namespace rather than on the
// source server in order to avoid counting MBeans which are not
// in the domain.
@Override
public Integer getMBeanCount() {
return getNamespace().getMBeanCount();
}
private boolean checkOn() {
final SecurityManager sm = System.getSecurityManager();
return (sm != null);
}
//
// Implements permission checks.
//
@Override
void check(ObjectName routingName, String member, String action) {
if (!checkOn()) return;
final String act = (action==null)?"-":action.intern();
if(act == "queryMBeans" || act == "queryNames") { // ES: OK
// This is tricky. check with 3 parameters is called
// by queryNames/queryMBeans before performing the query.
// At this point we must check with no class name.
// Therefore we pass a className of "-".
// The filtering will be done later - processOutputNames and
// processOutputInstance will call checkQuery.
//
check(routingName, "-", "-", act);
} else {
// This is also tricky:
// passing null here will cause check to retrieve the classname,
// if needed.
check(routingName, null, member, act);
}
}
//
// Implements permission checks.
//
@Override
void checkCreate(ObjectName routingName, String className, String action) {
if (!checkOn()) return;
check(routingName,className,"-",action);
}
//
// Implements permission checks.
//
void check(ObjectName routingName, String className, String member,
String action) {
if (!checkOn()) return;
final MBeanPermission perm;
// action is most probably already an intern string.
// string literals are intern strings.
// we create a new intern string for 'action' - just to be on
// the safe side...
// We intern it in order to be able to use == rather than equals
// below, because if we don't, and if action is not one of the
// 4 literals below, we would have to do a full string comparison.
//
final String act = (action==null)?"-":action.intern();
if (act == "getDomains") { // ES: OK
perm = new MBeanPermission(serverName,"-",member,
routingName,act);
} else {
final String clazz =
(className==null)?getClassName(routingName):className;
perm = new MBeanPermission(serverName,clazz,member,
routingName,act);
}
final SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(perm);
}
String getClassName(ObjectName routingName) {
if (routingName == null || routingName.isPattern()) return "-";
try {
return getNamespace().getSourceServer().
getObjectInstance(routingName).getClassName();
} catch (InstanceNotFoundException ex) {
LOG.finest("Can't get class name for "+routingName+
", using \"-\". Cause is: "+ex);
return "-";
}
}
//
// Implements permission filters for attributes...
//
@Override
AttributeList checkAttributes(ObjectName routingName,
AttributeList attributes, String action) {
if (!checkOn()) return attributes;
final String className = getClassName(routingName);
check(routingName,className,"-",action);
if (attributes == null || attributes.isEmpty()) return attributes;
final AttributeList res = new AttributeList();
for (Attribute at : attributes.asList()) {
try {
check(routingName,className,at.getName(),action);
res.add(at);
} catch (SecurityException x) { // DLS: OK
continue;
}
}
return res;
}
//
// Implements permission filters for attributes...
//
@Override
String[] checkAttributes(ObjectName routingName, String[] attributes,
String action) {
if (!checkOn()) return attributes;
final String className = getClassName(routingName);
check(routingName,className,"-",action);
if (attributes == null || attributes.length==0) return attributes;
final List<String> res = new ArrayList<String>(attributes.length);
for (String at : attributes) {
try {
check(routingName,className,at,action);
res.add(at);
} catch (SecurityException x) { // DLS: OK
continue;
}
}
return res.toArray(new String[res.size()]);
}
//
// Implements permission filters for domains...
//
@Override
String[] checkDomains(String[] domains, String action) {
if (domains == null || domains.length==0 || !checkOn())
return domains;
int count=0;
for (int i=0;i<domains.length;i++) {
try {
check(Util.newObjectName(domains[i]+":x=x"),"-",
"-","getDomains");
} catch (SecurityException x) { // DLS: OK
count++;
domains[i]=null;
}
}
if (count == 0) return domains;
final String[] res = new String[domains.length-count];
count = 0;
for (int i=0;i<domains.length;i++)
if (domains[i]!=null) res[count++]=domains[i];
return res;
}
//
// Implements permission filters for queries...
//
@Override
boolean checkQuery(ObjectName routingName, String action) {
try {
final String className = getClassName(routingName);
check(routingName,className,"-",action);
return true;
} catch (SecurityException x) { // DLS: OK
return false;
}
}
}

View File

@ -0,0 +1,577 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace;
import com.sun.jmx.defaults.JmxProperties;
import com.sun.jmx.interceptor.MBeanServerInterceptor;
import com.sun.jmx.mbeanserver.Util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.OperationsException;
import javax.management.QueryExp;
import javax.management.ReflectionException;
import javax.management.RuntimeOperationsException;
import javax.management.loading.ClassLoaderRepository;
import javax.management.namespace.JMXNamespace;
/**
* This interceptor wraps a JMXNamespace, and performs
* {@code ObjectName} rewriting. {@code HandlerInterceptor} are
* usually created and managed by a {@link NamespaceDispatcher} or
* {@link DomainDispatcher}.
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
public abstract class HandlerInterceptor<T extends JMXNamespace>
extends RoutingMBeanServerConnection<MBeanServer>
implements MBeanServerInterceptor {
/**
* A logger for this class.
**/
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
// The wrapped JMXNamespace
private final T handler;
/**
* Creates a new instance of HandlerInterceptor
*/
public HandlerInterceptor(T handler) {
if (handler == null) throw new IllegalArgumentException("null");
this.handler = handler;
}
@Override
protected MBeanServer source() {
return handler.getSourceServer();
}
// The MBeanServer on which getClassLoader / getClassLoaderFor
// will be called.
// The NamespaceInterceptor overrides this method - so that it
// getClassLoader / getClassLoaderFor don't trigger the loop
// detection mechanism.
//
MBeanServer getServerForLoading() {
return source();
}
T getNamespace() {
return handler;
}
// If the underlying JMXNamespace throws an IO, the IO will be
// wrapped in a RuntimeOperationsException.
RuntimeException handleIOException(IOException x,String fromMethodName,
Object... params) {
// Must do something here?
if (LOG.isLoggable(Level.FINEST)) {
LOG.finest("IO Exception in "+fromMethodName+": "+x+
" - "+" rethrowing as RuntimeOperationsException.");
}
throw new RuntimeOperationsException(
Util.newRuntimeIOException(x));
}
// From MBeanServer: catch & handles IOException
@Override
public AttributeList getAttributes(ObjectName name, String[] attributes)
throws InstanceNotFoundException, ReflectionException {
try {
return super.getAttributes(name, attributes);
} catch (IOException ex) {
throw handleIOException(ex,"getAttributes",name,attributes);
}
}
// From MBeanServer
public ClassLoader getClassLoaderFor(ObjectName mbeanName)
throws InstanceNotFoundException {
final ObjectName sourceName = toSourceOrRuntime(mbeanName);
try {
check(mbeanName,null,"getClassLoaderFor");
return getServerForLoading().getClassLoaderFor(sourceName);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// From MBeanServer
public ClassLoader getClassLoader(ObjectName loaderName)
throws InstanceNotFoundException {
final ObjectName sourceName = toSourceOrRuntime(loaderName);
try {
check(loaderName,null,"getClassLoader");
return getServerForLoading().getClassLoader(sourceName);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// From MBeanServer
public ObjectInstance registerMBean(Object object, ObjectName name)
throws InstanceAlreadyExistsException, MBeanRegistrationException,
NotCompliantMBeanException {
final ObjectName sourceName = newSourceMBeanName(name);
try {
checkCreate(name,object.getClass().getName(),"registerMBean");
return processOutputInstance(
source().registerMBean(object,sourceName));
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// From MBeanServer: catch & handles IOException
@Override
public void removeNotificationListener(ObjectName name, ObjectName listener)
throws InstanceNotFoundException, ListenerNotFoundException {
try {
super.removeNotificationListener(name, listener);
} catch (IOException ex) {
throw handleIOException(ex,"removeNotificationListener",name,listener);
}
}
// From MBeanServer: catch & handles IOException
@Override
public String getDefaultDomain() {
try {
return super.getDefaultDomain();
} catch (IOException ex) {
throw handleIOException(ex,"getDefaultDomain");
}
}
// From MBeanServer: catch & handles IOException
@Override
public String[] getDomains() {
try {
return super.getDomains();
} catch (IOException ex) {
throw handleIOException(ex,"getDomains");
}
}
// From MBeanServer: catch & handles IOException
@Override
public Integer getMBeanCount() {
try {
return super.getMBeanCount();
} catch (IOException ex) {
throw handleIOException(ex,"getMBeanCount");
}
}
// From MBeanServer: catch & handles IOException
@Override
public void setAttribute(ObjectName name, Attribute attribute)
throws InstanceNotFoundException, AttributeNotFoundException,
InvalidAttributeValueException, MBeanException,
ReflectionException {
try {
super.setAttribute(name, attribute);
} catch (IOException ex) {
throw handleIOException(ex,"setAttribute",name, attribute);
}
}
// From MBeanServer: catch & handles IOException
@Override
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
try {
return super.queryNames(name, query);
} catch (IOException ex) {
throw handleIOException(ex,"queryNames",name, query);
}
}
// From MBeanServer: catch & handles IOException
@Override
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
try {
return super.queryMBeans(name, query);
} catch (IOException ex) {
throw handleIOException(ex,"queryMBeans",name, query);
}
}
// From MBeanServer: catch & handles IOException
@Override
public boolean isInstanceOf(ObjectName name, String className)
throws InstanceNotFoundException {
try {
return super.isInstanceOf(name, className);
} catch (IOException ex) {
throw handleIOException(ex,"isInstanceOf",name, className);
}
}
// From MBeanServer: catch & handles IOException
@Override
public ObjectInstance createMBean(String className, ObjectName name)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException {
try {
return super.createMBean(className, name);
} catch (IOException ex) {
throw handleIOException(ex,"createMBean",className, name);
}
}
// From MBeanServer: catch & handles IOException
@Override
public ObjectInstance createMBean(String className, ObjectName name,
ObjectName loaderName)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException {
try {
return super.createMBean(className, name, loaderName);
} catch (IOException ex) {
throw handleIOException(ex,"createMBean",className, name, loaderName);
}
}
// From MBeanServer: catch & handles IOException
@Override
public Object getAttribute(ObjectName name, String attribute)
throws MBeanException, AttributeNotFoundException,
InstanceNotFoundException, ReflectionException {
try {
return super.getAttribute(name, attribute);
} catch (IOException ex) {
throw handleIOException(ex,"getAttribute",name, attribute);
}
}
// From MBeanServer: catch & handles IOException
@Override
public void removeNotificationListener(ObjectName name, ObjectName listener,
NotificationFilter filter, Object handback)
throws InstanceNotFoundException, ListenerNotFoundException {
try {
super.removeNotificationListener(name, listener, filter, handback);
} catch (IOException ex) {
throw handleIOException(ex,"removeNotificationListener",name,
listener, filter, handback);
}
}
// From MBeanServer: catch & handles IOException
@Override
public void removeNotificationListener(ObjectName name,
NotificationListener listener, NotificationFilter filter,
Object handback)
throws InstanceNotFoundException, ListenerNotFoundException {
try {
super.removeNotificationListener(name, listener, filter, handback);
} catch (IOException ex) {
throw handleIOException(ex,"removeNotificationListener",name,
listener, filter, handback);
}
}
// From MBeanServer: catch & handles IOException
@Override
public void removeNotificationListener(ObjectName name,
NotificationListener listener)
throws InstanceNotFoundException, ListenerNotFoundException {
try {
super.removeNotificationListener(name, listener);
} catch (IOException ex) {
throw handleIOException(ex,"removeNotificationListener",name,
listener);
}
}
// From MBeanServer: catch & handles IOException
@Override
public void addNotificationListener(ObjectName name,
NotificationListener listener, NotificationFilter filter,
Object handback) throws InstanceNotFoundException {
try {
super.addNotificationListener(name, listener, filter, handback);
} catch (IOException ex) {
throw handleIOException(ex,"addNotificationListener",name,
listener, filter, handback);
}
}
// From MBeanServer: catch & handles IOException
@Override
public void addNotificationListener(ObjectName name, ObjectName listener,
NotificationFilter filter, Object handback)
throws InstanceNotFoundException {
try {
super.addNotificationListener(name, listener, filter, handback);
} catch (IOException ex) {
throw handleIOException(ex,"addNotificationListener",name,
listener, filter, handback);
}
}
// From MBeanServer: catch & handles IOException
@Override
public boolean isRegistered(ObjectName name) {
try {
return super.isRegistered(name);
} catch (IOException ex) {
throw handleIOException(ex,"isRegistered",name);
}
}
// From MBeanServer: catch & handles IOException
@Override
public void unregisterMBean(ObjectName name)
throws InstanceNotFoundException, MBeanRegistrationException {
try {
super.unregisterMBean(name);
} catch (IOException ex) {
throw handleIOException(ex,"unregisterMBean",name);
}
}
// From MBeanServer: catch & handles IOException
@Override
public MBeanInfo getMBeanInfo(ObjectName name)
throws InstanceNotFoundException, IntrospectionException,
ReflectionException {
try {
return super.getMBeanInfo(name);
} catch (IOException ex) {
throw handleIOException(ex,"getMBeanInfo",name);
}
}
// From MBeanServer: catch & handles IOException
@Override
public ObjectInstance getObjectInstance(ObjectName name)
throws InstanceNotFoundException {
try {
return super.getObjectInstance(name);
} catch (IOException ex) {
throw handleIOException(ex,"getObjectInstance",name);
}
}
// From MBeanServer: catch & handles IOException
@Override
public ObjectInstance createMBean(String className, ObjectName name,
Object[] params, String[] signature)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException {
try {
return super.createMBean(className, name, params, signature);
} catch (IOException ex) {
throw handleIOException(ex,"createMBean",className, name,
params, signature);
}
}
// From MBeanServer: catch & handles IOException
@Override
public ObjectInstance createMBean(String className, ObjectName name,
ObjectName loaderName, Object[] params, String[] signature)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException {
try {
return super.createMBean(className, name, loaderName, params,
signature);
} catch (IOException ex) {
throw handleIOException(ex,"createMBean",className, name,loaderName,
params, signature);
}
}
// From MBeanServer: catch & handles IOException
@Override
public AttributeList setAttributes(ObjectName name,AttributeList attributes)
throws InstanceNotFoundException, ReflectionException {
try {
return super.setAttributes(name, attributes);
} catch (IOException ex) {
throw handleIOException(ex,"setAttributes",name, attributes);
}
}
// From MBeanServer: catch & handles IOException
@Override
public Object invoke(ObjectName name, String operationName, Object[] params,
String[] signature)
throws InstanceNotFoundException, MBeanException, ReflectionException {
try {
return super.invoke(name, operationName, params, signature);
} catch (IOException ex) {
throw handleIOException(ex,"invoke",name, operationName,
params, signature);
}
}
//
// These methods are inherited from MBeanServer....
//
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
public Object instantiate(String className)
throws ReflectionException, MBeanException {
if (LOG.isLoggable(Level.FINE))
LOG.fine("call to unsupported instantiate method: " +
"trowing UnsupportedOperationException");
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
public Object instantiate(String className, ObjectName loaderName)
throws ReflectionException, MBeanException,
InstanceNotFoundException {
if (LOG.isLoggable(Level.FINE))
LOG.fine("call to unsupported method: instantiate(...) -" +
"throwing UnsupportedOperationException");
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
public Object instantiate(String className, Object[] params,
String[] signature) throws ReflectionException, MBeanException {
if (LOG.isLoggable(Level.FINE))
LOG.fine("call to unsupported method: instantiate(...) -" +
"throwing UnsupportedOperationException");
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
public Object instantiate(String className, ObjectName loaderName,
Object[] params, String[] signature)
throws ReflectionException, MBeanException,
InstanceNotFoundException {
if (LOG.isLoggable(Level.FINE))
LOG.fine("call to unsupported method: instantiate(...) -" +
"throwing UnsupportedOperationException");
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
@Deprecated
public ObjectInputStream deserialize(ObjectName name, byte[] data)
throws InstanceNotFoundException, OperationsException {
if (LOG.isLoggable(Level.FINE))
LOG.fine("call to unsupported method: deserialize(...) -" +
"throwing UnsupportedOperationException");
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
@Deprecated
public ObjectInputStream deserialize(String className, byte[] data)
throws OperationsException, ReflectionException {
if (LOG.isLoggable(Level.FINE))
LOG.fine("call to unsupported method: deserialize(...) -" +
"throwing UnsupportedOperationException");
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
@Deprecated
public ObjectInputStream deserialize(String className,
ObjectName loaderName, byte[] data)
throws InstanceNotFoundException, OperationsException,
ReflectionException {
if (LOG.isLoggable(Level.FINE))
LOG.fine("call to unsupported method: deserialize(...) -" +
"throwing UnsupportedOperationException");
throw new UnsupportedOperationException("Not applicable.");
}
/**
* This method should never be called.
* Throws UnsupportedOperationException.
*/
public ClassLoaderRepository getClassLoaderRepository() {
if (LOG.isLoggable(Level.FINE))
LOG.fine("call to unsupported method: getClassLoaderRepository() -" +
"throwing UnsupportedOperationException");
throw new UnsupportedOperationException("Not applicable.");
}
static RuntimeException newUnsupportedException(String namespace) {
return new RuntimeOperationsException(
new UnsupportedOperationException(
"Not supported in this namespace: "+namespace));
}
}

View File

@ -0,0 +1,369 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace;
import com.sun.jmx.defaults.JmxProperties;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanServerConnection;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.event.EventClient;
import javax.management.namespace.JMXNamespaces;
import javax.management.remote.JMXAddressable;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXServiceURL;
import javax.security.auth.Subject;
/**
* A collection of methods that provide JMXConnector wrappers for
* JMXRemoteNamepaces underlying connectors.
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
public final class JMXNamespaceUtils {
/**
* A logger for this class.
**/
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
private static <K,V> Map<K,V> newWeakHashMap() {
return new WeakHashMap<K,V>();
}
/** Creates a new instance of JMXNamespaces */
private JMXNamespaceUtils() {
}
/**
* Returns an unmodifiable option map in which the given keys have been
* filtered out.
* @param keys keys to filter out from the map.
* @return An unmodifiable option map in which the given keys have been
* filtered out.
*/
public static <K,V> Map<K,V> filterMap(Map<K,V> map, K... keys) {
final Map<K,V> filtered;
filtered=new HashMap<K,V>(map);
for (K key : keys) {
filtered.remove(key);
}
return unmodifiableMap(filtered);
}
// returns un unmodifiable view of a map.
public static <K,V> Map<K,V> unmodifiableMap(Map<K,V> aMap) {
if (aMap == null || aMap.isEmpty())
return Collections.emptyMap();
return Collections.unmodifiableMap(aMap);
}
/**
* A base class that helps writing JMXConnectors that return
* MBeanServerConnection wrappers.
* This base class wraps an inner JMXConnector (the source), and preserve
* its caching policy. If a connection is cached in the source, its wrapper
* will be cached in this connector too.
* Author's note: rewriting this with java.lang.reflect.Proxy could be
* envisaged. It would avoid the combinatory sub-classing introduced by
* JMXAddressable.
* <p>
* Note: all the standard JMXConnector implementations are serializable.
* This implementation here is not. Should it be?
* I believe it must not be serializable unless it becomes
* part of a public API (either standard or officially exposed
* and supported in a documented com.sun package)
**/
static class JMXCachingConnector
implements JMXConnector {
// private static final long serialVersionUID = -2279076110599707875L;
final JMXConnector source;
// if this object is made serializable, then the variable below
// needs to become volatile transient and be lazyly-created...
private final
Map<MBeanServerConnection,MBeanServerConnection> connectionMap;
public JMXCachingConnector(JMXConnector source) {
this.source = checkNonNull(source, "source");
connectionMap = newWeakHashMap();
}
private MBeanServerConnection
getCached(MBeanServerConnection inner) {
return connectionMap.get(inner);
}
private MBeanServerConnection putCached(final MBeanServerConnection inner,
final MBeanServerConnection wrapper) {
if (inner == wrapper) return wrapper;
synchronized (this) {
final MBeanServerConnection concurrent =
connectionMap.get(inner);
if (concurrent != null) return concurrent;
connectionMap.put(inner,wrapper);
}
return wrapper;
}
public void addConnectionNotificationListener(NotificationListener
listener, NotificationFilter filter, Object handback) {
source.addConnectionNotificationListener(listener,filter,handback);
}
public void close() throws IOException {
source.close();
}
public void connect() throws IOException {
source.connect();
}
public void connect(Map<String,?> env) throws IOException {
source.connect(env);
}
public String getConnectionId() throws IOException {
return source.getConnectionId();
}
/**
* Preserve caching policy of the underlying connector.
**/
public MBeanServerConnection
getMBeanServerConnection() throws IOException {
final MBeanServerConnection inner =
source.getMBeanServerConnection();
final MBeanServerConnection cached = getCached(inner);
if (cached != null) return cached;
final MBeanServerConnection wrapper = wrap(inner);
return putCached(inner,wrapper);
}
public MBeanServerConnection
getMBeanServerConnection(Subject delegationSubject)
throws IOException {
final MBeanServerConnection wrapped =
source.getMBeanServerConnection(delegationSubject);
synchronized (this) {
final MBeanServerConnection cached = getCached(wrapped);
if (cached != null) return cached;
final MBeanServerConnection wrapper =
wrapWithSubject(wrapped,delegationSubject);
return putCached(wrapped,wrapper);
}
}
public void removeConnectionNotificationListener(
NotificationListener listener)
throws ListenerNotFoundException {
source.removeConnectionNotificationListener(listener);
}
public void removeConnectionNotificationListener(
NotificationListener l, NotificationFilter f,
Object handback) throws ListenerNotFoundException {
source.removeConnectionNotificationListener(l,f,handback);
}
/**
* This is the method that subclass will redefine. This method
* is called by {@code this.getMBeanServerConnection()}.
* {@code inner} is the connection returned by
* {@code source.getMBeanServerConnection()}.
**/
protected MBeanServerConnection wrap(MBeanServerConnection inner)
throws IOException {
return inner;
}
/**
* Subclass may also want to redefine this method.
* By default it calls wrap(inner). This method
* is called by {@code this.getMBeanServerConnection(Subject)}.
* {@code inner} is the connection returned by
* {@code source.getMBeanServerConnection(Subject)}.
**/
protected MBeanServerConnection wrapWithSubject(
MBeanServerConnection inner, Subject delegationSubject)
throws IOException {
return wrap(inner);
}
@Override
public String toString() {
if (source instanceof JMXAddressable) {
final JMXServiceURL address =
((JMXAddressable)source).getAddress();
if (address != null)
return address.toString();
}
return source.toString();
}
}
/**
* The name space connector can do 'cd'
**/
static class JMXNamespaceConnector extends JMXCachingConnector {
// private static final long serialVersionUID = -4813611540843020867L;
private final String toDir;
private final boolean closeable;
public JMXNamespaceConnector(JMXConnector source, String toDir,
boolean closeable) {
super(source);
this.toDir = toDir;
this.closeable = closeable;
}
@Override
public void close() throws IOException {
if (!closeable)
throw new UnsupportedOperationException("close");
else super.close();
}
@Override
protected MBeanServerConnection wrap(MBeanServerConnection wrapped)
throws IOException {
if (LOG.isLoggable(Level.FINER))
LOG.finer("Creating name space proxy connection for source: "+
"namespace="+toDir);
return JMXNamespaces.narrowToNamespace(wrapped,toDir);
}
@Override
public String toString() {
return "JMXNamespaces.narrowToNamespace("+
super.toString()+
", \""+toDir+"\")";
}
}
static class JMXEventConnector extends JMXCachingConnector {
// private static final long serialVersionUID = 4742659236340242785L;
JMXEventConnector(JMXConnector wrapped) {
super(wrapped);
}
@Override
protected MBeanServerConnection wrap(MBeanServerConnection inner)
throws IOException {
return EventClient.getEventClientConnection(inner);
}
@Override
public String toString() {
return "EventClient.withEventClient("+super.toString()+")";
}
}
static class JMXAddressableEventConnector extends JMXEventConnector
implements JMXAddressable {
// private static final long serialVersionUID = -9128520234812124712L;
JMXAddressableEventConnector(JMXConnector wrapped) {
super(wrapped);
}
public JMXServiceURL getAddress() {
return ((JMXAddressable)source).getAddress();
}
}
/**
* Creates a connector whose MBeamServerConnection will point to the
* given sub name space inside the source connector.
* @see JMXNamespace
**/
public static JMXConnector cd(final JMXConnector source,
final String toNamespace,
final boolean closeable)
throws IOException {
checkNonNull(source, "JMXConnector");
if (toNamespace == null || toNamespace.equals(""))
return source;
return new JMXNamespaceConnector(source,toNamespace,closeable);
}
/**
* Returns a JMX Connector that will use an {@link EventClient}
* to subscribe for notifications. If the server doesn't have
* an {@link EventClientDelegateMBean}, then the connector will
* use the legacy notification mechanism instead.
*
* @param source The underlying JMX Connector wrapped by the returned
* connector.
* @return A JMX Connector that will uses an {@link EventClient}, if
* available.
* @see EventClient#getEventClientConnection(MBeanServerConnection)
*/
public static JMXConnector withEventClient(final JMXConnector source) {
checkNonNull(source, "JMXConnector");
if (source instanceof JMXAddressable)
return new JMXAddressableEventConnector(source);
else
return new JMXEventConnector(source);
}
public static <T> T checkNonNull(T parameter, String name) {
if (parameter == null)
throw new IllegalArgumentException(name+" must not be null");
return parameter;
}
}

View File

@ -0,0 +1,449 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace;
import com.sun.jmx.defaults.JmxProperties;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Logger;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.namespace.JMXNamespaces;
import javax.management.namespace.JMXNamespace;
import javax.management.namespace.JMXNamespacePermission;
/**
* A NamespaceInterceptor wraps a JMXNamespace, performing
* ObjectName rewriting.
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
/**
* A logger for this class.
**/
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
private static final Logger PROBE_LOG = Logger.getLogger(
JmxProperties.NAMESPACE_LOGGER+".probe");
// The target name space in which the NamepsaceHandler is mounted.
private final String targetNs;
private final String serverName;
private final ObjectNameRouter proc;
/**
* Internal hack. The JMXRemoteNamespace can be closed and reconnected.
* Each time the JMXRemoteNamespace connects, a probe should be sent
* to detect cycle. The MBeanServer exposed by JMXRemoteNamespace thus
* implements the DynamicProbe interface, which makes it possible for
* this handler to know that it should send a new probe.
*
* XXX: TODO this probe thing is way too complex and fragile.
* This *must* go away or be replaced by something simpler.
* ideas are welcomed.
**/
public static interface DynamicProbe {
public boolean isProbeRequested();
}
/**
* Creates a new instance of NamespaceInterceptor
*/
public NamespaceInterceptor(
String serverName,
JMXNamespace handler,
String targetNamespace) {
super(handler);
this.serverName = serverName;
this.targetNs =
ObjectNameRouter.normalizeNamespacePath(targetNamespace,
true, true, false);
proc = new ObjectNameRouter(targetNamespace, "");
}
@Override
public String toString() {
return this.getClass().getName()+"(parent="+serverName+
", namespace="+this.targetNs+")";
}
/*
* XXX: TODO this probe thing is way too complex and fragile.
* This *must* go away or be replaced by something simpler.
* ideas are welcomed.
*/
private volatile boolean probed = false;
private volatile ObjectName probe;
// Query Pattern that we will send through the source server in order
// to detect self-linking namespaces.
//
// XXX: TODO this probe thing is way too complex and fragile.
// This *must* go away or be replaced by something simpler.
// ideas are welcomed.
final ObjectName makeProbePattern(ObjectName probe)
throws MalformedObjectNameException {
// we could probably link the probe pattern with the probe - e.g.
// using the UUID as key in the pattern - but is it worth it? it
// also has some side effects on the context namespace - because
// such a probe may get rejected by the jmx.context// namespace.
//
// The trick here is to devise a pattern that is not likely to
// be blocked by intermediate levels. Querying for all namespace
// handlers in the source (or source namespace) is more likely to
// achieve this goal.
//
return ObjectName.getInstance("*" +
JMXNamespaces.NAMESPACE_SEPARATOR + ":" +
JMXNamespace.TYPE_ASSIGNMENT);
}
// tell whether the name pattern corresponds to what might have been
// sent as a probe.
// XXX: TODO this probe thing is way too complex and fragile.
// This *must* go away or be replaced by something simpler.
// ideas are welcomed.
final boolean isProbePattern(ObjectName name) {
final ObjectName p = probe;
if (p == null) return false;
try {
return String.valueOf(name).endsWith(targetNs+
JMXNamespaces.NAMESPACE_SEPARATOR + "*" +
JMXNamespaces.NAMESPACE_SEPARATOR + ":" +
JMXNamespace.TYPE_ASSIGNMENT);
} catch (RuntimeException x) {
// should not happen.
PROBE_LOG.finest("Ignoring unexpected exception in self link detection: "+
x);
return false;
}
}
// The first time a request reaches this NamespaceInterceptor, the
// interceptor will send a probe to detect whether the underlying
// JMXNamespace links to itslef.
//
// One way to create such self-linking namespace would be for instance
// to create a JMXNamespace whose getSourceServer() method would return:
// JMXNamespaces.narrowToNamespace(getMBeanServer(),
// getObjectName().getDomain())
//
// If such an MBeanServer is returned, then any call to that MBeanServer
// will trigger an infinite loop.
// There can be even trickier configurations if remote connections are
// involved.
//
// In order to prevent this from happening, the NamespaceInterceptor will
// send a probe, in an attempt to detect whether it will receive it at
// the other end. If the probe is received, an exception will be thrown
// in order to break the recursion. The probe is only sent once - when
// the first request to the namespace occurs. The DynamicProbe interface
// can also be used by a Sun JMXNamespace implementation to request the
// emission of a probe at any time (see JMXRemoteNamespace
// implementation).
//
// Probes work this way: the NamespaceInterceptor sets a flag and sends
// a queryNames() request. If a queryNames() request comes in when the flag
// is on, then it deduces that there is a self-linking loop - and instead
// of calling queryNames() on the source MBeanServer of the JMXNamespace
// handler (which would cause the loop to go on) it breaks the recursion
// by returning the probe ObjectName.
// If the NamespaceInterceptor receives the probe ObjectName as result of
// its original sendProbe() request it knows that it has been looping
// back on itslef and throws an IOException...
//
//
// XXX: TODO this probe thing is way too complex and fragile.
// This *must* go away or be replaced by something simpler.
// ideas are welcomed.
//
final void sendProbe(MBeanServerConnection msc)
throws IOException {
try {
PROBE_LOG.fine("Sending probe");
// This is just to prevent any other thread to modify
// the probe while the detection cycle is in progress.
//
final ObjectName probePattern;
// we don't want to synchronize on this - we use targetNs
// because it's non null and final.
synchronized (targetNs) {
probed = false;
if (probe != null) {
throw new IOException("concurent connection in progress");
}
final String uuid = UUID.randomUUID().toString();
final String endprobe =
JMXNamespaces.NAMESPACE_SEPARATOR + uuid +
":type=Probe,key="+uuid;
final ObjectName newprobe =
ObjectName.getInstance(endprobe);
probePattern = makeProbePattern(newprobe);
probe = newprobe;
}
try {
PROBE_LOG.finer("Probe query: "+probePattern+" expecting: "+probe);
final Set<ObjectName> res = msc.queryNames(probePattern, null);
final ObjectName expected = probe;
PROBE_LOG.finer("Probe res: "+res);
if (res.contains(expected)) {
throw new IOException("namespace " +
targetNs + " is linking to itself: " +
"cycle detected by probe");
}
} catch (SecurityException x) {
PROBE_LOG.finer("Can't check for cycles: " + x);
// can't do anything....
} catch (RuntimeException x) {
PROBE_LOG.finer("Exception raised by queryNames: " + x);
throw x;
} finally {
probe = null;
}
} catch (MalformedObjectNameException x) {
final IOException io =
new IOException("invalid name space: probe failed");
io.initCause(x);
throw io;
}
PROBE_LOG.fine("Probe returned - no cycles");
probed = true;
}
// allows a Sun implementation JMX Namespace, such as the
// JMXRemoteNamespace, to control when a probe should be sent.
//
// XXX: TODO this probe thing is way too complex and fragile.
// This *must* go away or be replaced by something simpler.
// ideas are welcomed.
private boolean isProbeRequested(Object o) {
if (o instanceof DynamicProbe)
return ((DynamicProbe)o).isProbeRequested();
return false;
}
/**
* This method will send a probe to detect self-linking name spaces.
* A self linking namespace is a namespace that links back directly
* on itslef. Calling a method on such a name space always results
* in an infinite loop going through:
* [1]MBeanServer -> [2]NamespaceDispatcher -> [3]NamespaceInterceptor
* [4]JMXNamespace -> { network // or cd // or ... } -> [5]MBeanServer
* with exactly the same request than [1]...
*
* The namespace interceptor [2] tries to detect such condition the
* *first time* that the connection is used. It does so by setting
* a flag, and sending a queryNames() through the name space. If the
* queryNames comes back, it knows that there's a loop.
*
* The DynamicProbe interface can also be used by a Sun JMXNamespace
* implementation to request the emission of a probe at any time
* (see JMXRemoteNamespace implementation).
*/
private MBeanServer connection() {
try {
final MBeanServer c = super.source();
if (probe != null) // should not happen
throw new RuntimeException("connection is being probed");
if (probed == false || isProbeRequested(c)) {
try {
// Should not happen if class well behaved.
// Never probed. Force it.
//System.err.println("sending probe for " +
// "target="+targetNs+", source="+srcNs);
sendProbe(c);
} catch (IOException io) {
throw new RuntimeException(io.getMessage(), io);
}
}
if (c != null) {
return c;
}
} catch (RuntimeException x) {
throw x;
}
throw new NullPointerException("getMBeanServerConnection");
}
@Override
protected MBeanServer source() {
return connection();
}
@Override
protected MBeanServer getServerForLoading() {
// don't want to send probe on getClassLoader/getClassLoaderFor
return super.source();
}
/**
* Calls {@link MBeanServerConnection#queryNames queryNames}
* on the underlying
* {@link #getMBeanServerConnection MBeanServerConnection}.
**/
@Override
public final Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
// XXX: TODO this probe thing is way too complex and fragile.
// This *must* go away or be replaced by something simpler.
// ideas are welcomed.
PROBE_LOG.finer("probe is: "+probe+" pattern is: "+name);
if (probe != null && isProbePattern(name)) {
PROBE_LOG.finer("Return probe: "+probe);
return Collections.singleton(probe);
}
return super.queryNames(name, query);
}
@Override
protected ObjectName toSource(ObjectName targetName)
throws MalformedObjectNameException {
return proc.toSourceContext(targetName, true);
}
@Override
protected ObjectName toTarget(ObjectName sourceName)
throws MalformedObjectNameException {
return proc.toTargetContext(sourceName, false);
}
//
// Implements permission checks.
//
@Override
void check(ObjectName routingName, String member, String action) {
final SecurityManager sm = System.getSecurityManager();
if (sm == null) return;
if ("getDomains".equals(action)) return;
final JMXNamespacePermission perm =
new JMXNamespacePermission(serverName,member,
routingName,action);
sm.checkPermission(perm);
}
@Override
void checkCreate(ObjectName routingName, String className, String action) {
final SecurityManager sm = System.getSecurityManager();
if (sm == null) return;
final JMXNamespacePermission perm =
new JMXNamespacePermission(serverName,className,
routingName,action);
sm.checkPermission(perm);
}
//
// Implements permission filters for attributes...
//
@Override
AttributeList checkAttributes(ObjectName routingName,
AttributeList attributes, String action) {
check(routingName,null,action);
if (attributes == null || attributes.isEmpty()) return attributes;
final SecurityManager sm = System.getSecurityManager();
if (sm == null) return attributes;
final AttributeList res = new AttributeList();
for (Attribute at : attributes.asList()) {
try {
check(routingName,at.getName(),action);
res.add(at);
} catch (SecurityException x) { // DLS: OK
continue;
}
}
return res;
}
//
// Implements permission filters for attributes...
//
@Override
String[] checkAttributes(ObjectName routingName, String[] attributes,
String action) {
check(routingName,null,action);
if (attributes == null || attributes.length==0) return attributes;
final SecurityManager sm = System.getSecurityManager();
if (sm == null) return attributes;
final List<String> res = new ArrayList<String>(attributes.length);
for (String at : attributes) {
try {
check(routingName,at,action);
res.add(at);
} catch (SecurityException x) { // DLS: OK
continue;
}
}
return res.toArray(new String[res.size()]);
}
//
// Implements permission filters for domains...
//
@Override
String[] checkDomains(String[] domains, String action) {
// in principle, this method is never called because
// getDomains() will never be called - since there's
// no way that MBeanServer.getDomains() can be routed
// to a NamespaceInterceptor.
//
// This is also why there's no getDomains() in a
// JMXNamespacePermission...
//
return super.checkDomains(domains, action);
}
//
// Implements permission filters for queries...
//
@Override
boolean checkQuery(ObjectName routingName, String action) {
try {
check(routingName,null,action);
return true;
} catch (SecurityException x) { // DLS: OK
return false;
}
}
}

View File

@ -0,0 +1,191 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace;
import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
/**
* The ObjectNameRouter is used to rewrite routing object names.
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
public class ObjectNameRouter {
private static final int NAMESPACE_SEPARATOR_LENGTH =
NAMESPACE_SEPARATOR.length();
final String targetPrefix;
final String sourcePrefix;
final int slen;
final int tlen;
final boolean identity;
public ObjectNameRouter(String targetDirName) {
this(targetDirName,null);
}
/** Creates a new instance of ObjectNameRouter */
public ObjectNameRouter(final String remove, final String add) {
this.targetPrefix = (remove==null?"":remove);
this.sourcePrefix = (add==null?"":add);
tlen = targetPrefix.length();
slen = sourcePrefix.length();
identity = targetPrefix.equals(sourcePrefix);
}
public final ObjectName toTargetContext(ObjectName sourceName,
boolean removeLeadingSeparators) {
if (sourceName == null) return null;
if (identity) return sourceName;
String srcDomain = sourceName.getDomain();
// if the ObjectName starts with // and removeLeadingSeparators is
// true, then recursively strip leading //.
// Otherwise, do not rewrite ObjectName.
//
if (srcDomain.startsWith(NAMESPACE_SEPARATOR)) {
if (!removeLeadingSeparators) return sourceName;
else srcDomain = normalizeDomain(srcDomain,true);
}
if (slen != 0) {
if (!srcDomain.startsWith(sourcePrefix) ||
!srcDomain.startsWith(NAMESPACE_SEPARATOR,slen))
throw new IllegalArgumentException(
"ObjectName does not start with expected prefix "
+ sourcePrefix + ": " +
String.valueOf(sourceName));
srcDomain = srcDomain.substring(slen+NAMESPACE_SEPARATOR_LENGTH);
}
final String targetDomain =
(tlen>0?targetPrefix+NAMESPACE_SEPARATOR+srcDomain:srcDomain);
try {
return sourceName.withDomain(targetDomain);
} catch (MalformedObjectNameException x) {
throw new IllegalArgumentException(String.valueOf(sourceName),x);
}
}
public final ObjectName toSourceContext(ObjectName targetName,
boolean removeLeadingSeparators) {
if (targetName == null) return null;
if (identity) return targetName;
String targetDomain = targetName.getDomain();
if (targetDomain.startsWith(NAMESPACE_SEPARATOR)) {
if (!removeLeadingSeparators) return targetName;
else targetDomain =
normalizeDomain(targetDomain,true);
}
if (tlen != 0) {
if (!targetDomain.startsWith(targetPrefix) ||
!targetDomain.startsWith(NAMESPACE_SEPARATOR,tlen))
throw new IllegalArgumentException(
"ObjectName does not start with expected prefix "
+ targetPrefix + ": " +
String.valueOf(targetName));
targetDomain = targetDomain.
substring(tlen+NAMESPACE_SEPARATOR_LENGTH);
}
final String sourceDomain =
(slen>0?sourcePrefix+NAMESPACE_SEPARATOR+targetDomain:
targetDomain);
try {
return targetName.withDomain(sourceDomain);
} catch (MalformedObjectNameException x) {
throw new IllegalArgumentException(String.valueOf(targetName),x);
}
}
public final ObjectInstance toTargetContext(ObjectInstance sourceMoi,
boolean removeLeadingSeparators) {
if (sourceMoi == null) return null;
if (identity) return sourceMoi;
return new ObjectInstance(
toTargetContext(sourceMoi.getObjectName(),
removeLeadingSeparators),
sourceMoi.getClassName());
}
/**
* Removes leading, trailing, or duplicate // in a name space path.
**/
public static String normalizeDomain(String domain,
boolean removeLeadingSep) {
return normalizeNamespacePath(domain,removeLeadingSep,false,true);
}
/**
* Removes leading, trailing, or duplicate // in a name space path.
**/
public static String normalizeNamespacePath(String namespacePath,
boolean removeLeadingSep,
boolean removeTrailingSep,
boolean endsWithDomain) {
if (namespacePath.equals(""))
return "";
final String[] components = namespacePath.split(NAMESPACE_SEPARATOR);
final StringBuilder b =
new StringBuilder(namespacePath.length()+NAMESPACE_SEPARATOR_LENGTH);
String sep = null;
if (!removeLeadingSep && namespacePath.startsWith(NAMESPACE_SEPARATOR))
b.append(NAMESPACE_SEPARATOR);
int count = 0;
for (int i=0; i<components.length; i++) {
final String n=components[i];
if (n.equals("")) continue;
if (n.startsWith("/")||n.endsWith("/")) {
// throw exception unless we're looking at the last domain
// part of the ObjectName
if (! (endsWithDomain && i==(components.length-1))) {
throw new IllegalArgumentException(n+
" is not a valid name space identifier");
} else {
// There's a dirty little corner case when the domain
// part (last item) is exactly '/' - in that case we must
// not append '//'
//
removeTrailingSep = removeTrailingSep || n.equals("/");
}
}
if (sep != null) b.append(sep);
b.append(n);
sep = NAMESPACE_SEPARATOR;
count++;
}
if (!removeTrailingSep && namespacePath.endsWith(NAMESPACE_SEPARATOR)
&& count > 0)
b.append(NAMESPACE_SEPARATOR);
return b.toString();
}
}

View File

@ -0,0 +1,132 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace;
import com.sun.jmx.defaults.JmxProperties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.MBeanServerConnection;
import javax.management.namespace.JMXNamespaces;
/**
* A RoutingConnectionProxy is an MBeanServerConnection proxy that proxies a
* source name space in a source MBeanServerConnection.
* It wraps a source MBeanServerConnection, and rewrites routing
* ObjectNames. It is used to implement
* {@code JMXNamespaces.narrowToNamespace(MBeanServerConnection)}.
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
public class RoutingConnectionProxy
extends RoutingProxy<MBeanServerConnection> {
/**
* A logger for this class.
**/
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
/**
* Creates a new instance of RoutingConnectionProxy
*/
public RoutingConnectionProxy(MBeanServerConnection source,
String sourceDir) {
this(source,sourceDir,"",false);
}
/**
* Creates a new instance of RoutingConnectionProxy
*/
public RoutingConnectionProxy(MBeanServerConnection source,
String sourceDir,
String targetDir,
boolean forwardsContext) {
super(source,sourceDir,targetDir,forwardsContext);
if (LOG.isLoggable(Level.FINER))
LOG.finer("RoutingConnectionProxy for " + getSourceNamespace() +
" created");
}
@Override
public String toString() {
final String targetNs = getTargetNamespace();
final String sourceNs = getSourceNamespace();
String wrapped = String.valueOf(source());
if ("".equals(targetNs)) {
if (forwardsContext)
wrapped = "ClientContext.withDynamicContext("+wrapped+")";
return "JMXNamespaces.narrowToNamespace("+
wrapped+", \""+
sourceNs+"\")";
}
return this.getClass().getSimpleName()+"("+wrapped+", \""+
sourceNs+"\", \""+
targetNs+"\", "+forwardsContext+")";
}
public static MBeanServerConnection cd(MBeanServerConnection source,
String sourcePath) {
if (source == null) throw new IllegalArgumentException("null");
if (source.getClass().equals(RoutingConnectionProxy.class)) {
// cast is OK here, but findbugs complains unless we use class.cast
final RoutingConnectionProxy other =
RoutingConnectionProxy.class.cast(source);
final String target = other.getTargetNamespace();
// Avoid multiple layers of serialization.
//
// We construct a new proxy from the original source instead of
// stacking a new proxy on top of the old one.
// - that is we replace
// cd ( cd ( x, dir1), dir2);
// by
// cd (x, dir1//dir2);
//
// We can do this only when the source class is exactly
// NamespaceConnectionProxy.
//
if (target == null || target.equals("")) {
final String path =
JMXNamespaces.concat(other.getSourceNamespace(),
sourcePath);
return new RoutingConnectionProxy(other.source(),path,"",
other.forwardsContext);
}
// Note: we could do possibly something here - but it would involve
// removing part of targetDir, and possibly adding
// something to sourcePath.
// Too complex to bother! => simply default to stacking...
}
return new RoutingConnectionProxy(source,sourcePath);
}
}

View File

@ -0,0 +1,671 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace;
import com.sun.jmx.defaults.JmxProperties;
import com.sun.jmx.mbeanserver.Util;
import java.io.IOException;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.JMRuntimeException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.ReflectionException;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException;
/**
* A RoutingMBeanServerConnection wraps a MBeanServerConnection, defining
* abstract methods that can be implemented by subclasses to rewrite
* routing ObjectNames. It is used to implement
* HandlerInterceptors (wrapping JMXNamespace instances) and routing
* proxies (used to implement cd operations).
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnection>
implements MBeanServerConnection {
/**
* A logger for this class.
**/
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
/**
* Creates a new instance of RoutingMBeanServerConnection
*/
public RoutingMBeanServerConnection() {
}
/**
* Returns the wrapped source connection.
**/
protected abstract T source() throws IOException;
/**
* Converts a target ObjectName to a source ObjectName.
**/
protected abstract ObjectName toSource(ObjectName targetName)
throws MalformedObjectNameException;
/**
* Converts a source ObjectName to a target ObjectName.
**/
protected abstract ObjectName toTarget(ObjectName sourceName)
throws MalformedObjectNameException;
/**
* Can be overridden by subclasses to check the validity of a new
* ObjectName used in createMBean or registerMBean.
* This method is typically used by subclasses which might require
* special handling for "null";
**/
protected ObjectName newSourceMBeanName(ObjectName targetName)
throws MBeanRegistrationException {
try {
return toSource(targetName);
} catch (Exception x) {
throw new MBeanRegistrationException(x,"Illegal MBean Name");
}
}
// Calls toSource(), Wraps MalformedObjectNameException.
ObjectName toSourceOrRuntime(ObjectName targetName)
throws RuntimeOperationsException {
try {
return toSource(targetName);
} catch (MalformedObjectNameException x) {
final IllegalArgumentException x2 =
new IllegalArgumentException(String.valueOf(targetName),x);
final RuntimeOperationsException x3 =
new RuntimeOperationsException(x2);
throw x3;
}
}
// Wraps given exception if needed.
RuntimeException makeCompliantRuntimeException(Exception x) {
if (x instanceof SecurityException) return (SecurityException)x;
if (x instanceof JMRuntimeException) return (JMRuntimeException)x;
if (x instanceof RuntimeException)
return new RuntimeOperationsException((RuntimeException)x);
if (x instanceof IOException)
return Util.newRuntimeIOException((IOException)x);
// shouldn't come here...
final RuntimeException x2 = new UndeclaredThrowableException(x);
return new RuntimeOperationsException(x2);
}
/**
* This method is a hook to implement permission checking in subclasses.
* By default, this method does nothing and simply returns
* {@code attribute}.
*
* @param routingName The name of the MBean in the enclosing context.
* This is of the form {@code <namespace>//<ObjectName>}.
* @param attributes The list of attributes to check permission for.
* @param action one of "getAttribute" or "setAttribute"
* @return The list of attributes for which the callers has the
* appropriate {@link
* javax.management.namespace.JMXNamespacePermission}.
*/
String[] checkAttributes(ObjectName routingName,
String[] attributes, String action) {
check(routingName,null,action);
return attributes;
}
/**
* This method is a hook to implement permission checking in subclasses.
* By default, this method does nothing and simply returns
* {@code attribute}.
*
* @param routingName The name of the MBean in the enclosing context.
* This is of the form {@code <namespace>//<ObjectName>}.
* @param attributes The list of attributes to check permission for.
* @param action one of "getAttribute" or "setAttribute"
* @return The list of attributes for which the callers has the
* appropriate {@link
* javax.management.namespace.JMXNamespacePermission}.
*/
AttributeList checkAttributes(ObjectName routingName,
AttributeList attributes, String action) {
check(routingName,null,action);
return attributes;
}
// from MBeanServerConnection
public AttributeList getAttributes(ObjectName name, String[] attributes)
throws InstanceNotFoundException, ReflectionException, IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
final String[] authorized =
checkAttributes(name,attributes,"getAttribute");
final AttributeList attrList =
source().getAttributes(sourceName,authorized);
return attrList;
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
/**
* This method is a hook to implement permission checking in subclasses.
* By default, this method does nothing.
* A subclass may override this method and throw a {@link
* SecurityException} if the permission is denied.
*
* @param routingName The name of the MBean in the enclosing context.
* This is of the form {@code <namespace>//<ObjectName>}.
* @param member The {@link
* javax.management.namespace.JMXNamespacePermission#getMember member}
* name.
* @param action The {@link
* javax.management.namespace.JMXNamespacePermission#getActions action}
* name.
*/
void check(ObjectName routingName,
String member, String action) {
}
void checkPattern(ObjectName routingPattern,
String member, String action) {
// pattern is checked only at posteriori by checkQuery.
// checking it a priori usually doesn't work, because ObjectName.apply
// does not work between two patterns.
check(null,null,action);
}
void checkCreate(ObjectName routingName, String className,
String action) {
}
// from MBeanServerConnection
public Object invoke(ObjectName name, String operationName, Object[] params,
String[] signature)
throws InstanceNotFoundException, MBeanException, ReflectionException,
IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
check(name, operationName, "invoke");
final Object result =
source().invoke(sourceName,operationName,params,
signature);
return result;
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public void unregisterMBean(ObjectName name)
throws InstanceNotFoundException, MBeanRegistrationException,
IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
check(name, null, "unregisterMBean");
source().unregisterMBean(sourceName);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public MBeanInfo getMBeanInfo(ObjectName name)
throws InstanceNotFoundException, IntrospectionException,
ReflectionException, IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
check(name, null, "getMBeanInfo");
return source().getMBeanInfo(sourceName);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public ObjectInstance getObjectInstance(ObjectName name)
throws InstanceNotFoundException, IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
check(name, null, "getObjectInstance");
return processOutputInstance(
source().getObjectInstance(sourceName));
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public boolean isRegistered(ObjectName name) throws IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
return source().isRegistered(sourceName);
} catch (RuntimeMBeanException x) {
throw new RuntimeOperationsException(x.getTargetException());
} catch (RuntimeException x) {
throw makeCompliantRuntimeException(x);
}
}
// from MBeanServerConnection
public void setAttribute(ObjectName name, Attribute attribute)
throws InstanceNotFoundException, AttributeNotFoundException,
InvalidAttributeValueException, MBeanException,
ReflectionException, IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
check(name,
(attribute==null?null:attribute.getName()),
"setAttribute");
source().setAttribute(sourceName,attribute);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public ObjectInstance createMBean(String className,
ObjectName name, ObjectName loaderName,
Object[] params, String[] signature)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException, IOException {
final ObjectName sourceName = newSourceMBeanName(name);
// Loader Name is already a sourceLoaderName.
final ObjectName sourceLoaderName = loaderName;
try {
checkCreate(name, className, "instantiate");
checkCreate(name, className, "registerMBean");
final ObjectInstance instance =
source().createMBean(className,sourceName,
sourceLoaderName,
params,signature);
return processOutputInstance(instance);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public ObjectInstance createMBean(String className, ObjectName name,
Object[] params, String[] signature)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, IOException {
final ObjectName sourceName = newSourceMBeanName(name);
try {
checkCreate(name, className, "instantiate");
checkCreate(name, className, "registerMBean");
return processOutputInstance(source().createMBean(className,
sourceName,params,signature));
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public ObjectInstance createMBean(String className, ObjectName name,
ObjectName loaderName)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException, IOException {
final ObjectName sourceName = newSourceMBeanName(name);
// Loader Name is already a source Loader Name.
final ObjectName sourceLoaderName = loaderName;
try {
checkCreate(name, className, "instantiate");
checkCreate(name, className, "registerMBean");
return processOutputInstance(source().createMBean(className,
sourceName,sourceLoaderName));
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public ObjectInstance createMBean(String className, ObjectName name)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, IOException {
final ObjectName sourceName = newSourceMBeanName(name);
try {
checkCreate(name, className, "instantiate");
checkCreate(name, className, "registerMBean");
return processOutputInstance(source().
createMBean(className,sourceName));
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public Object getAttribute(ObjectName name, String attribute)
throws MBeanException, AttributeNotFoundException,
InstanceNotFoundException, ReflectionException, IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
check(name, attribute, "getAttribute");
return source().getAttribute(sourceName,attribute);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public boolean isInstanceOf(ObjectName name, String className)
throws InstanceNotFoundException, IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
check(name, null, "isInstanceOf");
return source().isInstanceOf(sourceName,className);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public AttributeList setAttributes(ObjectName name, AttributeList attributes)
throws InstanceNotFoundException, ReflectionException, IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
final AttributeList authorized =
checkAttributes(name, attributes, "setAttribute");
return source().
setAttributes(sourceName,authorized);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// Return names in the target's context.
Set<ObjectInstance> processOutputInstances(Set<ObjectInstance> sources) {
final Set<ObjectInstance> result = Util.equivalentEmptySet(sources);
for (ObjectInstance i : sources) {
try {
final ObjectInstance target = processOutputInstance(i);
if (!checkQuery(target.getObjectName(), "queryMBeans"))
continue;
result.add(target);
} catch (Exception x) {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Skiping returned item: " +
"Unexpected exception while processing " +
"ObjectInstance: " + x);
}
continue;
}
}
return result;
}
/**
* This is a hook to implement permission checking in subclasses.
*
* Checks that the caller has sufficient permission for returning
* information about {@code sourceName} in {@code action}.
*
* By default always return true. Subclass may override this method
* and return false if the caller doesn't have sufficient permissions.
*
* @param routingName The name of the MBean to include or exclude from
* the query, expressed in the enclosing context.
* This is of the form {@code <namespace>//<ObjectName>}.
* @param action one of "queryNames" or "queryMBeans"
* @return true if {@code sourceName} can be returned.
*/
boolean checkQuery(ObjectName routingName, String action) {
return true;
}
// Return names in the target's context.
ObjectInstance processOutputInstance(ObjectInstance source) {
if (source == null) return null;
final ObjectName sourceName = source.getObjectName();
try {
final ObjectName targetName = toTarget(sourceName);
return new ObjectInstance(targetName,source.getClassName());
} catch (MalformedObjectNameException x) {
final IllegalArgumentException x2 =
new IllegalArgumentException(String.valueOf(sourceName),x);
final RuntimeOperationsException x3 =
new RuntimeOperationsException(x2);
throw x3;
}
}
// Returns names in the target's context.
Set<ObjectName> processOutputNames(Set<ObjectName> sourceNames) {
final Set<ObjectName> names = Util.equivalentEmptySet(sourceNames);
for (ObjectName n : sourceNames) {
try {
final ObjectName targetName = toTarget(n);
if (!checkQuery(targetName, "queryNames")) continue;
names.add(targetName);
} catch (Exception x) {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Skiping returned item: " +
"Unexpected exception while processing " +
"ObjectInstance: " + x);
}
continue;
}
}
return names;
}
// from MBeanServerConnection
public Set<ObjectInstance> queryMBeans(ObjectName name,
QueryExp query) throws IOException {
if (name == null) name=ObjectName.WILDCARD;
final ObjectName sourceName = toSourceOrRuntime(name);
try {
checkPattern(name,null,"queryMBeans");
return processOutputInstances(
source().queryMBeans(sourceName,query));
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public Set<ObjectName> queryNames(ObjectName name, QueryExp query)
throws IOException {
if (name == null) name=ObjectName.WILDCARD;
final ObjectName sourceName = toSourceOrRuntime(name);
try {
checkPattern(name,null,"queryNames");
final Set<ObjectName> tmp = source().queryNames(sourceName,query);
final Set<ObjectName> out = processOutputNames(tmp);
//System.err.println("queryNames: out: "+out);
return out;
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public void removeNotificationListener(ObjectName name,
NotificationListener listener)
throws InstanceNotFoundException,
ListenerNotFoundException, IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
check(name,null,"removeNotificationListener");
source().removeNotificationListener(sourceName,listener);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public void addNotificationListener(ObjectName name, ObjectName listener,
NotificationFilter filter, Object handback)
throws InstanceNotFoundException, IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
// Listener name is already a source listener name.
try {
check(name,null,"addNotificationListener");
source().addNotificationListener(sourceName,listener,
filter,handback);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public void addNotificationListener(ObjectName name,
NotificationListener listener, NotificationFilter filter,
Object handback) throws InstanceNotFoundException, IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
check(name,null,"addNotificationListener");
source().addNotificationListener(sourceName, listener, filter,
handback);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public void removeNotificationListener(ObjectName name,
NotificationListener listener, NotificationFilter filter,
Object handback)
throws InstanceNotFoundException, ListenerNotFoundException,
IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
check(name,null,"removeNotificationListener");
source().removeNotificationListener(sourceName,listener,filter,
handback);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public void removeNotificationListener(ObjectName name, ObjectName listener,
NotificationFilter filter, Object handback)
throws InstanceNotFoundException, ListenerNotFoundException,
IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
check(name,null,"removeNotificationListener");
source().removeNotificationListener(sourceName,listener,
filter,handback);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public void removeNotificationListener(ObjectName name, ObjectName listener)
throws InstanceNotFoundException, ListenerNotFoundException,
IOException {
final ObjectName sourceName = toSourceOrRuntime(name);
// listener name is already a source name...
final ObjectName sourceListener = listener;
try {
check(name,null,"removeNotificationListener");
source().removeNotificationListener(sourceName,sourceListener);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public Integer getMBeanCount() throws IOException {
try {
return source().getMBeanCount();
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// from MBeanServerConnection
public String[] getDomains() throws IOException {
try {
check(null,null,"getDomains");
final String[] domains = source().getDomains();
return checkDomains(domains,"getDomains");
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
/**
* This method is a hook to implement permission checking in subclasses.
* Checks that the caller as the necessary permissions to view the
* given domain. If not remove the domains for which the caller doesn't
* have permission from the list.
* <p>
* By default, this method always returns {@code domains}
*
* @param domains The domains to return.
* @param action "getDomains"
* @return a filtered list of domains.
*/
String[] checkDomains(String[] domains, String action) {
return domains;
}
// from MBeanServerConnection
public String getDefaultDomain() throws IOException {
try {
return source().getDefaultDomain();
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
}

View File

@ -0,0 +1,282 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace;
import com.sun.jmx.defaults.JmxProperties;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.namespace.JMXNamespaces;
/**
* An RoutingProxy narrows on a given name space in a
* source object implementing MBeanServerConnection.
* It is used to implement
* {@code JMXNamespaces.narrowToNamespace(...)}.
* This abstract class has two concrete subclasses:
* <p>{@link RoutingConnectionProxy}: to cd in an MBeanServerConnection.</p>
* <p>{@link RoutingServerProxy}: to cd in an MBeanServer.</p>
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
public abstract class RoutingProxy<T extends MBeanServerConnection>
extends RoutingMBeanServerConnection<T> {
/**
* A logger for this class.
**/
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
// The source MBeanServerConnection
private final T source;
// The name space we're narrowing to (usually some name space in
// the source MBeanServerConnection
private final String sourceNs;
// The name space we pretend to be mounted in (usually "")
private final String targetNs;
// The name of the JMXNamespace that handles the source name space
private final ObjectName handlerName;
private final ObjectNameRouter router;
final boolean forwardsContext;
private volatile String defaultDomain = null;
/**
* Creates a new instance of RoutingProxy
*/
protected RoutingProxy(T source,
String sourceNs,
String targetNs,
boolean forwardsContext) {
if (source == null) throw new IllegalArgumentException("null");
this.sourceNs = JMXNamespaces.normalizeNamespaceName(sourceNs);
// Usually sourceNs is not null, except when implementing
// Client Contexts
//
if (sourceNs.equals("")) {
this.handlerName = null;
} else {
// System.err.println("sourceNs: "+sourceNs);
this.handlerName =
JMXNamespaces.getNamespaceObjectName(this.sourceNs);
try {
// System.err.println("handlerName: "+handlerName);
if (!source.isRegistered(handlerName))
throw new IllegalArgumentException(sourceNs +
": no such name space");
} catch (IOException x) {
throw new IllegalArgumentException("source stale: "+x,x);
}
}
this.source = source;
this.targetNs = (targetNs==null?"":
JMXNamespaces.normalizeNamespaceName(targetNs));
this.router =
new ObjectNameRouter(this.targetNs,this.sourceNs);
this.forwardsContext = forwardsContext;
if (LOG.isLoggable(Level.FINER))
LOG.finer("RoutingProxy for " + this.sourceNs + " created");
}
@Override
public T source() { return source; }
ObjectNameRouter getObjectNameRouter() {
// TODO: uncomment this when contexts are added
// if (forwardsContext)
// return ObjectNameRouter.wrapWithContext(router);
// else
return router;
}
@Override
public ObjectName toSource(ObjectName targetName)
throws MalformedObjectNameException {
if (targetName == null) return null;
if (targetName.getDomain().equals("") && targetNs.equals("")) {
try {
if (defaultDomain == null)
defaultDomain = getDefaultDomain();
} catch(Exception x) {
LOG.log(Level.FINEST,"Failed to get default domain",x);
}
if (defaultDomain != null)
targetName = targetName.withDomain(defaultDomain);
}
final ObjectNameRouter r = getObjectNameRouter();
return r.toSourceContext(targetName,true);
}
@Override
protected ObjectName newSourceMBeanName(ObjectName targetName)
throws MBeanRegistrationException {
if (targetName != null) return super.newSourceMBeanName(targetName);
// OK => we can accept null if sourceNs is empty.
if (sourceNs.equals("")) return null;
throw new MBeanRegistrationException(
new IllegalArgumentException(
"Can't use null ObjectName with namespaces"));
}
@Override
public ObjectName toTarget(ObjectName sourceName)
throws MalformedObjectNameException {
if (sourceName == null) return null;
final ObjectNameRouter r = getObjectNameRouter();
return r.toTargetContext(sourceName,false);
}
private Object getAttributeFromHandler(String attributeName)
throws IOException {
try {
return source().getAttribute(handlerName,attributeName);
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
} catch (IOException x) {
throw x;
} catch (MBeanException ex) {
throw new IOException("Failed to get "+attributeName+": "+
ex.getMessage(),
ex.getTargetException());
} catch (AttributeNotFoundException ex) {
throw new IOException("Failed to get "+attributeName+": "+
ex.getMessage(),ex);
} catch (InstanceNotFoundException ex) {
throw new IOException("Failed to get "+attributeName+": "+
ex.getMessage(),ex);
} catch (ReflectionException ex) {
throw new IOException("Failed to get "+attributeName+": "+
ex.getMessage(),ex);
}
}
// We cannot call getMBeanCount() on the underlying
// MBeanServerConnection, because it would return the number of
// 'top-level' MBeans, not the number of MBeans in the name space
// we are narrowing to. Instead we're calling getMBeanCount() on
// the JMXNamespace that handles the source name space.
//
// There is however one particular case when the sourceNs is empty.
// In that case, there's no handler - and the 'source' is the top
// level namespace. In that particular case, handlerName will be null,
// and we directly invoke the top level source().
// This later complex case is only used when implementing ClientContexts.
//
@Override
public Integer getMBeanCount() throws IOException {
try {
if (handlerName == null) return source().getMBeanCount();
return (Integer) getAttributeFromHandler("MBeanCount");
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// We cannot call getDomains() on the underlying
// MBeanServerConnection, because it would return the domains of
// 'top-level' MBeans, not the domains of MBeans in the name space
// we are narrowing to. Instead we're calling getDomains() on
// the JMXNamespace that handles the source name space.
//
// There is however one particular case when the sourceNs is empty.
// In that case, there's no handler - and the 'source' is the top
// level namespace. In that particular case, handlerName will be null,
// and we directly invoke the top level source().
// This later complex case is only used when implementing ClientContexts.
//
@Override
public String[] getDomains() throws IOException {
try {
if (handlerName == null) return source().getDomains();
return (String[]) getAttributeFromHandler("Domains");
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
// We cannot call getDefaultDomain() on the underlying
// MBeanServerConnection, because it would return the default domain of
// 'top-level' namespace, not the default domain in the name space
// we are narrowing to. Instead we're calling getDefaultDomain() on
// the JMXNamespace that handles the source name space.
//
// There is however one particular case when the sourceNs is empty.
// In that case, there's no handler - and the 'source' is the top
// level namespace. In that particular case, handlerName will be null,
// and we directly invoke the top level source().
// This later complex case is only used when implementing ClientContexts.
//
@Override
public String getDefaultDomain() throws IOException {
try {
if (handlerName == null) {
defaultDomain = source().getDefaultDomain();
} else {
defaultDomain =(String)
getAttributeFromHandler("DefaultDomain");
}
return defaultDomain;
} catch (RuntimeException ex) {
throw makeCompliantRuntimeException(ex);
}
}
public String getSourceNamespace() {
return sourceNs;
}
public String getTargetNamespace() {
return targetNs;
}
@Override
public String toString() {
return super.toString()+", sourceNs="+
sourceNs + (targetNs.equals("")?"":
(" mounted on targetNs="+targetNs));
}
}

View File

@ -0,0 +1,602 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace;
import com.sun.jmx.mbeanserver.Util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Collections;
import java.util.Set;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.OperationsException;
import javax.management.QueryExp;
import javax.management.ReflectionException;
import javax.management.loading.ClassLoaderRepository;
import javax.management.namespace.JMXNamespaces;
/**
* A RoutingServerProxy is an MBeanServer proxy that proxies a
* source name space in a source MBeanServer.
* It wraps a source MBeanServer, and rewrites routing ObjectNames.
* It is typically use for implementing 'cd' operations, and
* will add the source name space to routing ObjectNames at input,
* and remove it at output.
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
*
* @since 1.7
*/
public class RoutingServerProxy
extends RoutingProxy<MBeanServer>
implements MBeanServer {
/**
* Creates a new instance of RoutingServerProxy
*/
public RoutingServerProxy(MBeanServer source,
String sourceNs) {
this(source,sourceNs,"",false);
}
public RoutingServerProxy(MBeanServer source,
String sourceNs,
String targetNs,
boolean forwardsContext) {
super(source,sourceNs,targetNs,forwardsContext);
}
/**
* This method is called each time an IOException is raised when
* trying to forward an operation to the underlying
* MBeanServerConnection, as a result of calling
* {@link #getMBeanServerConnection()} or as a result of invoking the
* operation on the returned connection.
* Subclasses may redefine this method if they need to perform any
* specific handling of IOException (logging etc...).
* @param x The raised IOException.
* @param method The name of the method in which the exception was
* raised. This is one of the methods of the MBeanServer
* interface.
* @return A RuntimeException that should be thrown by the caller.
* In this default implementation, this is an
* {@link UndeclaredThrowableException} wrapping <var>x</var>.
**/
protected RuntimeException handleIOException(IOException x,
String method) {
return Util.newRuntimeIOException(x);
}
//--------------------------------------------
//--------------------------------------------
//
// Implementation of the MBeanServer interface
//
//--------------------------------------------
//--------------------------------------------
@Override
public void addNotificationListener(ObjectName name,
NotificationListener listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException {
try {
super.addNotificationListener(name, listener,
filter, handback);
} catch (IOException x) {
throw handleIOException(x,"addNotificationListener");
}
}
@Override
public void addNotificationListener(ObjectName name,
ObjectName listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException {
try {
super.addNotificationListener(name, listener,
filter, handback);
} catch (IOException x) {
throw handleIOException(x,"addNotificationListener");
}
}
@Override
public ObjectInstance createMBean(String className, ObjectName name)
throws
ReflectionException,
InstanceAlreadyExistsException,
MBeanRegistrationException,
MBeanException,
NotCompliantMBeanException {
try {
return super.createMBean(className, name);
} catch (IOException x) {
throw handleIOException(x,"createMBean");
}
}
@Override
public ObjectInstance createMBean(String className, ObjectName name,
Object params[], String signature[])
throws
ReflectionException,
InstanceAlreadyExistsException,
MBeanRegistrationException,
MBeanException,
NotCompliantMBeanException {
try {
return super.createMBean(className, name,
params, signature);
} catch (IOException x) {
throw handleIOException(x,"createMBean");
}
}
@Override
public ObjectInstance createMBean(String className,
ObjectName name,
ObjectName loaderName)
throws
ReflectionException,
InstanceAlreadyExistsException,
MBeanRegistrationException,
MBeanException,
NotCompliantMBeanException,
InstanceNotFoundException {
try {
return super.createMBean(className, name, loaderName);
} catch (IOException x) {
throw handleIOException(x,"createMBean");
}
}
@Override
public ObjectInstance createMBean(String className,
ObjectName name,
ObjectName loaderName,
Object params[],
String signature[])
throws
ReflectionException,
InstanceAlreadyExistsException,
MBeanRegistrationException,
MBeanException,
NotCompliantMBeanException,
InstanceNotFoundException {
try {
return super.createMBean(className, name, loaderName,
params, signature);
} catch (IOException x) {
throw handleIOException(x,"createMBean");
}
}
/**
* @deprecated see {@link MBeanServer#deserialize(ObjectName,byte[])
* MBeanServer}
**/
@Deprecated
public ObjectInputStream deserialize(ObjectName name, byte[] data)
throws InstanceNotFoundException, OperationsException {
final ObjectName sourceName = toSourceOrRuntime(name);
try {
return source().deserialize(sourceName,data);
} catch (RuntimeException x) {
throw makeCompliantRuntimeException(x);
}
}
/**
* @deprecated see {@link MBeanServer#deserialize(String,byte[])
* MBeanServer}
*/
@Deprecated
public ObjectInputStream deserialize(String className, byte[] data)
throws OperationsException, ReflectionException {
try {
return source().deserialize(className,data);
} catch (RuntimeException x) {
throw makeCompliantRuntimeException(x);
}
}
/**
* @deprecated see {@link MBeanServer#deserialize(String,ObjectName,byte[])
* MBeanServer}
*/
@Deprecated
public ObjectInputStream deserialize(String className,
ObjectName loaderName,
byte[] data)
throws
InstanceNotFoundException,
OperationsException,
ReflectionException {
try {
return source().deserialize(className,loaderName,data);
} catch (RuntimeException x) {
throw makeCompliantRuntimeException(x);
}
}
@Override
public Object getAttribute(ObjectName name, String attribute)
throws
MBeanException,
AttributeNotFoundException,
InstanceNotFoundException,
ReflectionException {
try {
return super.getAttribute(name, attribute);
} catch (IOException x) {
throw handleIOException(x,"getAttribute");
}
}
@Override
public AttributeList getAttributes(ObjectName name, String[] attributes)
throws InstanceNotFoundException, ReflectionException {
try {
return super.getAttributes(name, attributes);
} catch (IOException x) {
throw handleIOException(x,"getAttributes");
}
}
public ClassLoader getClassLoader(ObjectName loaderName)
throws InstanceNotFoundException {
final ObjectName sourceName = toSourceOrRuntime(loaderName);
try {
return source().getClassLoader(sourceName);
} catch (RuntimeException x) {
throw makeCompliantRuntimeException(x);
}
}
public ClassLoader getClassLoaderFor(ObjectName mbeanName)
throws InstanceNotFoundException {
final ObjectName sourceName = toSourceOrRuntime(mbeanName);
try {
return source().getClassLoaderFor(sourceName);
} catch (RuntimeException x) {
throw makeCompliantRuntimeException(x);
}
}
public ClassLoaderRepository getClassLoaderRepository() {
try {
return source().getClassLoaderRepository();
} catch (RuntimeException x) {
throw makeCompliantRuntimeException(x);
}
}
@Override
public String getDefaultDomain() {
try {
return super.getDefaultDomain();
} catch (IOException x) {
throw handleIOException(x,"getDefaultDomain");
}
}
@Override
public String[] getDomains() {
try {
return super.getDomains();
} catch (IOException x) {
throw handleIOException(x,"getDomains");
}
}
@Override
public Integer getMBeanCount() {
try {
return super.getMBeanCount();
} catch (IOException x) {
throw handleIOException(x,"getMBeanCount");
}
}
@Override
public MBeanInfo getMBeanInfo(ObjectName name)
throws
InstanceNotFoundException,
IntrospectionException,
ReflectionException {
try {
return super.getMBeanInfo(name);
} catch (IOException x) {
throw handleIOException(x,"getMBeanInfo");
}
}
@Override
public ObjectInstance getObjectInstance(ObjectName name)
throws InstanceNotFoundException {
try {
return super.getObjectInstance(name);
} catch (IOException x) {
throw handleIOException(x,"getObjectInstance");
}
}
public Object instantiate(String className)
throws ReflectionException, MBeanException {
try {
return source().instantiate(className);
} catch (RuntimeException x) {
throw makeCompliantRuntimeException(x);
}
}
public Object instantiate(String className,
Object params[],
String signature[])
throws ReflectionException, MBeanException {
try {
return source().instantiate(className,
params,signature);
} catch (RuntimeException x) {
throw makeCompliantRuntimeException(x);
}
}
public Object instantiate(String className, ObjectName loaderName)
throws ReflectionException, MBeanException,
InstanceNotFoundException {
final ObjectName srcLoaderName = toSourceOrRuntime(loaderName);
try {
return source().instantiate(className,srcLoaderName);
} catch (RuntimeException x) {
throw makeCompliantRuntimeException(x);
}
}
public Object instantiate(String className, ObjectName loaderName,
Object params[], String signature[])
throws ReflectionException, MBeanException,
InstanceNotFoundException {
final ObjectName srcLoaderName = toSourceOrRuntime(loaderName);
try {
return source().instantiate(className,srcLoaderName,
params,signature);
} catch (RuntimeException x) {
throw makeCompliantRuntimeException(x);
}
}
@Override
public Object invoke(ObjectName name, String operationName,
Object params[], String signature[])
throws
InstanceNotFoundException,
MBeanException,
ReflectionException {
try {
return super.invoke(name,operationName,params,signature);
} catch (IOException x) {
throw handleIOException(x,"invoke");
}
}
@Override
public boolean isInstanceOf(ObjectName name, String className)
throws InstanceNotFoundException {
try {
return super.isInstanceOf(name, className);
} catch (IOException x) {
throw handleIOException(x,"isInstanceOf");
}
}
@Override
public boolean isRegistered(ObjectName name) {
try {
return super.isRegistered(name);
} catch (IOException x) {
throw handleIOException(x,"isRegistered");
}
}
@Override
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
try {
return super.queryMBeans(name, query);
} catch (IOException x) {
handleIOException(x,"queryMBeans");
return Collections.emptySet();
}
}
@Override
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
try {
return super.queryNames(name, query);
} catch (IOException x) {
handleIOException(x,"queryNames");
return Collections.emptySet();
}
}
public ObjectInstance registerMBean(Object object, ObjectName name)
throws
InstanceAlreadyExistsException,
MBeanRegistrationException,
NotCompliantMBeanException {
final ObjectName sourceName = newSourceMBeanName(name);
try {
return processOutputInstance(
source().registerMBean(object,sourceName));
} catch (RuntimeException x) {
throw makeCompliantRuntimeException(x);
}
}
@Override
public void removeNotificationListener(ObjectName name,
NotificationListener listener)
throws InstanceNotFoundException, ListenerNotFoundException {
try {
super.removeNotificationListener(name, listener);
} catch (IOException x) {
throw handleIOException(x,"removeNotificationListener");
}
}
@Override
public void removeNotificationListener(ObjectName name,
NotificationListener listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException, ListenerNotFoundException {
try {
super.removeNotificationListener(name, listener,
filter, handback);
} catch (IOException x) {
throw handleIOException(x,"removeNotificationListener");
}
}
@Override
public void removeNotificationListener(ObjectName name,
ObjectName listener)
throws InstanceNotFoundException, ListenerNotFoundException {
try {
super.removeNotificationListener(name, listener);
} catch (IOException x) {
throw handleIOException(x,"removeNotificationListener");
}
}
@Override
public void removeNotificationListener(ObjectName name,
ObjectName listener,
NotificationFilter filter,
Object handback)
throws InstanceNotFoundException, ListenerNotFoundException {
try {
super.removeNotificationListener(name, listener,
filter, handback);
} catch (IOException x) {
throw handleIOException(x,"removeNotificationListener");
}
}
@Override
public void setAttribute(ObjectName name, Attribute attribute)
throws
InstanceNotFoundException,
AttributeNotFoundException,
InvalidAttributeValueException,
MBeanException,
ReflectionException {
try {
super.setAttribute(name, attribute);
} catch (IOException x) {
throw handleIOException(x,"setAttribute");
}
}
@Override
public AttributeList setAttributes(ObjectName name,
AttributeList attributes)
throws InstanceNotFoundException, ReflectionException {
try {
return super.setAttributes(name, attributes);
} catch (IOException x) {
throw handleIOException(x,"setAttributes");
}
}
@Override
public void unregisterMBean(ObjectName name)
throws InstanceNotFoundException, MBeanRegistrationException {
try {
super.unregisterMBean(name);
} catch (IOException x) {
throw handleIOException(x,"unregisterMBean");
}
}
public static MBeanServer cd(MBeanServer source, String sourcePath) {
if (source == null) throw new IllegalArgumentException("null");
if (source.getClass().equals(RoutingServerProxy.class)) {
// cast is OK here, but findbugs complains unless we use class.cast
final RoutingServerProxy other =
RoutingServerProxy.class.cast(source);
final String target = other.getTargetNamespace();
// Avoid multiple layers of serialization.
//
// We construct a new proxy from the original source instead of
// stacking a new proxy on top of the old one.
// - that is we replace
// cd ( cd ( x, dir1), dir2);
// by
// cd (x, dir1//dir2);
//
// We can do this only when the source class is exactly
// NamespaceServerProxy.
//
if (target == null || target.equals("")) {
final String path =
JMXNamespaces.concat(other.getSourceNamespace(),
sourcePath);
return new RoutingServerProxy(other.source(),path,"",
other.forwardsContext);
}
// Note: we could do possibly something here - but it would involve
// removing part of targetDir, and possibly adding
// something to sourcePath.
// Too complex to bother! => simply default to stacking...
}
return new RoutingServerProxy(source,sourcePath);
}
}

View File

@ -0,0 +1,45 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>The <code>com.sun.jmx.namespace</code> package</title>
<!--
Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
particular file as subject to the "Classpath" exception as provided
by Sun in the LICENSE file that accompanied this code.
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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
CA 95054 USA or visit www.sun.com if you need additional information or
have any questions.
-->
</head>
<body bgcolor="white">
<p>The <code>com.sun.jmx.namespace</code> package contains
sun specific implementation classes used to implement the
JMX namespaces.
</p>
<p><b>DO NOT USE THESE CLASSES DIRECTLY</b></p>
<p><b>
This API is a Sun internal API and is subject to changes without notice.
</b></p>
<p>The public API through wich these proprietary classes can be
invoked is located in <code>javax.management.namespace</code>
package.
</p>
</body>
</html>

View File

@ -0,0 +1,150 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace.serial;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
/**
* Class DefaultRewritingProcessor. Rewrite ObjectName in input & output
* parameters.
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
// We know that rewriting using serialization is costly.
// This object tries to determine whether an object needs rewriting prior
// to rewriting, and rewrites by creating a new object in those cases
// where we know how to recreate a new object (e.g. a Notification).
// Rewriting is however usually not used - so this object is just a
// skeleton that eventually uses serialization...
//
class DefaultRewritingProcessor extends RewritingProcessor {
private static enum RewriteMode {
INPUT, // Input from target to source (parameters)
OUTPUT // Output from source to target (results)
};
private final boolean identity;
public DefaultRewritingProcessor(String targetDirName) {
this(targetDirName,null);
}
/** Creates a new instance of SerialParamProcessor */
public DefaultRewritingProcessor(final String remove, final String add) {
super(new SerialRewritingProcessor(remove, add));
identity = remove.equals(add);
}
private ObjectName rewriteObjectName(RewriteMode mode,
ObjectName name) {
return changeContext(mode, name);
}
private ObjectInstance rewriteObjectInstance(RewriteMode mode,
ObjectInstance moi) {
final ObjectName srcName = moi.getObjectName();
final ObjectName targetName = changeContext(mode,srcName);
if (targetName == srcName) return moi;
return new ObjectInstance(targetName,moi.getClassName());
}
private Object processObject(RewriteMode mode, Object obj) {
if (obj == null) return null;
// Some things which will always needs rewriting:
// ObjectName, ObjectInstance, and Notifications.
// Take care of those we can handle here...
//
if (obj instanceof ObjectName)
return rewriteObjectName(mode,(ObjectName) obj);
else if (obj instanceof ObjectInstance)
return rewriteObjectInstance(mode,(ObjectInstance) obj);
// TODO: add other standard JMX classes - like e.g. MBeanInfo...
//
// Well, the object may contain an ObjectName => pass it to
// our serial rewriting delegate...
//
return processAnyObject(mode,obj);
}
private Object processAnyObject(RewriteMode mode, Object obj) {
switch (mode) {
case INPUT:
return super.rewriteInput(obj);
case OUTPUT:
return super.rewriteOutput(obj);
default: // can't happen.
throw new AssertionError();
}
}
private ObjectName changeContext(RewriteMode mode, ObjectName name) {
switch (mode) {
case INPUT:
return toSourceContext(name);
case OUTPUT:
return toTargetContext(name);
default: // can't happen.
throw new AssertionError();
}
}
@Override
public ObjectName toTargetContext(ObjectName srcName) {
if (identity) return srcName;
return super.toTargetContext(srcName);
}
@Override
public ObjectName toSourceContext(ObjectName targetName) {
if (identity) return targetName;
return super.toSourceContext(targetName);
}
@SuppressWarnings("unchecked")
@Override
public <T> T rewriteInput(T input) {
if (identity) return input;
return (T) processObject(RewriteMode.INPUT,input);
}
@SuppressWarnings("unchecked")
@Override
public <T> T rewriteOutput(T result) {
if (identity) return result;
return (T) processObject(RewriteMode.OUTPUT,result);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2008 Sun Microsystems, Inc. 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
@ -23,36 +23,52 @@
* have any questions.
*/
#ifdef HEADLESS
#error This file should not be included in headless library
#endif
package com.sun.jmx.namespace.serial;
#include "awt_motif.h"
#include <jvm.h>
import javax.management.ObjectInstance;
import javax.management.ObjectName;
/* Common routines required for both Motif 2.1 and Motif 1.2 */
#include <Xm/ScrollBarP.h>
/* Remove the ScrollBar widget's continuous scrolling timeout handler
on a ButtonRelease to prevent the continuous scrolling that would
occur if a timeout expired after the ButtonRelease.
*/
/*
* Note: RFE:4263104 is filed when the API is available these needs to removed
/**
* Class RoutingOnlyProcessor. A RewritingProcessor that uses
* Java Serialization to rewrite ObjectNames contained in
* input & results...
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
*
* @since 1.7
*/
void
awt_motif_Scrollbar_ButtonReleaseHandler(Widget w,
XtPointer data,
XEvent *event,
Boolean *cont)
{
/* Remove the timeout handler. */
#define END_TIMER (1<<2)
XmScrollBarWidget sbw = (XmScrollBarWidget) w;
if (sbw->scrollBar.timer != NULL) {
XtRemoveTimeOut( sbw->scrollBar.timer );
sbw->scrollBar.timer = (XtIntervalId)NULL;
sbw->scrollBar.flags |= END_TIMER;
}
class IdentityProcessor extends RewritingProcessor {
/** Creates a new instance of SerialRewritingProcessor */
public IdentityProcessor() {
}
@Override
public <T> T rewriteOutput(T result) {
return result;
}
@Override
public <T> T rewriteInput(T input) {
return input;
}
@Override
public final ObjectName toTargetContext(ObjectName sourceName) {
return sourceName;
}
@Override
public final ObjectInstance toTargetContext(ObjectInstance sourceMoi) {
return sourceMoi;
}
@Override
public final ObjectName toSourceContext(ObjectName targetName) {
return targetName;
}
}

View File

@ -0,0 +1,145 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace.serial;
import com.sun.jmx.defaults.JmxProperties;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* The JMXNamespaceContext class is used to implement a thread local
* serialization / deserialization context for namespaces.
* <p>
* This class is consulted by {@link javax.management.ObjectName} at
* serialization / deserialization time.
* The serialization or deserialization context is established by
* by the {@link SerialRewritingProcessor} defined in this package.
* <p>
* These classes are Sun proprietary APIs, subject to change without
* notice. Do not use these classes directly.
* The public API to rewrite ObjectNames embedded in parameters is
* defined in {@link javax.management.namespace.JMXNamespaces}.
*
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
public class JMXNamespaceContext {
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
public final String prefixToRemove;
public final String prefixToAdd;
private JMXNamespaceContext(String add, String remove) {
prefixToRemove = (remove==null?"":remove);
prefixToAdd = (add==null?"":add);
}
private final static class SerialContext {
private JMXNamespaceContext serializationContext;
private JMXNamespaceContext deserializationContext;
public SerialContext(){
serializationContext = new JMXNamespaceContext("","");
deserializationContext = new JMXNamespaceContext("","");
}
}
private final static ThreadLocal<SerialContext> prefix =
new ThreadLocal<SerialContext>() {
@Override
protected SerialContext initialValue() {
return new SerialContext();
}
};
public static JMXNamespaceContext getSerializationContext() {
return prefix.get().serializationContext;
}
public static JMXNamespaceContext getDeserializationContext() {
return prefix.get().deserializationContext;
}
private static String[] setSerializationContext(String oldPrefix,
String newPrefix) {
final SerialContext c = prefix.get();
JMXNamespaceContext dc = c.serializationContext;
String[] old = {dc.prefixToRemove, dc.prefixToAdd};
c.serializationContext = new JMXNamespaceContext(newPrefix,oldPrefix);
return old;
}
private static String[] setDeserializationContext(String oldPrefix,
String newPrefix) {
final SerialContext c = prefix.get();
JMXNamespaceContext dc = c.deserializationContext;
String[] old = {dc.prefixToRemove, dc.prefixToAdd};
c.deserializationContext = new JMXNamespaceContext(newPrefix,oldPrefix);
return old;
}
static void serialize(ObjectOutputStream stream, Object obj,
String prefixToRemove, String prefixToAdd)
throws IOException {
final String[] old =
setSerializationContext(prefixToRemove,prefixToAdd);
try {
stream.writeObject(obj);
} finally {
try {
setSerializationContext(old[0],old[1]);
} catch (Exception x) {
LOG.log(Level.FINEST,
"failed to restore serialization context",x);
}
}
}
static Object deserialize(ObjectInputStream stream,
String prefixToRemove,
String prefixToAdd)
throws IOException, ClassNotFoundException {
final String[] old =
setDeserializationContext(prefixToRemove,prefixToAdd);
try {
return stream.readObject();
} finally {
try {
setDeserializationContext(old[0],old[1]);
} catch (Exception x) {
LOG.log(Level.FINEST,
"failed to restore serialization context",x);
}
}
}
}

View File

@ -0,0 +1,362 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace.serial;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
/**
* An object that can rewrite ObjectNames contained in input/output
* parameters when entering/leaving a {@link javax.management.namespace
* namespace}.
* <p>When entering a {@link javax.management.namespace
* namespace}, the {@code namespace} prefix is stripped from
* ObjectNames contained in input parameters. When leaving a
* {@code namespace},
* the {@code namespace} prefix is prepended to the ObjectNames contained in
* the result parameters returned from that {@code namespace}.
* </p>
* <p>Objects that need to perform these operations usually use a
* {@code RewritingProcessor} for that purpose.<br>
* The {@code RewritingProcessor} allows a somewhat larger
* transformation in which part of a prefix {@link #newRewritingProcessor
* remove} can be replaced by another prefix {@link #newRewritingProcessor
* add}. The transformation described above correspond to the case where
* {@code remove} is the stripped {@link javax.management.namespace
* namespace} prefix (removed when entering the {@code namespace}) and
* {@code add} is the empty String {@code ""}.
* <br>
* It is interesting to note that {@link
* javax.management.JMXNamespaces#narrowToNamespace narrowToNamespace}
* operations use the inverse transformation (that is, {@code remove} is
* the empty String {@code ""} and {@code add} is the {@link
* javax.management.namespace namespace} prefix).
* <br>
* On a more general scale, {@link #rewriteInput rewriteInput} removes
* {@link #newRewritingProcessor remove} and the prepend {@link
* #newRewritingProcessor add}, and {@link #rewriteOutput rewriteOutput}
* does the opposite, removing {@link #newRewritingProcessor add}, and
* then adding {@link #newRewritingProcessor remove}.
* <br>
* An implementation of {@code RewritingProcessor} should make sure that
* <code>rewriteInput(rewriteOutput(x,clp),clp)</code> and
* <code>rewriteOutput(rewriteInput(x,clp),clp)</code> always return
* {@code x} or an exact clone of {@code x}.
* </p>
* <p>A default implementation of {@code RewritingProcessor} based on
* Java Object Serialization can be
* obtained from {@link #newRewritingProcessor newRewritingProcessor}.
* </p>
* <p>
* By default, the instances of {@code RewritingProcessor} returned by
* {@link #newRewritingProcessor newRewritingProcessor} will rewrite
* ObjectNames contained in instances of classes they don't know about by
* serializing and then deserializing such object instances. This will
* happen even if such instances don't - or can't contain ObjectNames,
* because the default implementation of {@code RewritingProcessor} will
* not be able to determine whether instances of such classes can/do contain
* instance of ObjectNames before serializing/deserializing them.
* </p>
* <p>If you are using custom classes that the default implementation of
* {@code RewritingProcessor} don't know about, it can be interesting to
* prevent an instance of {@code RewritingProcessor} to serialize/deserialize
* instances of such classes for nothing. In that case, you could customize
* the behavior of such a {@code RewritingProcessor} by wrapping it in a
* custom subclass of {@code RewritingProcessor} as shown below:
* <pre>
* public class MyRewritingProcessor extends RewritingProcessor {
* MyRewritingProcessor(String remove, String add) {
* this(RewritingProcessor.newRewritingProcessor(remove,add));
* }
* MyRewritingProcessor(RewritingProcessor delegate) {
* super(delegate);
* }
*
* <T> T rewriteInput(T input) {
* if (input == null) return null;
* if (MyClass.equals(input.getClass())) {
* // I know that MyClass doesn't contain any ObjectName
* return (T) input;
* }
* return super.rewriteInput(input);
* }
* <T> T rewriteOutput(T result) {
* if (result == null) return null;
* if (MyClass.equals(result.getClass())) {
* // I know that MyClass doesn't contain any ObjectName
* return (T) result;
* }
* return super.rewriteOutput(result);
* }
* }
* </pre>
* </p>
* <p>Such a subclass may also provide an alternate way of rewriting
* custom subclasses for which rewriting is needed - for instance:
* <pre>
* public class MyRewritingProcessor extends RewritingProcessor {
* MyRewritingProcessor(String remove, String add) {
* this(RewritingProcessor.newRewritingProcessor(remove,add));
* }
* MyRewritingProcessor(RewritingProcessor delegate) {
* super(delegate);
* }
*
* <T> T rewriteInput(T input) {
* if (input == null) return null;
* if (MyClass.equals(input.getClass())) {
* // I know that MyClass doesn't contain any ObjectName
* return (T) input;
* } else if (MyOtherClass.equals(input.getClass())) {
* // Returns a new instance in which ObjectNames have been
* // replaced.
* final ObjectName aname = ((MyOtherClass)input).getName();
* return (T) (new MyOtherClass(super.rewriteInput(aname)));
* }
* return super.rewriteInput(input,clp);
* }
* <T> T rewriteOutput(T result) {
* if (result == null) return null;
* if (MyClass.equals(result.getClass())) {
* // I know that MyClass doesn't contain any ObjectName
* return (T) result;
* } else if (MyOtherClass.equals(result.getClass())) {
* // Returns a new instance in which ObjectNames have been
* // replaced.
* final ObjectName aname = ((MyOtherClass)result).getName();
* return (T) (new MyOtherClass(super.rewriteOutput(aname)));
* }
* return super.rewriteOutput(result,clp);
* }
* }
* </pre>
* </p>
* <p>If your application only uses {@link javax.management.MXBean MXBeans},
* or MBeans using simple types, and doesn't define any custom subclass of
* {@link javax.management.Notification}, you should never write such
* such {@code RewitingProcessor} implementations.
* </p>
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
public abstract class RewritingProcessor {
/**
* A logger for this class.
**/
private final RewritingProcessor delegate;
/**
* Creates a new instance of RewritingProcessor.
* <p>This is equivalent to calling {@link
* #RewritingProcessor(RewritingProcessor) RewritingProcessor(null)}.
* </p>
**/
protected RewritingProcessor() {
this(null);
}
/**
* Creates a new instance of RewritingProcessor, with a delegate.
* @param delegate a {@code RewritingProcessor} to which all the
* calls will be delegated. When implementing a subclass
* of {@code RewritingProcessor}, calling {@link
* #rewriteInput super.rewriteInput} will invoke
* {@code delegate.rewriteInput} and calling {@link
* #rewriteOutput super.rewriteOutput} will invoke
* {@code delegate.rewriteOutput}.
*
**/
protected RewritingProcessor(RewritingProcessor delegate) {
this.delegate = delegate;
}
/**
* Rewrites ObjectNames when {@link RewritingProcessor leaving} a {@link
* javax.management.namespace namespace}.
* <p>
* Returns {@code obj}, if it is known that {@code obj} doesn't contain
* any ObjectName, or a new copied instance of {@code obj} in which
* ObjectNames (if any) will have been rewritten, if {@code obj} contains
* ObjectNames, or if it is not known whether {@code obj} contains
* ObjectNames or not.
* </p>
* <p>
* The default implementation of this method is as follows: if the
* {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code
* null}, throws an {@link IllegalArgumentException}. Otherwise,
* returns {@code delegate.rewriteOutput(obj)}.
* </p>
* <p>This behavior can be overridden by subclasses as shown in this
* class {@link RewritingProcessor description}.
* </p>
* @param obj The result to be rewritten if needed.
*
* @return {@code obj}, or a clone of {@code obj} in which ObjectNames
* have been rewritten. See this class {@link RewritingProcessor
* description} for more details.
* @throws IllegalArgumentException if this implementation does not know
* how to rewrite the object.
**/
public <T> T rewriteOutput(T obj) {
if (obj == null) return null;
if (delegate != null)
return delegate.rewriteOutput(obj);
throw new IllegalArgumentException("can't rewrite "+
obj.getClass().getName());
}
/**
* Rewrites ObjectNames when {@link RewritingProcessor entering} a {@link
* javax.management.namespace namespace}.
* <p>
* Returns {@code obj}, if it is known that {@code obj} doesn't contain
* any ObjectName, or a new copied instance of {@code obj} in which
* ObjectNames (if any) will have been rewritten, if {@code obj} contains
* ObjectNames, or if it is not known whether {@code obj} contains
* ObjectNames or not.
* </p>
* <p>
* The default implementation of this method is as follows: if the
* {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code
* null}, throws an {@link IllegalArgumentException}. Otherwise,
* returns {@code delegate.rewriteInput(obj)}.
* </p>
* <p>This behavior can be overridden by subclasses as shown in this
* class {@link RewritingProcessor description}.
* </p>
* @param obj The result to be rewritten if needed.
* @return {@code obj}, or a clone of {@code obj} in which ObjectNames
* have been rewritten. See this class {@link RewritingProcessor
* description} for more details.
* @throws IllegalArgumentException if this implementation does not know
* how to rewrite the object.
**/
public <T> T rewriteInput(T obj) {
if (obj == null) return null;
if (delegate != null)
return delegate.rewriteInput(obj);
throw new IllegalArgumentException("can't rewrite "+
obj.getClass().getName());
}
/**
* Translate a routing ObjectName from the target (calling) context to
* the source (called) context when {@link RewritingProcessor entering} a
* {@link javax.management.namespace namespace}.
* <p>
* The default implementation of this method is as follows: if the
* {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code
* null}, throws an {@link IllegalArgumentException}. Otherwise,
* returns {@code delegate.toSourceContext(targetName)}.
* </p>
* <p>This behavior can be overridden by subclasses as shown in this
* class {@link RewritingProcessor description}.
* </p>
* @param targetName The routing target ObjectName to translate.
* @return The ObjectName translated to the source context.
* @throws IllegalArgumentException if this implementation does not know
* how to rewrite the object.
**/
public ObjectName toSourceContext(ObjectName targetName) {
if (delegate != null)
return delegate.toSourceContext(targetName);
throw new IllegalArgumentException("can't rewrite targetName: "+
" no delegate.");
}
/**
* Translate an ObjectName returned from the source context into
* the target (calling) context when {@link RewritingProcessor leaving} a
* {@link javax.management.namespace namespace}.
* <p>
* The default implementation of this method is as follows: if the
* {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code
* null}, throws an {@link IllegalArgumentException}. Otherwise,
* returns {@code delegate.toTargetContext(sourceName)}.
* </p>
* <p>This behavior can be overridden by subclasses as shown in this
* class {@link RewritingProcessor description}.
* </p>
* @param sourceName The routing source ObjectName to translate to the
* target context.
* @return The ObjectName translated to the target context.
* @throws IllegalArgumentException if this implementation does not know
* how to rewrite the object.
**/
public ObjectName toTargetContext(ObjectName sourceName) {
if (delegate != null)
return delegate.toTargetContext(sourceName);
throw new IllegalArgumentException("can't rewrite sourceName: "+
" no delegate.");
}
/**
* Translate an ObjectInstance returned from the source context into
* the target (calling) context when {@link RewritingProcessor leaving} a
* {@link javax.management.namespace namespace}.
* <p>
* The default implementation of this method is as follows: if the
* {@link #RewritingProcessor(RewritingProcessor) delegate} is {@code
* null}, throws an {@link IllegalArgumentException}. Otherwise,
* returns {@code delegate.toTargetContext(sourceMoi)}.
* </p>
* <p>This behavior can be overridden by subclasses as shown in this
* class {@link RewritingProcessor description}.
* </p>
* @param sourceMoi The routing source ObjectInstance to translate.
* @return The ObjectInstance translated to the target context.
* @throws IllegalArgumentException if this implementation does not know
* how to rewrite the object.
**/
public ObjectInstance toTargetContext(ObjectInstance sourceMoi) {
if (delegate != null)
return delegate.toTargetContext(sourceMoi);
throw new IllegalArgumentException("can't rewrite sourceName: "+
" no delegate.");
}
/**
* Creates a new default instance of {@link RewritingProcessor}.
* @param remove The prefix to remove from {@link ObjectName ObjectNames}
* when {@link RewritingProcessor entering} the {@link
* javax.management.namespace namespace}.
* @param add The prefix to add to {@link ObjectName ObjectNames}
* when {@link RewritingProcessor entering} the {@link
* javax.management.namespace namespace} (this is performed
* after having removed the {@code remove} prefix.
* @return A new {@link RewritingProcessor} processor object that will
* perform the requested operation, using Java serialization if
* necessary.
**/
public static RewritingProcessor newRewritingProcessor(String remove,
String add) {
return new DefaultRewritingProcessor(remove,add);
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace.serial;
import com.sun.jmx.namespace.ObjectNameRouter;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
/**
* Class RoutingOnlyProcessor. A RewritingProcessor that uses
* Java Serialization to rewrite ObjectNames contained in
* input and results...
*
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
class RoutingOnlyProcessor extends RewritingProcessor {
final ObjectNameRouter router;
public RoutingOnlyProcessor(String targetDirName) {
this(targetDirName,null);
}
/** Creates a new instance of RoutingOnlyProcessor */
public RoutingOnlyProcessor(final String remove, final String add) {
super(new IdentityProcessor());
if (remove == null || add == null)
throw new IllegalArgumentException("Null argument");
router = new ObjectNameRouter(remove,add);
}
@Override
public final ObjectName toTargetContext(ObjectName sourceName) {
return router.toTargetContext(sourceName,false);
}
@Override
public final ObjectName toSourceContext(ObjectName targetName) {
return router.toSourceContext(targetName,false);
}
@Override
public final ObjectInstance toTargetContext(ObjectInstance sourceMoi) {
return router.toTargetContext(sourceMoi,false);
}
}

View File

@ -0,0 +1,172 @@
/*
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.namespace.serial;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.util.LinkedList;
import java.util.Queue;
import javax.management.ObjectName;
/**
* Class SerialRewritingProcessor. A RewritingProcessor that uses
* Java Serialization to rewrite ObjectNames contained in
* input & results...
* <p><b>
* This API is a Sun internal API and is subject to changes without notice.
* </b></p>
* @since 1.7
*/
class SerialRewritingProcessor extends RewritingProcessor {
private static class CloneOutput extends ObjectOutputStream {
Queue<Class<?>> classQueue = new LinkedList<Class<?>>();
CloneOutput(OutputStream out) throws IOException {
super(out);
}
@Override
protected void annotateClass(Class<?> c) {
classQueue.add(c);
}
@Override
protected void annotateProxyClass(Class<?> c) {
classQueue.add(c);
}
}
private static class CloneInput extends ObjectInputStream {
private final CloneOutput output;
CloneInput(InputStream in, CloneOutput output) throws IOException {
super(in);
this.output = output;
}
@Override
protected Class<?> resolveClass(ObjectStreamClass osc)
throws IOException, ClassNotFoundException {
Class<?> c = output.classQueue.poll();
String expected = osc.getName();
String found = (c == null) ? null : c.getName();
if (!expected.equals(found)) {
throw new InvalidClassException("Classes desynchronized: " +
"found " + found + " when expecting " + expected);
}
return c;
}
@Override
protected Class<?> resolveProxyClass(String[] interfaceNames)
throws IOException, ClassNotFoundException {
return output.classQueue.poll();
}
}
final String targetPrefix;
final String sourcePrefix;
final boolean identity;
public SerialRewritingProcessor(String targetDirName) {
this(targetDirName,null);
}
/** Creates a new instance of SerialRewritingProcessor */
public SerialRewritingProcessor(final String remove, final String add) {
super(new RoutingOnlyProcessor(remove,add));
this.targetPrefix = remove;
this.sourcePrefix = add;
identity = targetPrefix.equals(sourcePrefix);
}
private <T> T switchContext(T result, String from,String to)
throws IOException, ClassNotFoundException {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final CloneOutput ostream = new CloneOutput(baos);
JMXNamespaceContext.serialize(ostream,result,from,null);
ostream.flush();
final byte[] bytes = baos.toByteArray();
final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
final CloneInput istream = new CloneInput(bais, ostream);
@SuppressWarnings("unchecked")
final T clone = (T) JMXNamespaceContext.deserialize(istream,null,to);
return clone;
}
@Override
@SuppressWarnings("unchecked")
public <T> T rewriteOutput(T result) {
if (identity) return result;
return (T) processOutput(result);
}
private Object processOutput(Object result) {
try {
if (result instanceof ObjectName)
return toTargetContext((ObjectName) result);
return switchContext(result,sourcePrefix,targetPrefix);
} catch (ClassNotFoundException x) {
throw new IllegalArgumentException("Can't process result: "+x,x);
} catch (IOException x) {
throw new IllegalArgumentException("Can't process result: "+x,x);
}
}
@Override
@SuppressWarnings("unchecked")
public <T> T rewriteInput(T input) {
if (identity) return input;
return (T) processInput(input);
}
private Object processInput(Object input) {
try {
if (input instanceof ObjectName)
return toSourceContext((ObjectName) input);
return switchContext(input,targetPrefix,sourcePrefix);
} catch (ClassNotFoundException x) {
throw new IllegalArgumentException("Can't process input: "+x,x);
} catch (IOException x) {
throw new IllegalArgumentException("Can't process input: "+x,x);
}
}
}

View File

@ -0,0 +1,44 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>The <code>com.sun.jmx.namespace.serial</code> package</title>
<!--
Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
particular file as subject to the "Classpath" exception as provided
by Sun in the LICENSE file that accompanied this code.
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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
CA 95054 USA or visit www.sun.com if you need additional information or
have any questions.
-->
</head>
<body bgcolor="white">
<p>The <code>com.sun.jmx.namespace.serial</code> package contains
sun specific implementation classes used to switch namespace
prefixes in ObjectName during serialization.
</p>
<p><b>NEVER USE THESE CLASSES DIRECTLY</b></p>
<p><b>
This API is a Sun internal API and is subject to changes without notice.
</b></p>
<p>The public API through which these proprietary classes can be invoked is
located in <code>javax.management.namespace.JMXNamespaces</code>
</p>
</body>
</html>

View File

@ -57,6 +57,7 @@ import javax.security.auth.Subject;
public class ServerNotifForwarder {
public ServerNotifForwarder(MBeanServer mbeanServer,
Map env,
NotificationBuffer notifBuffer,
@ -85,7 +86,8 @@ public class ServerNotifForwarder {
// Explicitly check MBeanPermission for addNotificationListener
//
checkMBeanPermission(name, "addNotificationListener");
checkMBeanPermission(getMBeanServerName(),
mbeanServer, name, "addNotificationListener");
if (notificationAccessController != null) {
notificationAccessController.addNotificationListener(
connectionId, name, getSubject());
@ -155,7 +157,8 @@ public class ServerNotifForwarder {
// Explicitly check MBeanPermission for removeNotificationListener
//
checkMBeanPermission(name, "removeNotificationListener");
checkMBeanPermission(getMBeanServerName(),
mbeanServer, name, "removeNotificationListener");
if (notificationAccessController != null) {
notificationAccessController.removeNotificationListener(
connectionId, name, getSubject());
@ -330,13 +333,7 @@ public class ServerNotifForwarder {
* Explicitly check the MBeanPermission for
* the current access control context.
*/
private void checkMBeanPermission(final ObjectName name,
final String actions)
throws InstanceNotFoundException, SecurityException {
checkMBeanPermission(mbeanServer, name, actions);
}
public static void checkMBeanPermission(
public static void checkMBeanPermission(String serverName,
final MBeanServer mbs, final ObjectName name, final String actions)
throws InstanceNotFoundException, SecurityException {
SecurityManager sm = System.getSecurityManager();
@ -355,7 +352,9 @@ public class ServerNotifForwarder {
throw (InstanceNotFoundException) extractException(e);
}
String classname = oi.getClassName();
MBeanPermission perm = new MBeanPermission(classname,
MBeanPermission perm = new MBeanPermission(
serverName,
classname,
null,
name,
actions);
@ -370,8 +369,8 @@ public class ServerNotifForwarder {
TargetedNotification tn) {
try {
if (checkNotificationEmission) {
checkMBeanPermission(
name, "addNotificationListener");
checkMBeanPermission(getMBeanServerName(),
mbeanServer, name, "addNotificationListener");
}
if (notificationAccessController != null) {
notificationAccessController.fetchNotification(
@ -433,11 +432,27 @@ public class ServerNotifForwarder {
}
}
private String getMBeanServerName() {
if (mbeanServerName != null) return mbeanServerName;
else return (mbeanServerName = getMBeanServerName(mbeanServer));
}
private static String getMBeanServerName(final MBeanServer server) {
final PrivilegedAction<String> action = new PrivilegedAction<String>() {
public String run() {
return Util.getMBeanServerSecurityName(server);
}
};
return AccessController.doPrivileged(action);
}
//------------------
// PRIVATE VARIABLES
//------------------
private MBeanServer mbeanServer;
private volatile String mbeanServerName;
private final String connectionId;

View File

@ -25,6 +25,7 @@
package com.sun.jmx.remote.util;
import com.sun.jmx.defaults.JmxProperties;
import com.sun.jmx.event.EventClientFactory;
import java.lang.reflect.InvocationHandler;
@ -45,6 +46,7 @@ import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.event.EventClient;
import javax.management.event.EventClientDelegate;
import javax.management.namespace.JMXNamespaces;
/**
* Class EventClientConnection - a {@link Proxy} that wraps an
@ -63,12 +65,10 @@ public class EventClientConnection implements InvocationHandler,
/**
* A logger for this class.
**/
private static final Logger LOG =
Logger.getLogger(EventClientConnection.class.getName());
private static final Logger LOG = JmxProperties.NOTIFICATION_LOGGER;
private static final String NAMESPACE_SEPARATOR = "//";
private static final int NAMESPACE_SEPARATOR_LENGTH =
NAMESPACE_SEPARATOR.length();
JMXNamespaces.NAMESPACE_SEPARATOR.length();
/**
* Creates a new {@code EventClientConnection}.
@ -212,9 +212,9 @@ public class EventClientConnection implements InvocationHandler,
}
final ObjectName mbean = (ObjectName) args[0];
final EventClient client = getEventClient();
final EventClient evtClient = getEventClient();
// Fails if client is null AND the MBean we try to listen to is
// Fails if evtClient is null AND the MBean we try to listen to is
// in a subnamespace. We fail here because we know this will not
// work.
//
@ -222,15 +222,15 @@ public class EventClientConnection implements InvocationHandler,
// earlier agent (JDK 1.6 or earlier), then the EventClient will
// be null (we can't use the event service with earlier JDKs).
//
// In principle a null client indicates that the remote VM is of
// In principle a null evtClient indicates that the remote VM is of
// an earlier version, in which case it shouldn't contain any namespace.
//
// So having a null client AND an MBean contained in a namespace is
// So having a null evtClient AND an MBean contained in a namespace is
// clearly an error case.
//
if (client == null) {
if (evtClient == null) {
final String domain = mbean.getDomain();
final int index = domain.indexOf(NAMESPACE_SEPARATOR);
final int index = domain.indexOf(JMXNamespaces.NAMESPACE_SEPARATOR);
if (index > -1 && index <
(domain.length()-NAMESPACE_SEPARATOR_LENGTH)) {
throw new UnsupportedOperationException(method.getName()+
@ -256,9 +256,9 @@ public class EventClientConnection implements InvocationHandler,
final NotificationFilter filter = (NotificationFilter) args[2];
final Object handback = args[3];
if (client != null) {
if (evtClient != null) {
// general case
client.addNotificationListener(mbean,listener,filter,handback);
evtClient.addNotificationListener(mbean,listener,filter,handback);
} else {
// deprecated case. Only works for mbean in local namespace.
connection.addNotificationListener(mbean,listener,filter,
@ -274,9 +274,9 @@ public class EventClientConnection implements InvocationHandler,
switch (nargs) {
case 2:
if (client != null) {
if (evtClient != null) {
// general case
client.removeNotificationListener(mbean,listener);
evtClient.removeNotificationListener(mbean,listener);
} else {
// deprecated case. Only works for mbean in local namespace.
connection.removeNotificationListener(mbean, listener);
@ -286,8 +286,8 @@ public class EventClientConnection implements InvocationHandler,
case 4:
NotificationFilter filter = (NotificationFilter) args[2];
Object handback = args[3];
if (client != null) {
client.removeNotificationListener(mbean,
if (evtClient != null) {
evtClient.removeNotificationListener(mbean,
listener,
filter,
handback);

View File

@ -1,5 +1,5 @@
/*
* Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1998-2008 Sun Microsystems, Inc. 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
@ -256,13 +256,13 @@ public class ExtCheck {
private boolean isNotOlderThan(String already,String target)
throws NumberFormatException
{
if (already == null || already.length() < 1) {
if (already == null || already.length() < 1) {
throw new NumberFormatException("Empty version string");
}
// Until it matches scan and compare numbers
StringTokenizer dtok = new StringTokenizer(target, ".", true);
StringTokenizer stok = new StringTokenizer(already, ".", true);
// Until it matches scan and compare numbers
StringTokenizer dtok = new StringTokenizer(target, ".", true);
StringTokenizer stok = new StringTokenizer(already, ".", true);
while (dtok.hasMoreTokens() || stok.hasMoreTokens()) {
int dver;
int sver;
@ -276,19 +276,19 @@ public class ExtCheck {
} else
sver = 0;
if (sver < dver)
return false; // Known to be incompatible
if (sver > dver)
return true; // Known to be compatible
if (sver < dver)
return false; // Known to be incompatible
if (sver > dver)
return true; // Known to be compatible
// Check for and absorb separators
if (dtok.hasMoreTokens())
dtok.nextToken();
if (stok.hasMoreTokens())
stok.nextToken();
// Compare next component
}
// All components numerically equal
// Check for and absorb separators
if (dtok.hasMoreTokens())
dtok.nextToken();
if (stok.hasMoreTokens())
stok.nextToken();
// Compare next component
}
// All components numerically equal
return true;
}
@ -307,11 +307,10 @@ public class ExtCheck {
}
/**
* Print out the error message and exit from the program
* Throws a RuntimeException with a message describing the error.
*/
static void error(String message){
System.err.println(message);
System.exit(-1);
static void error(String message) throws RuntimeException {
throw new RuntimeException(message);
}
@ -356,19 +355,19 @@ public class ExtCheck {
}
private JarFile findJarFile(URL url) throws IOException {
// Optimize case where url refers to a local jar file
if ("file".equals(url.getProtocol())) {
String path = url.getFile().replace('/', File.separatorChar);
File file = new File(path);
if (!file.exists()) {
throw new FileNotFoundException(path);
}
return new JarFile(path);
}
URLConnection uc = getBaseURL().openConnection();
//uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION);
return ((JarURLConnection)uc).getJarFile();
}
// Optimize case where url refers to a local jar file
if ("file".equals(url.getProtocol())) {
String path = url.getFile().replace('/', File.separatorChar);
File file = new File(path);
if (!file.exists()) {
throw new FileNotFoundException(path);
}
return new JarFile(path);
}
URLConnection uc = getBaseURL().openConnection();
//uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION);
return ((JarURLConnection)uc).getJarFile();
}
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright 1998 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1998-2008 Sun Microsystems, Inc. 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
@ -32,7 +32,10 @@ import java.io.*;
*/
public final class Main {
public static final String INSUFFICIENT = "Insufficient number of arguments";
public static final String MISSING = "Missing <jar file> argument";
public static final String DOES_NOT_EXIST = "Jarfile does not exist: ";
public static final String EXTRA = "Extra command line argument: ";
/**
* Terminates with one of the following codes
@ -40,26 +43,36 @@ public final class Main {
* 0 No newer jar file was found
* -1 An internal error occurred
*/
public static void main(String args[]){
if (args.length < 1){
System.err.println("Usage: extcheck [-verbose] <jar file>");
public static void main(String args[]) {
try {
realMain(args);
} catch (Exception ex) {
System.err.println(ex.getMessage());
System.exit(-1);
}
}
public static void realMain(String[] args) throws Exception {
if (args.length < 1) {
usage(INSUFFICIENT);
}
int argIndex = 0;
boolean verboseFlag = false;
if (args[argIndex].equals("-verbose")){
if (args[argIndex].equals("-verbose")) {
verboseFlag = true;
argIndex++;
if (argIndex >= args.length) {
usage(MISSING);
}
}
String jarName = args[argIndex];
argIndex++;
File jarFile = new File(jarName);
if (!jarFile.exists()){
ExtCheck.error("Jarfile " + jarName + " does not exist");
usage(DOES_NOT_EXIST + jarName);
}
if (argIndex < args.length) {
ExtCheck.error("Extra command line argument :"+args[argIndex]);
usage(EXTRA + args[argIndex]);
}
ExtCheck jt = ExtCheck.create(jarFile,verboseFlag);
boolean result = jt.checkInstalledAgainstTarget();
@ -68,7 +81,10 @@ public final class Main {
} else {
System.exit(1);
}
}
private static void usage(String msg) throws Exception {
throw new Exception(msg + "\nUsage: extcheck [-verbose] <jar file>");
}
}

View File

@ -120,7 +120,7 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes
private int version; // The version of .hprof being read
private int debugLevel;
private int currPos; // Current position in the file
private long currPos; // Current position in the file
private int dumpsToSkip;
private boolean callStack; // If true, read the call stack of objects
@ -196,7 +196,9 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes
break;
}
in.readInt(); // Timestamp of this record
int length = in.readInt();
// Length of record: readInt() will return negative value for record
// length >2GB. so store 32bit value in long to keep it unsigned.
long length = in.readInt() & 0xffffffffL;
if (debugLevel > 0) {
System.out.println("Read record type " + type
+ ", length " + length
@ -211,7 +213,7 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes
switch (type) {
case HPROF_UTF8: {
long id = readID();
byte[] chars = new byte[length - identifierSize];
byte[] chars = new byte[(int)length - identifierSize];
in.readFully(chars);
names.put(new Long(id), new String(chars));
break;
@ -351,8 +353,8 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes
return snapshot;
}
private void skipBytes(int length) throws IOException {
in.skipBytes(length);
private void skipBytes(long length) throws IOException {
in.skipBytes((int)length);
}
private int readVersionHeader() throws IOException {
@ -381,7 +383,7 @@ public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes
throw new IOException("Version string not recognized at byte " + (pos+3));
}
private void readHeapDump(int bytesLeft, int posAtEnd) throws IOException {
private void readHeapDump(long bytesLeft, long posAtEnd) throws IOException {
while (bytesLeft > 0) {
int type = in.readUnsignedByte();
if (debugLevel > 0) {

View File

@ -213,8 +213,8 @@ public class Button extends Component implements Accessible {
}
// This could change the preferred size of the Component.
if (testvalid && valid) {
invalidate();
if (testvalid) {
invalidateIfValid();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1995-2008 Sun Microsystems, Inc. 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
@ -284,8 +284,8 @@ public class Checkbox extends Component implements ItemSelectable, Accessible {
}
// This could change the preferred size of the Component.
if (testvalid && valid) {
invalidate();
if (testvalid) {
invalidateIfValid();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1995-2008 Sun Microsystems, Inc. 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
@ -207,9 +207,7 @@ public class Choice extends Component implements ItemSelectable, Accessible {
}
// This could change the preferred size of the Component.
if (valid) {
invalidate();
}
invalidateIfValid();
}
/**
@ -269,9 +267,7 @@ public class Choice extends Component implements ItemSelectable, Accessible {
}
// This could change the preferred size of the Component.
if (valid) {
invalidate();
}
invalidateIfValid();
}
/**
@ -299,9 +295,7 @@ public class Choice extends Component implements ItemSelectable, Accessible {
}
// This could change the preferred size of the Component.
if (valid) {
invalidate();
}
invalidateIfValid();
}
/**
@ -323,9 +317,7 @@ public class Choice extends Component implements ItemSelectable, Accessible {
}
// This could change the preferred size of the Component.
if (valid) {
invalidate();
}
invalidateIfValid();
}
/**
@ -367,9 +359,7 @@ public class Choice extends Component implements ItemSelectable, Accessible {
}
// This could change the preferred size of the Component.
if (valid) {
invalidate();
}
invalidateIfValid();
}
/**

View File

@ -350,7 +350,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
* @see #validate
* @see #invalidate
*/
volatile boolean valid = false;
private volatile boolean valid = false;
/**
* The <code>DropTarget</code> associated with this component.
@ -639,11 +639,21 @@ public abstract class Component implements ImageObserver, MenuContainer,
*/
private PropertyChangeSupport changeSupport;
// Note: this field is considered final, though readObject() prohibits
// initializing final fields.
private transient Object changeSupportLock = new Object();
private Object getChangeSupportLock() {
return changeSupportLock;
/*
* In some cases using "this" as an object to synchronize by
* can lead to a deadlock if client code also uses synchronization
* by a component object. For every such situation revealed we should
* consider possibility of replacing "this" with the package private
* objectLock object introduced below. So far there're 2 issues known:
* - CR 6708322 (the getName/setName methods);
* - CR 6608764 (the PropertyChangeListener machinery).
*
* Note: this field is considered final, though readObject() prohibits
* initializing final fields.
*/
private transient Object objectLock = new Object();
Object getObjectLock() {
return objectLock;
}
boolean isPacked = false;
@ -816,7 +826,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
*/
public String getName() {
if (name == null && !nameExplicitlySet) {
synchronized(this) {
synchronized(getObjectLock()) {
if (name == null && !nameExplicitlySet)
name = constructComponentName();
}
@ -833,7 +843,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
*/
public void setName(String name) {
String oldName;
synchronized(this) {
synchronized(getObjectLock()) {
oldName = this.name;
this.name = name;
nameExplicitlySet = true;
@ -1708,9 +1718,9 @@ public abstract class Component implements ImageObserver, MenuContainer,
// This could change the preferred size of the Component.
// Fix for 6213660. Should compare old and new fonts and do not
// call invalidate() if they are equal.
if (valid && f != oldFont && (oldFont == null ||
if (f != oldFont && (oldFont == null ||
!oldFont.equals(f))) {
invalidate();
invalidateIfValid();
}
}
@ -1767,9 +1777,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
firePropertyChange("locale", oldValue, l);
// This could change the preferred size of the Component.
if (valid) {
invalidate();
}
invalidateIfValid();
}
/**
@ -2078,8 +2086,8 @@ public abstract class Component implements ImageObserver, MenuContainer,
if (resized) {
invalidate();
}
if (parent != null && parent.valid) {
parent.invalidate();
if (parent != null) {
parent.invalidateIfValid();
}
}
if (needNotify) {
@ -2135,7 +2143,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
Toolkit.getEventQueue().postEvent(e);
}
} else {
if (this instanceof Container && ((Container)this).ncomponents > 0) {
if (this instanceof Container && ((Container)this).countComponents() > 0) {
boolean enabledOnToolkit =
Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
if (resized) {
@ -2648,7 +2656,8 @@ public abstract class Component implements ImageObserver, MenuContainer,
public void validate() {
synchronized (getTreeLock()) {
ComponentPeer peer = this.peer;
if (!valid && peer != null) {
boolean wasValid = isValid();
if (!wasValid && peer != null) {
Font newfont = getFont();
Font oldfont = peerFont;
if (newfont != oldfont && (oldfont == null
@ -2659,6 +2668,9 @@ public abstract class Component implements ImageObserver, MenuContainer,
peer.layout();
}
valid = true;
if (!wasValid) {
mixOnValidating();
}
}
}
@ -2687,12 +2699,20 @@ public abstract class Component implements ImageObserver, MenuContainer,
if (!isMaximumSizeSet()) {
maxSize = null;
}
if (parent != null && parent.valid) {
parent.invalidate();
if (parent != null) {
parent.invalidateIfValid();
}
}
}
/** Invalidates the component unless it is already invalid.
*/
final void invalidateIfValid() {
if (isValid()) {
invalidate();
}
}
/**
* Creates a graphics context for this component. This method will
* return <code>null</code> if this component is currently not
@ -5794,7 +5814,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
}
}
transient EventQueueItem[] eventCache;
transient sun.awt.EventQueueItem[] eventCache;
/**
* @see #isCoalescingEnabled
@ -7545,9 +7565,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
Container rootAncestor = getTraversalRoot();
Component comp = this;
while (rootAncestor != null &&
!(rootAncestor.isShowing() &&
rootAncestor.isFocusable() &&
rootAncestor.isEnabled()))
!(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
{
comp = rootAncestor;
rootAncestor = comp.getFocusCycleRootAncestor();
@ -7596,9 +7614,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
Container rootAncestor = getTraversalRoot();
Component comp = this;
while (rootAncestor != null &&
!(rootAncestor.isShowing() &&
rootAncestor.isFocusable() &&
rootAncestor.isEnabled()))
!(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
{
comp = rootAncestor;
rootAncestor = comp.getFocusCycleRootAncestor();
@ -7777,7 +7793,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
protected String paramString() {
String thisName = getName();
String str = (thisName != null? thisName : "") + "," + x + "," + y + "," + width + "x" + height;
if (!valid) {
if (!isValid()) {
str += ",invalid";
}
if (!visible) {
@ -7905,7 +7921,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
*/
public void addPropertyChangeListener(
PropertyChangeListener listener) {
synchronized (getChangeSupportLock()) {
synchronized (getObjectLock()) {
if (listener == null) {
return;
}
@ -7931,7 +7947,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
*/
public void removePropertyChangeListener(
PropertyChangeListener listener) {
synchronized (getChangeSupportLock()) {
synchronized (getObjectLock()) {
if (listener == null || changeSupport == null) {
return;
}
@ -7954,7 +7970,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
* @since 1.4
*/
public PropertyChangeListener[] getPropertyChangeListeners() {
synchronized (getChangeSupportLock()) {
synchronized (getObjectLock()) {
if (changeSupport == null) {
return new PropertyChangeListener[0];
}
@ -7996,7 +8012,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
public void addPropertyChangeListener(
String propertyName,
PropertyChangeListener listener) {
synchronized (getChangeSupportLock()) {
synchronized (getObjectLock()) {
if (listener == null) {
return;
}
@ -8026,7 +8042,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
public void removePropertyChangeListener(
String propertyName,
PropertyChangeListener listener) {
synchronized (getChangeSupportLock()) {
synchronized (getObjectLock()) {
if (listener == null || changeSupport == null) {
return;
}
@ -8050,7 +8066,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
*/
public PropertyChangeListener[] getPropertyChangeListeners(
String propertyName) {
synchronized (getChangeSupportLock()) {
synchronized (getObjectLock()) {
if (changeSupport == null) {
return new PropertyChangeListener[0];
}
@ -8071,7 +8087,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
protected void firePropertyChange(String propertyName,
Object oldValue, Object newValue) {
PropertyChangeSupport changeSupport;
synchronized (getChangeSupportLock()) {
synchronized (getObjectLock()) {
changeSupport = this.changeSupport;
}
if (changeSupport == null ||
@ -8373,7 +8389,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException
{
changeSupportLock = new Object();
objectLock = new Object();
s.defaultReadObject();
@ -8537,9 +8553,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
firePropertyChange("componentOrientation", oldValue, o);
// This could change the preferred size of the Component.
if (valid) {
invalidate();
}
invalidateIfValid();
}
/**
@ -8575,6 +8589,14 @@ public abstract class Component implements ImageObserver, MenuContainer,
setComponentOrientation(orientation);
}
final boolean canBeFocusOwner() {
// It is enabled, visible, focusable.
if (isEnabled() && isDisplayable() && isVisible() && isFocusable()) {
return true;
}
return false;
}
/**
* Checks that this component meets the prerequesites to be focus owner:
* - it is enabled, visible, focusable
@ -8584,9 +8606,9 @@ public abstract class Component implements ImageObserver, MenuContainer,
* this component as focus owner
* @since 1.5
*/
final boolean canBeFocusOwner() {
final boolean canBeFocusOwnerRecursively() {
// - it is enabled, visible, focusable
if (!(isEnabled() && isDisplayable() && isVisible() && isFocusable())) {
if (!canBeFocusOwner()) {
return false;
}
@ -9381,7 +9403,8 @@ public abstract class Component implements ImageObserver, MenuContainer,
*/
private boolean areBoundsValid() {
Container cont = getContainer();
return cont == null || cont.isValid() || cont.getLayout() == null;
return cont == null || cont.isValid()
|| cont.getLayout() == null;
}
/**
@ -9652,5 +9675,10 @@ public abstract class Component implements ImageObserver, MenuContainer,
}
}
void mixOnValidating() {
// This method gets overriden in the Container. Obviously, a plain
// non-container components don't need to handle validation.
}
// ****************** END OF MIXING CODE ********************************
}

View File

@ -44,8 +44,6 @@ import java.io.PrintWriter;
import java.util.Arrays;
import java.util.EventListener;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import java.util.logging.*;
@ -90,21 +88,14 @@ public class Container extends Component {
private static final Logger log = Logger.getLogger("java.awt.Container");
private static final Logger eventLog = Logger.getLogger("java.awt.event.Container");
/**
* The number of components in this container.
* This value can be null.
* @see #getComponent
* @see #getComponents
* @see #getComponentCount
*/
int ncomponents;
private static final Component[] EMPTY_ARRAY = new Component[0];
/**
* The components in this container.
* @see #add
* @see #getComponents
*/
Component component[] = new Component[0];
private java.util.List<Component> component = new java.util.ArrayList<Component>();
/**
* Layout manager for this container.
@ -290,7 +281,9 @@ public class Container extends Component {
*/
@Deprecated
public int countComponents() {
return ncomponents;
synchronized (getTreeLock()) {
return component.size();
}
}
/**
@ -302,10 +295,10 @@ public class Container extends Component {
*/
public Component getComponent(int n) {
synchronized (getTreeLock()) {
if ((n < 0) || (n >= ncomponents)) {
if ((n < 0) || (n >= component.size())) {
throw new ArrayIndexOutOfBoundsException("No such child: " + n);
}
return component[n];
return component.get(n);
}
}
@ -322,7 +315,7 @@ public class Container extends Component {
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
final Component[] getComponents_NoClientCode() {
synchronized (getTreeLock()) {
return Arrays.copyOf(component, ncomponents);
return component.toArray(EMPTY_ARRAY);
}
} // getComponents_NoClientCode()
@ -421,6 +414,29 @@ public class Container extends Component {
return comp;
}
/**
* Checks that the component
* isn't supposed to be added into itself.
*/
private void checkAddToSelf(Component comp){
if (comp instanceof Container) {
for (Container cn = this; cn != null; cn=cn.parent) {
if (cn == comp) {
throw new IllegalArgumentException("adding container's parent to itself");
}
}
}
}
/**
* Checks that the component is not a Window instance.
*/
private void checkNotAWindow(Component comp){
if (comp instanceof Window) {
throw new IllegalArgumentException("adding a window to a container");
}
}
/**
* Checks that the component comp can be added to this container
* Checks : index in bounds of container's size,
@ -437,26 +453,18 @@ public class Container extends Component {
GraphicsConfiguration thisGC = getGraphicsConfiguration();
if (index > ncomponents || index < 0) {
if (index > component.size() || index < 0) {
throw new IllegalArgumentException("illegal component position");
}
if (comp.parent == this) {
if (index == ncomponents) {
if (index == component.size()) {
throw new IllegalArgumentException("illegal component position " +
index + " should be less then " + ncomponents);
index + " should be less then " + component.size());
}
}
if (comp instanceof Container) {
for (Container cn = this; cn != null; cn=cn.parent) {
if (cn == comp) {
throw new IllegalArgumentException("adding container's parent to itself");
}
}
checkAddToSelf(comp);
checkNotAWindow(comp);
if (comp instanceof Window) {
throw new IllegalArgumentException("adding a window to a container");
}
}
Window thisTopLevel = getContainingWindow();
Window compTopLevel = comp.getContainingWindow();
if (thisTopLevel != compTopLevel) {
@ -495,25 +503,17 @@ public class Container extends Component {
adjustDescendants(-(comp.countHierarchyMembers()));
comp.parent = null;
System.arraycopy(component, index + 1,
component, index,
ncomponents - index - 1);
component[--ncomponents] = null;
component.remove(index);
if (valid) {
invalidate();
}
invalidateIfValid();
} else {
if (newIndex > index) { // 2->4: 012345 -> 013425, 2->5: 012345 -> 013452
if (newIndex-index > 0) {
System.arraycopy(component, index+1, component, index, newIndex-index);
}
} else { // 4->2: 012345 -> 014235
if (index-newIndex > 0) {
System.arraycopy(component, newIndex, component, newIndex+1, index-newIndex);
}
}
component[newIndex] = comp;
// We should remove component and then
// add it by the newIndex without newIndex decrement if even we shift components to the left
// after remove. Consult the rules below:
// 2->4: 012345 -> 013425, 2->5: 012345 -> 013452
// 4->2: 012345 -> 014235
component.remove(index);
component.add(newIndex, comp);
}
if (comp.parent == null) { // was actually removed
if (containerListener != null ||
@ -779,17 +779,11 @@ public class Container extends Component {
// Check if moving between containers
if (curParent != this) {
/* Add component to list; allocate new array if necessary. */
if (ncomponents == component.length) {
component = Arrays.copyOf(component, ncomponents * 2 + 1);
}
if (index == -1 || index == ncomponents) {
component[ncomponents++] = comp;
//index == -1 means add to the end.
if (index == -1) {
component.add(comp);
} else {
System.arraycopy(component, index, component,
index + 1, ncomponents - index);
component[index] = comp;
ncomponents++;
component.add(index, comp);
}
comp.parent = this;
@ -799,14 +793,12 @@ public class Container extends Component {
comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
adjustDescendants(comp.countHierarchyMembers());
} else {
if (index < ncomponents) {
component[index] = comp;
if (index < component.size()) {
component.set(index, comp);
}
}
if (valid) {
invalidate();
}
invalidateIfValid();
if (peer != null) {
if (comp.peer == null) { // Remove notify was called or it didn't have peer - create new one
comp.addNotify();
@ -860,11 +852,11 @@ public class Container extends Component {
// If component is focus owner or parent container of focus owner check that after reparenting
// focus owner moved out if new container prohibit this kind of focus owner.
if (comp.isFocusOwner() && !comp.canBeFocusOwner()) {
if (comp.isFocusOwner() && !comp.canBeFocusOwnerRecursively()) {
comp.transferFocus();
} else if (comp instanceof Container) {
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (focusOwner != null && isParentOf(focusOwner) && !focusOwner.canBeFocusOwner()) {
if (focusOwner != null && isParentOf(focusOwner) && !focusOwner.canBeFocusOwnerRecursively()) {
focusOwner.transferFocus();
}
}
@ -901,14 +893,8 @@ public class Container extends Component {
if (comp.parent != this) {
return -1;
}
for (int i = 0; i < ncomponents; i++) {
if (component[i] == comp) {
return i;
}
}
return component.indexOf(comp);
}
// To please javac
return -1;
}
/**
@ -1042,22 +1028,12 @@ public class Container extends Component {
*/
GraphicsConfiguration thisGC = this.getGraphicsConfiguration();
if (index > ncomponents || (index < 0 && index != -1)) {
if (index > component.size() || (index < 0 && index != -1)) {
throw new IllegalArgumentException(
"illegal component position");
}
if (comp instanceof Container) {
for (Container cn = this; cn != null; cn=cn.parent) {
if (cn == comp) {
throw new IllegalArgumentException(
"adding container's parent to itself");
}
}
if (comp instanceof Window) {
throw new IllegalArgumentException(
"adding a window to a container");
}
}
checkAddToSelf(comp);
checkNotAWindow(comp);
if (thisGC != null) {
comp.checkGD(thisGC.getDevice().getIDstring());
}
@ -1065,22 +1041,16 @@ public class Container extends Component {
/* Reparent the component and tidy up the tree's state. */
if (comp.parent != null) {
comp.parent.remove(comp);
if (index > ncomponents) {
if (index > component.size()) {
throw new IllegalArgumentException("illegal component position");
}
}
/* Add component to list; allocate new array if necessary. */
if (ncomponents == component.length) {
component = Arrays.copyOf(component, ncomponents * 2 + 1);
}
if (index == -1 || index == ncomponents) {
component[ncomponents++] = comp;
//index == -1 means add to the end.
if (index == -1) {
component.add(comp);
} else {
System.arraycopy(component, index, component,
index + 1, ncomponents - index);
component[index] = comp;
ncomponents++;
component.add(index, comp);
}
comp.parent = this;
@ -1090,9 +1060,7 @@ public class Container extends Component {
comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
adjustDescendants(comp.countHierarchyMembers());
if (valid) {
invalidate();
}
invalidateIfValid();
if (peer != null) {
comp.addNotify();
}
@ -1129,11 +1097,9 @@ public class Container extends Component {
* IllegalArgumentException.
*/
void checkGD(String stringID) {
Component tempComp;
for (int i = 0; i < component.length; i++) {
tempComp= component[i];
if (tempComp != null) {
tempComp.checkGD(stringID);
for (Component comp : component) {
if (comp != null) {
comp.checkGD(stringID);
}
}
}
@ -1163,10 +1129,10 @@ public class Container extends Component {
*/
public void remove(int index) {
synchronized (getTreeLock()) {
if (index < 0 || index >= ncomponents) {
if (index < 0 || index >= component.size()) {
throw new ArrayIndexOutOfBoundsException(index);
}
Component comp = component[index];
Component comp = component.get(index);
if (peer != null) {
comp.removeNotify();
}
@ -1181,14 +1147,9 @@ public class Container extends Component {
adjustDescendants(-(comp.countHierarchyMembers()));
comp.parent = null;
System.arraycopy(component, index + 1,
component, index,
ncomponents - index - 1);
component[--ncomponents] = null;
component.remove(index);
if (valid) {
invalidate();
}
invalidateIfValid();
if (containerListener != null ||
(eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
@ -1229,14 +1190,9 @@ public class Container extends Component {
public void remove(Component comp) {
synchronized (getTreeLock()) {
if (comp.parent == this) {
/* Search backwards, expect that more recent additions
* are more likely to be removed.
*/
Component component[] = this.component;
for (int i = ncomponents; --i >= 0; ) {
if (component[i] == comp) {
remove(i);
}
int index = component.indexOf(comp);
if (index >= 0) {
remove(index);
}
}
}
@ -1258,9 +1214,8 @@ public class Container extends Component {
-listeningBoundsChildren);
adjustDescendants(-descendantsCount);
while (ncomponents > 0) {
Component comp = component[--ncomponents];
component[ncomponents] = null;
while (!component.isEmpty()) {
Component comp = component.remove(component.size()-1);
if (peer != null) {
comp.removeNotify();
@ -1286,9 +1241,7 @@ public class Container extends Component {
if (peer != null && layoutMgr == null && isVisible()) {
updateCursorImmediately();
}
if (valid) {
invalidate();
}
invalidateIfValid();
}
}
@ -1300,8 +1253,8 @@ public class Container extends Component {
if (eventLog.isLoggable(Level.FINE)) {
// Verify listeningChildren is correct
int sum = 0;
for (int i = 0; i < ncomponents; i++) {
sum += component[i].numListening(mask);
for (Component comp : component) {
sum += comp.numListening(mask);
}
if (listeningChildren != sum) {
eventLog.log(Level.FINE, "Assertion (listeningChildren == sum) failed");
@ -1312,8 +1265,8 @@ public class Container extends Component {
if (eventLog.isLoggable(Level.FINE)) {
// Verify listeningBoundsChildren is correct
int sum = 0;
for (int i = 0; i < ncomponents; i++) {
sum += component[i].numListening(mask);
for (Component comp : component) {
sum += comp.numListening(mask);
}
if (listeningBoundsChildren != sum) {
eventLog.log(Level.FINE, "Assertion (listeningBoundsChildren == sum) failed");
@ -1375,8 +1328,8 @@ public class Container extends Component {
if (log.isLoggable(Level.FINE)) {
// Verify descendantsCount is correct
int sum = 0;
for (int i = 0; i < ncomponents; i++) {
sum += component[i].countHierarchyMembers();
for (Component comp : component) {
sum += comp.countHierarchyMembers();
}
if (descendantsCount != sum) {
log.log(Level.FINE, "Assertion (descendantsCount == sum) failed");
@ -1408,7 +1361,7 @@ public class Container extends Component {
int listeners = getListenersCount(id, enabledOnToolkit);
for (int count = listeners, i = 0; count > 0; i++) {
count -= component[i].createHierarchyEvents(id, changed,
count -= component.get(i).createHierarchyEvents(id, changed,
changedParent, changeFlags, enabledOnToolkit);
}
return listeners +
@ -1420,13 +1373,13 @@ public class Container extends Component {
boolean enabledOnToolkit)
{
assert Thread.holdsLock(getTreeLock());
if (ncomponents == 0) {
if (component.isEmpty()) {
return;
}
int listeners = getListenersCount(id, enabledOnToolkit);
for (int count = listeners, i = 0; count > 0; i++) {
count -= component[i].createHierarchyEvents(id, this, parent,
count -= component.get(i).createHierarchyEvents(id, this, parent,
changeFlags, enabledOnToolkit);
}
}
@ -1448,9 +1401,7 @@ public class Container extends Component {
*/
public void setLayout(LayoutManager mgr) {
layoutMgr = mgr;
if (valid) {
invalidate();
}
invalidateIfValid();
}
/**
@ -1522,10 +1473,10 @@ public class Container extends Component {
*/
public void validate() {
/* Avoid grabbing lock unless really necessary. */
if (!valid) {
if (!isValid()) {
boolean updateCur = false;
synchronized (getTreeLock()) {
if (!valid && peer != null) {
if (!isValid() && peer != null) {
ContainerPeer p = null;
if (peer instanceof ContainerPeer) {
p = (ContainerPeer) peer;
@ -1534,7 +1485,6 @@ public class Container extends Component {
p.beginValidate();
}
validateTree();
valid = true;
if (p != null) {
p.endValidate();
updateCur = isVisible();
@ -1557,17 +1507,16 @@ public class Container extends Component {
* @see #validate
*/
protected void validateTree() {
if (!valid) {
if (!isValid()) {
if (peer instanceof ContainerPeer) {
((ContainerPeer)peer).beginLayout();
}
doLayout();
Component component[] = this.component;
for (int i = 0 ; i < ncomponents ; ++i) {
Component comp = component[i];
for (int i = 0; i < component.size(); i++) {
Component comp = component.get(i);
if ( (comp instanceof Container)
&& !(comp instanceof Window)
&& !comp.valid) {
&& !(comp instanceof Window)
&& !comp.isValid()) {
((Container)comp).validateTree();
} else {
comp.validate();
@ -1577,7 +1526,7 @@ public class Container extends Component {
((ContainerPeer)peer).endLayout();
}
}
valid = true;
super.validate();
}
/**
@ -1586,20 +1535,16 @@ public class Container extends Component {
*/
void invalidateTree() {
synchronized (getTreeLock()) {
for (int i = 0; i < ncomponents; ++i) {
Component comp = component[i];
for (int i = 0; i < component.size(); i++) {
Component comp = component.get(i);
if (comp instanceof Container) {
((Container)comp).invalidateTree();
}
else {
if (comp.valid) {
comp.invalidate();
}
comp.invalidateIfValid();
}
}
if (valid) {
invalidate();
}
invalidateIfValid();
}
}
@ -1838,7 +1783,7 @@ public class Container extends Component {
// super.paint(); -- Don't bother, since it's a NOP.
GraphicsCallback.PaintCallback.getInstance().
runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS);
runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS);
}
}
@ -1893,7 +1838,7 @@ public class Container extends Component {
}
GraphicsCallback.PrintCallback.getInstance().
runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS);
runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS);
}
}
@ -1906,7 +1851,7 @@ public class Container extends Component {
public void paintComponents(Graphics g) {
if (isShowing()) {
GraphicsCallback.PaintAllCallback.getInstance().
runComponents(component, g, GraphicsCallback.TWO_PASSES);
runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.TWO_PASSES);
}
}
@ -1928,7 +1873,7 @@ public class Container extends Component {
void paintHeavyweightComponents(Graphics g) {
if (isShowing()) {
GraphicsCallback.PaintHeavyweightComponentsCallback.getInstance().
runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS |
runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS |
GraphicsCallback.HEAVYWEIGHTS);
}
}
@ -1942,7 +1887,7 @@ public class Container extends Component {
public void printComponents(Graphics g) {
if (isShowing()) {
GraphicsCallback.PrintAllCallback.getInstance().
runComponents(component, g, GraphicsCallback.TWO_PASSES);
runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.TWO_PASSES);
}
}
@ -1964,7 +1909,7 @@ public class Container extends Component {
void printHeavyweightComponents(Graphics g) {
if (isShowing()) {
GraphicsCallback.PrintHeavyweightComponentsCallback.getInstance().
runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS |
runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS |
GraphicsCallback.HEAVYWEIGHTS);
}
}
@ -2260,11 +2205,9 @@ public class Container extends Component {
boolean searchHeavyweightChildren,
boolean searchHeavyweightDescendants) {
synchronized (getTreeLock()) {
int ncomponents = this.ncomponents;
Component component[] = this.component;
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = component[i];
for (int i = 0; i < component.size(); i++) {
Component comp = component.get(i);
if (comp != null && comp.visible &&
((!searchHeavyweightChildren &&
comp.peer instanceof LightweightPeer) ||
@ -2415,8 +2358,8 @@ public class Container extends Component {
}
synchronized (getTreeLock()) {
// Two passes: see comment in sun.awt.SunGraphicsCallback
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = component[i];
for (int i = 0; i < component.size(); i++) {
Component comp = component.get(i);
if (comp != null &&
!(comp.peer instanceof LightweightPeer)) {
if (comp.contains(x - comp.x, y - comp.y)) {
@ -2424,8 +2367,8 @@ public class Container extends Component {
}
}
}
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = component[i];
for (int i = 0; i < component.size(); i++) {
Component comp = component.get(i);
if (comp != null &&
comp.peer instanceof LightweightPeer) {
if (comp.contains(x - comp.x, y - comp.y)) {
@ -2544,43 +2487,43 @@ public class Container extends Component {
if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) {
return null;
}
int ncomponents = this.ncomponents;
Component component[] = this.component;
// Two passes: see comment in sun.awt.SunGraphicsCallback
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = component[i];
if (comp != null &&
!(comp.peer instanceof LightweightPeer)) {
if (comp instanceof Container) {
comp = ((Container)comp).findComponentAtImpl(x - comp.x,
y - comp.y,
ignoreEnabled);
} else {
comp = comp.locate(x - comp.x, y - comp.y);
}
if (comp != null && comp.visible &&
(ignoreEnabled || comp.enabled))
{
return comp;
synchronized (getTreeLock()) {
for (int i = 0; i < component.size(); i++) {
Component comp = component.get(i);
if (comp != null &&
!(comp.peer instanceof LightweightPeer)) {
if (comp instanceof Container) {
comp = ((Container)comp).findComponentAtImpl(x - comp.x,
y - comp.y,
ignoreEnabled);
} else {
comp = comp.locate(x - comp.x, y - comp.y);
}
if (comp != null && comp.visible &&
(ignoreEnabled || comp.enabled))
{
return comp;
}
}
}
}
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = component[i];
if (comp != null &&
comp.peer instanceof LightweightPeer) {
if (comp instanceof Container) {
comp = ((Container)comp).findComponentAtImpl(x - comp.x,
y - comp.y,
ignoreEnabled);
} else {
comp = comp.locate(x - comp.x, y - comp.y);
}
if (comp != null && comp.visible &&
(ignoreEnabled || comp.enabled))
{
return comp;
for (int i = 0; i < component.size(); i++) {
Component comp = component.get(i);
if (comp != null &&
comp.peer instanceof LightweightPeer) {
if (comp instanceof Container) {
comp = ((Container)comp).findComponentAtImpl(x - comp.x,
y - comp.y,
ignoreEnabled);
} else {
comp = comp.locate(x - comp.x, y - comp.y);
}
if (comp != null && comp.visible &&
(ignoreEnabled || comp.enabled))
{
return comp;
}
}
}
}
@ -2632,10 +2575,14 @@ public class Container extends Component {
if (! (peer instanceof LightweightPeer)) {
dispatcher = new LightweightDispatcher(this);
}
int ncomponents = this.ncomponents;
Component component[] = this.component;
for (int i = 0 ; i < ncomponents ; i++) {
component[i].addNotify();
// We shouldn't use iterator because of the Swing menu
// implementation specifics:
// the menu is being assigned as a child to JLayeredPane
// instead of particular component so always affect
// collection of component if menu is becoming shown or hidden.
for (int i = 0; i < component.size(); i++) {
component.get(i).addNotify();
}
// Update stacking order if native platform allows
ContainerPeer cpeer = (ContainerPeer)peer;
@ -2658,21 +2605,25 @@ public class Container extends Component {
*/
public void removeNotify() {
synchronized (getTreeLock()) {
int ncomponents = this.ncomponents;
Component component[] = this.component;
for (int i = ncomponents - 1; i >= 0; i--) {
if( component[i] != null ) {
// We shouldn't use iterator because of the Swing menu
// implementation specifics:
// the menu is being assigned as a child to JLayeredPane
// instead of particular component so always affect
// collection of component if menu is becoming shown or hidden.
for (int i = component.size()-1 ; i >= 0 ; i--) {
Component comp = component.get(i);
if (comp != null) {
// Fix for 6607170.
// We want to suppress focus change on disposal
// of the focused component. But because of focus
// is asynchronous, we should suppress focus change
// on every component in case it receives native focus
// in the process of disposal.
component[i].setAutoFocusTransferOnDisposal(false);
component[i].removeNotify();
component[i].setAutoFocusTransferOnDisposal(true);
}
}
comp.setAutoFocusTransferOnDisposal(false);
comp.removeNotify();
comp.setAutoFocusTransferOnDisposal(true);
}
}
// If some of the children had focus before disposal then it still has.
// Auto-transfer focus to the next (or previous) component if auto-transfer
// is enabled.
@ -2683,7 +2634,7 @@ public class Container extends Component {
}
if ( dispatcher != null ) {
dispatcher.dispose();
dispatcher = null;
dispatcher = null;
}
super.removeNotify();
}
@ -2873,12 +2824,12 @@ public class Container extends Component {
*/
public void list(PrintStream out, int indent) {
super.list(out, indent);
int ncomponents = this.ncomponents;
Component component[] = this.component;
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = component[i];
if (comp != null) {
comp.list(out, indent+1);
synchronized(getTreeLock()) {
for (int i = 0; i < component.size(); i++) {
Component comp = component.get(i);
if (comp != null) {
comp.list(out, indent+1);
}
}
}
}
@ -2899,12 +2850,12 @@ public class Container extends Component {
*/
public void list(PrintWriter out, int indent) {
super.list(out, indent);
int ncomponents = this.ncomponents;
Component component[] = this.component;
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = component[i];
if (comp != null) {
comp.list(out, indent+1);
synchronized(getTreeLock()) {
for (int i = 0; i < component.size(); i++) {
Component comp = component.get(i);
if (comp != null) {
comp.list(out, indent+1);
}
}
}
}
@ -3414,9 +3365,11 @@ public class Container extends Component {
*/
public void applyComponentOrientation(ComponentOrientation o) {
super.applyComponentOrientation(o);
for (int i = 0 ; i < ncomponents ; ++i) {
component[i].applyComponentOrientation(o);
synchronized (getTreeLock()) {
for (int i = 0; i < component.size(); i++) {
Component comp = component.get(i);
comp.applyComponentOrientation(o);
}
}
}
@ -3534,8 +3487,8 @@ public class Container extends Component {
*/
private void writeObject(ObjectOutputStream s) throws IOException {
ObjectOutputStream.PutField f = s.putFields();
f.put("ncomponents", ncomponents);
f.put("component", component);
f.put("ncomponents", component.size());
f.put("component", component.toArray(EMPTY_ARRAY));
f.put("layoutMgr", layoutMgr);
f.put("dispatcher", dispatcher);
f.put("maxSize", maxSize);
@ -3574,8 +3527,12 @@ public class Container extends Component {
throws ClassNotFoundException, IOException
{
ObjectInputStream.GetField f = s.readFields();
ncomponents = f.get("ncomponents", 0);
component = (Component[])f.get("component", new Component[0]);
Component [] tmpComponent = (Component[])f.get("component", EMPTY_ARRAY);
int ncomponents = (Integer) f.get("ncomponents", 0);
component = new java.util.ArrayList<Component>(ncomponents);
for (int i = 0; i < ncomponents; ++i) {
component.add(tmpComponent[i]);
}
layoutMgr = (LayoutManager)f.get("layoutMgr", null);
dispatcher = (LightweightDispatcher)f.get("dispatcher", null);
// Old stream. Doesn't contain maxSize among Component's fields.
@ -3585,16 +3542,14 @@ public class Container extends Component {
focusCycleRoot = f.get("focusCycleRoot", false);
containerSerializedDataVersion = f.get("containerSerializedDataVersion", 1);
focusTraversalPolicyProvider = f.get("focusTraversalPolicyProvider", false);
Component component[] = this.component;
for(int i = 0; i < ncomponents; i++) {
component[i].parent = this;
java.util.List<Component> component = this.component;
for(Component comp : component) {
comp.parent = this;
adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
component[i].numListening(AWTEvent.HIERARCHY_EVENT_MASK));
comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
component[i].numListening(
AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
adjustDescendants(component[i].countHierarchyMembers());
comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
adjustDescendants(comp.countHierarchyMembers());
}
Object keyOrNull;
@ -4111,6 +4066,21 @@ public class Container extends Component {
}
}
@Override
void mixOnValidating() {
synchronized (getTreeLock()) {
if (mixingLog.isLoggable(Level.FINE)) {
mixingLog.fine("this = " + this);
}
if (hasHeavyweightDescendants()) {
recursiveApplyCurrentShape();
}
super.mixOnValidating();
}
}
// ****************** END OF MIXING CODE ********************************
}

View File

@ -556,8 +556,7 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
* enabled, and focusable; <code>false</code> otherwise
*/
protected boolean accept(Component aComponent) {
if (!(aComponent.isVisible() && aComponent.isDisplayable() &&
aComponent.isFocusable() && aComponent.isEnabled())) {
if (!aComponent.canBeFocusOwner()) {
return false;
}

View File

@ -154,7 +154,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
private boolean doRestoreFocus(Component toFocus, Component vetoedComponent,
boolean clearOnFailure)
{
if (toFocus != vetoedComponent && toFocus.isShowing() && toFocus.isFocusable() &&
if (toFocus != vetoedComponent && toFocus.isShowing() && toFocus.canBeFocusOwner() &&
toFocus.requestFocus(false, CausedFocusEvent.Cause.ROLLBACK))
{
return true;
@ -500,8 +500,11 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
}
}
if (!(newFocusOwner.isFocusable() && newFocusOwner.isEnabled()
&& newFocusOwner.isShowing()))
if (!(newFocusOwner.isFocusable() && newFocusOwner.isShowing() &&
// Refuse focus on a disabled component if the focus event
// isn't of UNKNOWN reason (i.e. not a result of a direct request
// but traversal, activation or system generated).
(newFocusOwner.isEnabled() || cause.equals(CausedFocusEvent.Cause.UNKNOWN))))
{
// we should not accept focus on such component, so reject it.
dequeueKeyEvents(-1, newFocusOwner);
@ -742,8 +745,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
public boolean dispatchKeyEvent(KeyEvent e) {
Component focusOwner = (((AWTEvent)e).isPosted) ? getFocusOwner() : e.getComponent();
if (focusOwner != null && focusOwner.isShowing() &&
focusOwner.isFocusable() && focusOwner.isEnabled()) {
if (focusOwner != null && focusOwner.isShowing() && focusOwner.canBeFocusOwner()) {
if (!e.isConsumed()) {
Component comp = e.getComponent();
if (comp != null && comp.isEnabled()) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1995-2008 Sun Microsystems, Inc. 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
@ -1327,8 +1327,8 @@ public class Dialog extends Window {
// the insets of the Dialog. If we could, we'd call invalidate()
// from the peer, but we need to guarantee that we're not holding
// the Dialog lock when we call invalidate().
if (testvalid && valid) {
invalidate();
if (testvalid) {
invalidateIfValid();
}
}

View File

@ -42,6 +42,7 @@ import sun.awt.AppContext;
import sun.awt.AWTAutoShutdown;
import sun.awt.PeerEvent;
import sun.awt.SunToolkit;
import sun.awt.EventQueueItem;
/**
* <code>EventQueue</code> is a platform-independent class
@ -359,7 +360,7 @@ public class EventQueue {
entry != null; entry = entry.next)
{
// Give Component.coalesceEvents a chance
if (entry.event.getSource() == source && entry.id == id) {
if (entry.event.getSource() == source && entry.event.getID() == id) {
AWTEvent coalescedEvent = source.coalesceEvents(
entry.event, e);
if (coalescedEvent != null) {
@ -499,7 +500,7 @@ public class EventQueue {
for (EventQueueItem entry = queues[i].head, prev = null;
entry != null; prev = entry, entry = entry.next)
{
if (entry.id == id) {
if (entry.event.getID() == id) {
if (prev == null) {
queues[i].head = entry.next;
} else {
@ -545,7 +546,7 @@ public class EventQueue {
for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
EventQueueItem q = queues[i].head;
for (; q != null; q = q.next) {
if (q.id == id) {
if (q.event.getID() == id) {
return q.event;
}
}
@ -1051,14 +1052,3 @@ class Queue {
EventQueueItem head;
EventQueueItem tail;
}
class EventQueueItem {
AWTEvent event;
int id;
EventQueueItem next;
EventQueueItem(AWTEvent evt) {
event = evt;
id = evt.getID();
}
}

Some files were not shown because too many files have changed in this diff Show More