1
1
/*
2
- * Copyright 2002-2016 the original author or authors.
2
+ * Copyright 2002-2018 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
16
16
17
17
package org .springframework .remoting .rmi ;
18
18
19
- import java .rmi .NoSuchObjectException ;
19
+ import java .lang .reflect .InvocationTargetException ;
20
+ import java .lang .reflect .Method ;
20
21
import java .rmi .Remote ;
21
22
import java .rmi .RemoteException ;
22
23
import java .util .Properties ;
25
26
import org .springframework .beans .factory .DisposableBean ;
26
27
import org .springframework .beans .factory .InitializingBean ;
27
28
import org .springframework .jndi .JndiTemplate ;
29
+ import org .springframework .lang .Nullable ;
30
+ import org .springframework .util .ReflectionUtils ;
28
31
29
32
/**
30
33
* Service exporter which binds RMI services to JNDI.
66
69
*/
67
70
public class JndiRmiServiceExporter extends RmiBasedExporter implements InitializingBean , DisposableBean {
68
71
72
+ @ Nullable
73
+ private static Method exportObject ;
74
+
75
+ @ Nullable
76
+ private static Method unexportObject ;
77
+
78
+ static {
79
+ try {
80
+ Class <?> portableRemoteObject =
81
+ JndiRmiServiceExporter .class .getClassLoader ().loadClass ("javax.rmi.PortableRemoteObject" );
82
+ exportObject = portableRemoteObject .getMethod ("exportObject" , Remote .class );
83
+ unexportObject = portableRemoteObject .getMethod ("unexportObject" , Remote .class );
84
+ }
85
+ catch (Throwable ex ) {
86
+ // java.corba module not available on JDK 9+
87
+ exportObject = null ;
88
+ unexportObject = null ;
89
+ }
90
+ }
91
+
92
+
69
93
private JndiTemplate jndiTemplate = new JndiTemplate ();
70
94
71
95
private String jndiName ;
@@ -116,6 +140,7 @@ public void prepare() throws NamingException, RemoteException {
116
140
117
141
// Initialize and cache exported object.
118
142
this .exportedObject = getObjectToExport ();
143
+ invokePortableRemoteObject (exportObject );
119
144
120
145
rebind ();
121
146
}
@@ -136,11 +161,31 @@ public void rebind() throws NamingException {
136
161
* Unbind the RMI service from JNDI on bean factory shutdown.
137
162
*/
138
163
@ Override
139
- public void destroy () throws NamingException , NoSuchObjectException {
164
+ public void destroy () throws NamingException , RemoteException {
140
165
if (logger .isInfoEnabled ()) {
141
166
logger .info ("Unbinding RMI service from JNDI location [" + this .jndiName + "]" );
142
167
}
143
168
this .jndiTemplate .unbind (this .jndiName );
169
+ invokePortableRemoteObject (unexportObject );
170
+ }
171
+
172
+
173
+ private void invokePortableRemoteObject (@ Nullable Method method ) throws RemoteException {
174
+ if (method != null ) {
175
+ try {
176
+ method .invoke (null , this .exportedObject );
177
+ }
178
+ catch (InvocationTargetException ex ) {
179
+ Throwable targetEx = ex .getTargetException ();
180
+ if (targetEx instanceof RemoteException ) {
181
+ throw (RemoteException ) targetEx ;
182
+ }
183
+ ReflectionUtils .rethrowRuntimeException (targetEx );
184
+ }
185
+ catch (Throwable ex ) {
186
+ throw new IllegalStateException ("PortableRemoteObject invocation failed" , ex );
187
+ }
188
+ }
144
189
}
145
190
146
191
}
0 commit comments