Skip to content

Commit 5c92d60

Browse files
authored
HADOOP-19329. Remove direct usage of sun.misc.Signal (#7759) Contributed by Cheng Pan.
* HADOOP-19329. Remove directly usage of sun.misc.Signal Reviewed-by: Chris Nauroth <[email protected]> Signed-off-by: Shilun Fan <[email protected]>
1 parent b68dc8a commit 5c92d60

File tree

3 files changed

+181
-18
lines changed

3 files changed

+181
-18
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/service/launcher/IrqHandler.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@
2121
import java.util.concurrent.atomic.AtomicInteger;
2222

2323
import org.apache.hadoop.util.Preconditions;
24+
import org.apache.hadoop.util.SignalUtil;
2425
import org.slf4j.Logger;
2526
import org.slf4j.LoggerFactory;
26-
import sun.misc.Signal;
27-
import sun.misc.SignalHandler;
2827

2928
import org.apache.hadoop.classification.InterfaceAudience;
3029
import org.apache.hadoop.classification.InterfaceStability;
@@ -38,8 +37,7 @@
3837
*/
3938
@InterfaceAudience.Private
4039
@InterfaceStability.Unstable
41-
@SuppressWarnings("UseOfSunClasses")
42-
public final class IrqHandler implements SignalHandler {
40+
public final class IrqHandler implements SignalUtil.Handler {
4341
private static final Logger LOG = LoggerFactory.getLogger(IrqHandler.class);
4442

4543
/**
@@ -68,7 +66,7 @@ public final class IrqHandler implements SignalHandler {
6866
/**
6967
* Stored signal.
7068
*/
71-
private Signal signal;
69+
private SignalUtil.Signal signal;
7270

7371
/**
7472
* Create an IRQ handler bound to the specific interrupt.
@@ -89,8 +87,8 @@ public IrqHandler(String name, Interrupted handler) {
8987
public void bind() {
9088
Preconditions.checkState(signal == null, "Handler already bound");
9189
try {
92-
signal = new Signal(name);
93-
Signal.handle(signal, this);
90+
signal = new SignalUtil.Signal(name);
91+
SignalUtil.handle(signal, this);
9492
} catch (IllegalArgumentException e) {
9593
throw new IllegalArgumentException(
9694
"Could not set handler for signal \"" + name + "\"."
@@ -110,7 +108,7 @@ public String getName() {
110108
* Raise the signal.
111109
*/
112110
public void raise() {
113-
Signal.raise(signal);
111+
SignalUtil.raise(signal);
114112
}
115113

116114
@Override
@@ -123,7 +121,7 @@ public String toString() {
123121
* @param s signal raised
124122
*/
125123
@Override
126-
public void handle(Signal s) {
124+
public void handle(SignalUtil.Signal s) {
127125
signalCount.incrementAndGet();
128126
InterruptData data = new InterruptData(s.getName(), s.getNumber());
129127
LOG.info("Interrupted: {}", data);

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/SignalLogger.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
package org.apache.hadoop.util;
2020

2121
import org.slf4j.Logger;
22-
import sun.misc.Signal;
23-
import sun.misc.SignalHandler;
2422

2523
import org.apache.hadoop.classification.InterfaceAudience;
2624
import org.apache.hadoop.classification.InterfaceStability;
@@ -41,13 +39,13 @@ public enum SignalLogger {
4139
/**
4240
* Our signal handler.
4341
*/
44-
private static class Handler implements SignalHandler {
42+
private static class Handler implements SignalUtil.Handler {
4543
final private Logger log;
46-
final private SignalHandler prevHandler;
44+
final private SignalUtil.Handler prevHandler;
4745

4846
Handler(String name, Logger log) {
4947
this.log = log;
50-
prevHandler = Signal.handle(new Signal(name), this);
48+
prevHandler = SignalUtil.handle(new SignalUtil.Signal(name), this);
5149
}
5250

5351
/**
@@ -56,9 +54,8 @@ private static class Handler implements SignalHandler {
5654
* @param signal The incoming signal
5755
*/
5856
@Override
59-
public void handle(Signal signal) {
60-
log.error("RECEIVED SIGNAL " + signal.getNumber() +
61-
": SIG" + signal.getName());
57+
public void handle(SignalUtil.Signal signal) {
58+
log.error("RECEIVED SIGNAL {}: SIG{}", signal.getNumber(), signal.getName());
6259
prevHandler.handle(signal);
6360
}
6461
}
@@ -75,7 +72,7 @@ public void register(final Logger log) {
7572
registered = true;
7673
StringBuilder bld = new StringBuilder();
7774
bld.append("registered UNIX signal handlers for [");
78-
final String SIGNALS[] = { "TERM", "HUP", "INT" };
75+
final String[] SIGNALS = {"TERM", "HUP", "INT"};
7976
String separator = "";
8077
for (String signalName : SIGNALS) {
8178
try {
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.hadoop.util;
20+
21+
import org.apache.hadoop.classification.InterfaceAudience;
22+
23+
import org.apache.hadoop.util.dynamic.BindingUtils;
24+
import org.apache.hadoop.util.dynamic.DynConstructors;
25+
import org.apache.hadoop.util.dynamic.DynMethods;
26+
27+
import java.lang.reflect.Method;
28+
import java.lang.reflect.Proxy;
29+
30+
@InterfaceAudience.Private
31+
public class SignalUtil {
32+
33+
static final Class<?> JDK_SIGNAL_CLAZZ =
34+
BindingUtils.loadClassSafely("sun.misc.Signal");
35+
static final Class<?> JDK_SIGNAL_HANDLER_CLAZZ =
36+
BindingUtils.loadClassSafely("sun.misc.SignalHandler");
37+
38+
static final DynConstructors.Ctor<?> JDK_SIGNAL_CTOR =
39+
new DynConstructors.Builder()
40+
.impl(JDK_SIGNAL_CLAZZ, String.class)
41+
.build();
42+
43+
static final DynMethods.StaticMethod JDK_SIGNAL_HANDLE_STATIC_METHOD =
44+
new DynMethods.Builder("handle")
45+
.impl(JDK_SIGNAL_CLAZZ, JDK_SIGNAL_CLAZZ, JDK_SIGNAL_HANDLER_CLAZZ)
46+
.buildStatic();
47+
48+
static final DynMethods.StaticMethod JDK_SIGNAL_RAISE_STATIC_METHOD =
49+
new DynMethods.Builder("raise")
50+
.impl(JDK_SIGNAL_CLAZZ, JDK_SIGNAL_CLAZZ)
51+
.buildStatic();
52+
53+
static final DynMethods.UnboundMethod JDK_SIGNAL_HANDLER_HANDLE_UNBOUND_METHOD =
54+
new DynMethods.Builder("handle")
55+
.impl(JDK_SIGNAL_HANDLER_CLAZZ, JDK_SIGNAL_CLAZZ)
56+
.build();
57+
58+
@InterfaceAudience.Private
59+
public static class Signal {
60+
private static final DynMethods.UnboundMethod GET_NUMBER_UNBOUND_METHOD =
61+
new DynMethods.Builder("getNumber").impl(JDK_SIGNAL_CLAZZ).build();
62+
63+
private static final DynMethods.UnboundMethod GET_NAME_UNBOUND_METHOD =
64+
new DynMethods.Builder("getName").impl(JDK_SIGNAL_CLAZZ).build();
65+
66+
private final Object/* sun.misc.Signal */ delegate;
67+
private final DynMethods.BoundMethod getNumberMethod;
68+
private final DynMethods.BoundMethod getNameMethod;
69+
70+
public Signal(String name) {
71+
Preconditions.checkNotNull(name);
72+
this.delegate = JDK_SIGNAL_CTOR.newInstance(name);
73+
this.getNumberMethod = GET_NUMBER_UNBOUND_METHOD.bind(delegate);
74+
this.getNameMethod = GET_NAME_UNBOUND_METHOD.bind(delegate);
75+
}
76+
77+
public Signal(Object delegate) {
78+
Preconditions.checkArgument(JDK_SIGNAL_CLAZZ.isInstance(delegate),
79+
String.format("Expected class is '%s', but actual class is '%s'",
80+
JDK_SIGNAL_CLAZZ.getName(), delegate.getClass().getName()));
81+
this.delegate = delegate;
82+
this.getNumberMethod = GET_NUMBER_UNBOUND_METHOD.bind(delegate);
83+
this.getNameMethod = GET_NAME_UNBOUND_METHOD.bind(delegate);
84+
}
85+
86+
public int getNumber() {
87+
return getNumberMethod.invoke();
88+
}
89+
90+
public String getName() {
91+
return getNameMethod.invoke();
92+
}
93+
94+
@Override
95+
public boolean equals(Object obj) {
96+
if (this == obj) {
97+
return true;
98+
}
99+
if (obj instanceof Signal) {
100+
return delegate.equals(((Signal)obj).delegate);
101+
}
102+
return false;
103+
}
104+
105+
@Override
106+
public int hashCode() {
107+
return delegate.hashCode();
108+
}
109+
110+
@Override
111+
public String toString() {
112+
return delegate.toString();
113+
}
114+
}
115+
116+
@InterfaceAudience.Private
117+
public interface Handler {
118+
void handle(Signal sig);
119+
}
120+
121+
static class JdkSignalHandlerImpl implements Handler {
122+
123+
private final Object/* sun.misc.SignalHandler */ delegate;
124+
private final DynMethods.BoundMethod jdkSignalHandlerHandleMethod;
125+
126+
JdkSignalHandlerImpl(Handler handler) {
127+
this.delegate = Proxy.newProxyInstance(
128+
getClass().getClassLoader(),
129+
new Class<?>[] {JDK_SIGNAL_HANDLER_CLAZZ},
130+
(proxyObj, method, args) -> {
131+
if ("handle".equals(method.getName()) && args.length == 1
132+
&& JDK_SIGNAL_CLAZZ.isInstance(args[0])) {
133+
handler.handle(new Signal(args[0]));
134+
return null;
135+
} else {
136+
Method delegateMethod = handler.getClass().getMethod(
137+
method.getName(), method.getParameterTypes());
138+
return delegateMethod.invoke(handler, args);
139+
}
140+
}
141+
);
142+
this.jdkSignalHandlerHandleMethod = JDK_SIGNAL_HANDLER_HANDLE_UNBOUND_METHOD.bind(delegate);
143+
}
144+
145+
JdkSignalHandlerImpl(Object delegate) {
146+
Preconditions.checkArgument(JDK_SIGNAL_HANDLER_CLAZZ.isInstance(delegate),
147+
String.format("Expected class is '%s', but actual class is '%s'",
148+
JDK_SIGNAL_HANDLER_CLAZZ.getName(), delegate.getClass().getName()));
149+
this.delegate = delegate;
150+
this.jdkSignalHandlerHandleMethod = JDK_SIGNAL_HANDLER_HANDLE_UNBOUND_METHOD.bind(delegate);
151+
}
152+
153+
@Override
154+
public void handle(Signal sig) {
155+
jdkSignalHandlerHandleMethod.invoke(sig.delegate);
156+
}
157+
}
158+
159+
public static Handler handle(Signal sig, Handler handler) {
160+
Object preHandle = JDK_SIGNAL_HANDLE_STATIC_METHOD.invoke(
161+
sig.delegate, new JdkSignalHandlerImpl(handler).delegate);
162+
return new JdkSignalHandlerImpl(preHandle);
163+
}
164+
165+
public static void raise(Signal sig) throws IllegalArgumentException {
166+
JDK_SIGNAL_RAISE_STATIC_METHOD.invoke(sig.delegate);
167+
}
168+
}

0 commit comments

Comments
 (0)