Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
e44c8167
Commit
e44c8167
authored
Feb 24, 2018
by
David Herberth
Committed by
Stephane Nicoll
May 14, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Set classloader for JMX endpoints to application classloader
See gh-12209
parent
c14b3a37
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
3 deletions
+61
-3
EndpointMBean.java
...ingframework/boot/actuate/endpoint/jmx/EndpointMBean.java
+35
-2
JmxEndpointExporter.java
...mework/boot/actuate/endpoint/jmx/JmxEndpointExporter.java
+10
-1
EndpointMBeanTests.java
...amework/boot/actuate/endpoint/jmx/EndpointMBeanTests.java
+16
-0
No files found.
spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/EndpointMBean.java
View file @
e44c8167
...
@@ -29,8 +29,11 @@ import javax.management.MBeanException;
...
@@ -29,8 +29,11 @@ import javax.management.MBeanException;
import
javax.management.MBeanInfo
;
import
javax.management.MBeanInfo
;
import
javax.management.ReflectionException
;
import
javax.management.ReflectionException
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
reactor.core.publisher.Mono
;
import
reactor.core.publisher.Mono
;
import
org.springframework.beans.factory.BeanClassLoaderAware
;
import
org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException
;
import
org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException
;
import
org.springframework.boot.actuate.endpoint.InvocationContext
;
import
org.springframework.boot.actuate.endpoint.InvocationContext
;
import
org.springframework.boot.actuate.endpoint.SecurityContext
;
import
org.springframework.boot.actuate.endpoint.SecurityContext
;
...
@@ -46,11 +49,15 @@ import org.springframework.util.ClassUtils;
...
@@ -46,11 +49,15 @@ import org.springframework.util.ClassUtils;
* @author Phillip Webb
* @author Phillip Webb
* @since 2.0.0
* @since 2.0.0
*/
*/
public
class
EndpointMBean
implements
DynamicMBean
{
public
class
EndpointMBean
implements
DynamicMBean
,
BeanClassLoaderAware
{
private
static
final
boolean
REACTOR_PRESENT
=
ClassUtils
.
isPresent
(
private
static
final
boolean
REACTOR_PRESENT
=
ClassUtils
.
isPresent
(
"reactor.core.publisher.Mono"
,
EndpointMBean
.
class
.
getClassLoader
());
"reactor.core.publisher.Mono"
,
EndpointMBean
.
class
.
getClassLoader
());
private
static
final
Log
logger
=
LogFactory
.
getLog
(
EndpointMBean
.
class
);
private
ClassLoader
classLoader
;
private
final
JmxOperationResponseMapper
responseMapper
;
private
final
JmxOperationResponseMapper
responseMapper
;
private
final
ExposableJmxEndpoint
endpoint
;
private
final
ExposableJmxEndpoint
endpoint
;
...
@@ -69,6 +76,11 @@ public class EndpointMBean implements DynamicMBean {
...
@@ -69,6 +76,11 @@ public class EndpointMBean implements DynamicMBean {
this
.
operations
=
getOperations
(
endpoint
);
this
.
operations
=
getOperations
(
endpoint
);
}
}
@Override
public
void
setBeanClassLoader
(
ClassLoader
classLoader
)
{
this
.
classLoader
=
classLoader
;
}
private
Map
<
String
,
JmxOperation
>
getOperations
(
ExposableJmxEndpoint
endpoint
)
{
private
Map
<
String
,
JmxOperation
>
getOperations
(
ExposableJmxEndpoint
endpoint
)
{
Map
<
String
,
JmxOperation
>
operations
=
new
HashMap
<>();
Map
<
String
,
JmxOperation
>
operations
=
new
HashMap
<>();
endpoint
.
getOperations
()
endpoint
.
getOperations
()
...
@@ -90,7 +102,28 @@ public class EndpointMBean implements DynamicMBean {
...
@@ -90,7 +102,28 @@ public class EndpointMBean implements DynamicMBean {
+
"' has no operation named "
+
actionName
;
+
"' has no operation named "
+
actionName
;
throw
new
ReflectionException
(
new
IllegalArgumentException
(
message
),
message
);
throw
new
ReflectionException
(
new
IllegalArgumentException
(
message
),
message
);
}
}
return
invoke
(
operation
,
params
);
ClassLoader
previousClassLoader
=
overrideThreadContextClassLoaderSafe
(
this
.
classLoader
);
try
{
return
invoke
(
operation
,
params
);
}
finally
{
overrideThreadContextClassLoaderSafe
(
previousClassLoader
);
}
}
private
static
ClassLoader
overrideThreadContextClassLoaderSafe
(
ClassLoader
classLoader
)
{
if
(
classLoader
==
null
)
{
return
null
;
}
try
{
return
ClassUtils
.
overrideThreadContextClassLoader
(
classLoader
);
}
catch
(
SecurityException
exc
)
{
// can't set class loader, ignore it and proceed
logger
.
warn
(
"Unable to override class loader for JMX endpoint."
);
}
return
null
;
}
}
private
Object
invoke
(
JmxOperation
operation
,
Object
[]
params
)
private
Object
invoke
(
JmxOperation
operation
,
Object
[]
params
)
...
...
spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/JmxEndpointExporter.java
View file @
e44c8167
...
@@ -29,6 +29,7 @@ import javax.management.ObjectName;
...
@@ -29,6 +29,7 @@ import javax.management.ObjectName;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.apache.commons.logging.LogFactory
;
import
org.springframework.beans.factory.BeanClassLoaderAware
;
import
org.springframework.beans.factory.DisposableBean
;
import
org.springframework.beans.factory.DisposableBean
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.jmx.JmxException
;
import
org.springframework.jmx.JmxException
;
...
@@ -42,10 +43,12 @@ import org.springframework.util.Assert;
...
@@ -42,10 +43,12 @@ import org.springframework.util.Assert;
* @author Phillip Webb
* @author Phillip Webb
* @since 2.0.0
* @since 2.0.0
*/
*/
public
class
JmxEndpointExporter
implements
InitializingBean
,
DisposableBean
{
public
class
JmxEndpointExporter
implements
InitializingBean
,
DisposableBean
,
BeanClassLoaderAware
{
private
static
final
Log
logger
=
LogFactory
.
getLog
(
JmxEndpointExporter
.
class
);
private
static
final
Log
logger
=
LogFactory
.
getLog
(
JmxEndpointExporter
.
class
);
private
ClassLoader
classLoader
;
private
final
MBeanServer
mBeanServer
;
private
final
MBeanServer
mBeanServer
;
private
final
EndpointObjectNameFactory
objectNameFactory
;
private
final
EndpointObjectNameFactory
objectNameFactory
;
...
@@ -70,6 +73,11 @@ public class JmxEndpointExporter implements InitializingBean, DisposableBean {
...
@@ -70,6 +73,11 @@ public class JmxEndpointExporter implements InitializingBean, DisposableBean {
this
.
endpoints
=
Collections
.
unmodifiableCollection
(
endpoints
);
this
.
endpoints
=
Collections
.
unmodifiableCollection
(
endpoints
);
}
}
@Override
public
void
setBeanClassLoader
(
ClassLoader
classLoader
)
{
this
.
classLoader
=
classLoader
;
}
@Override
@Override
public
void
afterPropertiesSet
()
{
public
void
afterPropertiesSet
()
{
this
.
registered
=
register
();
this
.
registered
=
register
();
...
@@ -89,6 +97,7 @@ public class JmxEndpointExporter implements InitializingBean, DisposableBean {
...
@@ -89,6 +97,7 @@ public class JmxEndpointExporter implements InitializingBean, DisposableBean {
try
{
try
{
ObjectName
name
=
this
.
objectNameFactory
.
getObjectName
(
endpoint
);
ObjectName
name
=
this
.
objectNameFactory
.
getObjectName
(
endpoint
);
EndpointMBean
mbean
=
new
EndpointMBean
(
this
.
responseMapper
,
endpoint
);
EndpointMBean
mbean
=
new
EndpointMBean
(
this
.
responseMapper
,
endpoint
);
mbean
.
setBeanClassLoader
(
this
.
classLoader
);
this
.
mBeanServer
.
registerMBean
(
mbean
,
name
);
this
.
mBeanServer
.
registerMBean
(
mbean
,
name
);
return
name
;
return
name
;
}
}
...
...
spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/EndpointMBeanTests.java
View file @
e44c8167
...
@@ -16,6 +16,9 @@
...
@@ -16,6 +16,9 @@
package
org
.
springframework
.
boot
.
actuate
.
endpoint
.
jmx
;
package
org
.
springframework
.
boot
.
actuate
.
endpoint
.
jmx
;
import
java.net.URL
;
import
java.net.URLClassLoader
;
import
javax.management.Attribute
;
import
javax.management.Attribute
;
import
javax.management.AttributeList
;
import
javax.management.AttributeList
;
import
javax.management.AttributeNotFoundException
;
import
javax.management.AttributeNotFoundException
;
...
@@ -32,6 +35,7 @@ import reactor.core.publisher.Mono;
...
@@ -32,6 +35,7 @@ import reactor.core.publisher.Mono;
import
org.springframework.beans.FatalBeanException
;
import
org.springframework.beans.FatalBeanException
;
import
org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException
;
import
org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException
;
import
org.springframework.boot.actuate.endpoint.InvocationContext
;
import
org.springframework.boot.actuate.endpoint.InvocationContext
;
import
org.springframework.util.ClassUtils
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
hamcrest
.
CoreMatchers
.
instanceOf
;
import
static
org
.
hamcrest
.
CoreMatchers
.
instanceOf
;
...
@@ -126,6 +130,18 @@ public class EndpointMBeanTests {
...
@@ -126,6 +130,18 @@ public class EndpointMBeanTests {
bean
.
invoke
(
"missingOperation"
,
NO_PARAMS
,
NO_SIGNATURE
);
bean
.
invoke
(
"missingOperation"
,
NO_PARAMS
,
NO_SIGNATURE
);
}
}
@Test
public
void
invokeShouldInvokeJmxOperationWithBeanClassLoader
()
throws
ReflectionException
,
MBeanException
{
TestExposableJmxEndpoint
endpoint
=
new
TestExposableJmxEndpoint
(
new
TestJmxOperation
((
arguments
)
->
ClassUtils
.
getDefaultClassLoader
()));
URLClassLoader
beanClassLoader
=
new
URLClassLoader
(
new
URL
[]{},
getClass
().
getClassLoader
());
EndpointMBean
bean
=
new
EndpointMBean
(
this
.
responseMapper
,
endpoint
);
bean
.
setBeanClassLoader
(
beanClassLoader
);
Object
result
=
bean
.
invoke
(
"testOperation"
,
NO_PARAMS
,
NO_SIGNATURE
);
assertThat
(
result
).
isEqualTo
(
beanClassLoader
);
}
@Test
@Test
public
void
invokeWhenOperationIsInvalidShouldThrowException
()
public
void
invokeWhenOperationIsInvalidShouldThrowException
()
throws
MBeanException
,
ReflectionException
{
throws
MBeanException
,
ReflectionException
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment