Skip to content

Commit b296bb2

Browse files
authored
Expose HCR event source and future action (#143)
* Expose HCR event source and future action * Fix build errors
1 parent 909ab61 commit b296bb2

File tree

3 files changed

+92
-46
lines changed

3 files changed

+92
-46
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2017 Microsoft Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Microsoft Corporation - initial API and implementation
10+
*******************************************************************************/
11+
12+
package com.microsoft.java.debug.core.adapter;
13+
14+
public class HotCodeReplaceEvent {
15+
16+
public enum EventType {
17+
ERROR(-1),
18+
19+
WARNING(-2),
20+
21+
STARTING(1),
22+
23+
END(2),
24+
25+
BUILD_COMPLETE(3);
26+
27+
private int value;
28+
29+
private EventType(int value) {
30+
this.value = value;
31+
}
32+
33+
public int getValue() {
34+
return this.value;
35+
}
36+
}
37+
38+
private EventType eventType;
39+
40+
private String message;
41+
42+
public HotCodeReplaceEvent(EventType eventType, String message) {
43+
this.eventType = eventType;
44+
this.message = message;
45+
}
46+
47+
public EventType getEventType() {
48+
return eventType;
49+
}
50+
51+
public String getMessage() {
52+
return message;
53+
}
54+
}

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IHotCodeReplaceProvider.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,15 @@
1212
package com.microsoft.java.debug.core.adapter;
1313

1414
import java.util.List;
15+
import java.util.concurrent.CompletableFuture;
1516
import java.util.function.Consumer;
1617

18+
import io.reactivex.Observable;
19+
1720
public interface IHotCodeReplaceProvider extends IProvider {
1821
void onClassRedefined(Consumer<List<String>> consumer);
22+
23+
CompletableFuture<List<String>> redefineClasses();
24+
25+
Observable<HotCodeReplaceEvent> getEventHub();
1926
}

com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java

Lines changed: 31 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.Iterator;
2929
import java.util.List;
3030
import java.util.Map;
31+
import java.util.concurrent.CompletableFuture;
3132
import java.util.function.Consumer;
3233
import java.util.logging.Level;
3334
import java.util.logging.Logger;
@@ -60,10 +61,11 @@
6061
import com.microsoft.java.debug.core.DebugUtility;
6162
import com.microsoft.java.debug.core.IDebugSession;
6263
import com.microsoft.java.debug.core.StackFrameUtility;
64+
import com.microsoft.java.debug.core.adapter.HotCodeReplaceEvent;
6365
import com.microsoft.java.debug.core.adapter.IDebugAdapterContext;
6466
import com.microsoft.java.debug.core.adapter.IHotCodeReplaceProvider;
6567
import com.microsoft.java.debug.core.protocol.Events;
66-
import com.microsoft.java.debug.core.protocol.Events.DebugEvent;
68+
6769
import com.sun.jdi.ArrayType;
6870
import com.sun.jdi.ClassNotLoadedException;
6971
import com.sun.jdi.IncompatibleThreadStateException;
@@ -74,6 +76,9 @@
7476
import com.sun.jdi.VirtualMachine;
7577
import com.sun.jdi.request.StepRequest;
7678

79+
import io.reactivex.Observable;
80+
import io.reactivex.subjects.PublishSubject;
81+
7782
/**
7883
* The hot code replace provider listens for changes to class files and notifies
7984
* the running debug session of the changes.
@@ -92,6 +97,8 @@ public class JavaHotCodeReplaceProvider implements IHotCodeReplaceProvider, IRes
9297

9398
private List<Consumer<List<String>>> consumers = new ArrayList<Consumer<List<String>>>();
9499

100+
private PublishSubject<HotCodeReplaceEvent> eventSubject = PublishSubject.<HotCodeReplaceEvent>create();
101+
95102
/**
96103
* Visitor for resource deltas.
97104
*/
@@ -249,45 +256,6 @@ private IResource getSourceFile(IJavaProject project, String qualifiedName, Stri
249256
}
250257
}
251258

252-
/**
253-
* Hot code replace event type.
254-
*/
255-
enum EventType {
256-
ERROR(-1),
257-
258-
WARNING(-2),
259-
260-
STARTING(1),
261-
262-
END(2);
263-
264-
private int value;
265-
266-
private EventType(int value) {
267-
this.value = value;
268-
}
269-
270-
public int getValue() {
271-
return this.value;
272-
}
273-
}
274-
275-
class HotCodeReplaceEvent extends DebugEvent {
276-
277-
public EventType eventType;
278-
279-
public String message;
280-
281-
/**
282-
* Constructor.
283-
*/
284-
public HotCodeReplaceEvent(EventType eventType, String message) {
285-
super("hotCodeReplace");
286-
this.eventType = eventType;
287-
this.message = message;
288-
}
289-
}
290-
291259
@Override
292260
public void initialize(IDebugAdapterContext context, Map<String, Object> options) {
293261
if (DebugSettings.getCurrent().enableHotCodeReplace) {
@@ -319,6 +287,25 @@ public void onClassRedefined(Consumer<List<String>> consumer) {
319287
this.consumers.add(consumer);
320288
}
321289

290+
@Override
291+
public CompletableFuture<List<String>> redefineClasses() {
292+
return CompletableFuture.supplyAsync(() -> {
293+
List<String> classNames = new ArrayList();
294+
295+
// TODO: fill the class name collection by calling doHotCodeReplace
296+
return classNames;
297+
});
298+
}
299+
300+
@Override
301+
public Observable<HotCodeReplaceEvent> getEventHub() {
302+
return eventSubject;
303+
}
304+
305+
private void publishEvent(HotCodeReplaceEvent.EventType type, String message) {
306+
eventSubject.onNext(new HotCodeReplaceEvent(type, message));
307+
}
308+
322309
private void doHotCodeReplace(List<IResource> resourcesToReplace, List<String> qualifiedNamesToReplace) {
323310
if (context == null || currentDebugSession == null) {
324311
return;
@@ -340,8 +327,7 @@ private void doHotCodeReplace(List<IResource> resourcesToReplace, List<String> q
340327
return;
341328
}
342329

343-
context.getProtocolServer()
344-
.sendEvent(new HotCodeReplaceEvent(EventType.STARTING, "Start hot code replacement procedure..."));
330+
publishEvent(HotCodeReplaceEvent.EventType.STARTING, "Start hot code replacement procedure...");
345331

346332
try {
347333
List<ThreadReference> poppedThreads = new ArrayList<>();
@@ -361,8 +347,7 @@ private void doHotCodeReplace(List<IResource> resourcesToReplace, List<String> q
361347
}
362348

363349
if (containsObsoleteMethods()) {
364-
context.getProtocolServer()
365-
.sendEvent(new HotCodeReplaceEvent(EventType.ERROR, "JVM contains obsolete methods"));
350+
publishEvent(HotCodeReplaceEvent.EventType.ERROR, "JVM contains obsolete methods");
366351
}
367352

368353
if (currentDebugSession.getVM().canPopFrames() && framesPopped) {
@@ -373,7 +358,7 @@ private void doHotCodeReplace(List<IResource> resourcesToReplace, List<String> q
373358
} catch (DebugException e) {
374359
logger.log(Level.SEVERE, "Failed to complete hot code replace: " + e.getMessage(), e);
375360
} finally {
376-
context.getProtocolServer().sendEvent(new HotCodeReplaceEvent(EventType.END, "Completed hot code replace"));
361+
publishEvent(HotCodeReplaceEvent.EventType.END, "Completed hot code replace");
377362
}
378363

379364
threadFrameMap.clear();
@@ -627,7 +612,7 @@ private void redefineTypesJDK(List<IResource> resources, List<String> qualifiedN
627612
currentDebugSession.getVM().redefineClasses(typesToBytes);
628613
} catch (UnsupportedOperationException | NoClassDefFoundError | VerifyError | ClassFormatError
629614
| ClassCircularityError e) {
630-
context.getProtocolServer().sendEvent(new HotCodeReplaceEvent(EventType.ERROR, e.getMessage()));
615+
publishEvent(HotCodeReplaceEvent.EventType.ERROR, e.getMessage());
631616
throw new DebugException("Failed to redefine classes: " + e.getMessage());
632617
}
633618
}

0 commit comments

Comments
 (0)