From 1847974c0b1ff90da18474e92f9346b865e61387 Mon Sep 17 00:00:00 2001 From: kaifox Date: Fri, 7 Feb 2020 18:41:47 +0100 Subject: [PATCH 1/4] first attempts to spawn missions works now. Renamed internal mission to JdiMission to avoid misunderstandings. --- README.md | 2 +- build.gradle | 8 +- commons/build.gradle | 2 +- .../domain/{Mission.java => JdiMission.java} | 4 +- .../molr/commons/domain/impl/MissionImpl.java | 10 +- .../exception/MissionExecutionException.java | 4 +- .../MissionMaterializationException.java | 4 +- .../commons/mission/MissionMaterializer.java | 12 +- .../commons/mission/MissionsDiscoverer.java | 10 +- .../impl/AnnotatedMissionMaterializer.java | 6 +- .../impl/ClasspathMissionDiscoverer.java | 6 +- .../molr/commons/mole/GenericMoleRunner.java | 3 +- .../java/cern/molr/commons/mole/Mole.java | 10 +- .../cern/molr/commons/mole/RunWithMole.java | 4 +- .../impl/InMemoryMissionsRegistry.java | 6 +- .../main/java/cern/molr/jvm/MoleSpawner.java | 8 +- .../jvm/impl/SimpleMoleRunnerSpawner.java | 14 +-- .../spawner}/json/MissionTypeAdapter.java | 24 ++-- .../AnnotatedMissionMaterializerTest.java | 6 +- .../impl/ClasspathMissionDiscovererTest.java | 24 ++-- .../impl/InMemoryMissionsRegistryTest.java | 18 +-- .../jvm/impl/SimpleMoleRunnerSpawnerTest.java | 15 ++- .../spawner}/json/MissionTypeAdapterTest.java | 10 +- gradle.properties | 1 + .../mole/jdebug/spawner}/gui/DebugPane.java | 12 +- .../jdebug/spawner}/gui/SessionsListPane.java | 8 +- .../mole/jdebug/spawner}/gui/SwingUtils.java | 2 +- inspector/build.gradle | 6 +- .../io/molr/mole/jdebug/domain/Missions.java | 57 +++++++++ .../jdebug/spawner/ConnectorInspector.java | 32 +++++ .../jdebug/spawner}/DebugMoleSpawner.java | 39 +++--- .../jdebug/spawner/JdiMissionSpawner.java | 24 ++++ .../spawner}/controller/JdiController.java | 2 +- .../controller/JdiControllerImpl.java | 21 ++-- .../spawner}/controller/JdiEntryRegistry.java | 4 +- .../spawner}/controller/JdiEventHandler.java | 4 +- .../controller/JdiInstanceBuilder.java | 24 ++-- .../LocalDelegatingStatefulJdiController.java | 118 ++++++++++++++++++ .../spawner}/controller/SourceCodeLoader.java | 2 +- .../controller/StatefulJdiController.java | 10 +- .../controller/StatefulJdiControllerImpl.java | 10 +- .../controller/SteppingJdiEventHandler.java | 8 +- .../spawner}/domain/InstantiationRequest.java | 12 +- .../mole/jdebug/spawner}/domain/Session.java | 12 +- .../jdebug/spawner}/domain/SourceFetcher.java | 2 +- .../domain/impl/InstantiationRequestImpl.java | 20 +-- .../spawner}/domain/impl/SessionImpl.java | 18 +-- .../spawner}/domain/impl/SessionRegistry.java | 8 +- .../jdebug/spawner}/entry/EntryListener.java | 2 +- .../jdebug/spawner}/entry/EntryState.java | 2 +- .../spawner}/entry/EntryStateBuilder.java | 4 +- .../spawner}/entry/impl/EntryStateImpl.java | 4 +- .../jdebug/spawner/examples/HelloWorld.java | 41 ++++++ .../spawner/examples/HelloWorldExample.java | 27 ++++ .../jdi/ClassInstantiationListener.java | 2 +- .../jdebug/spawner}/jdi/LocationRange.java | 2 +- .../mole/jdebug/spawner}/jdi/ThreadState.java | 7 +- .../mole/jdebug/spawner}/package-info.java | 4 +- .../spawner}/remote/EntryListenerMethod.java | 4 +- .../spawner}/remote/EntryListenerReader.java | 8 +- .../spawner}/remote/EntryListenerWriter.java | 6 +- .../spawner}/remote/JdiControllerCommand.java | 4 +- .../spawner}/remote/JdiControllerReader.java | 4 +- .../spawner}/remote/JdiControllerWriter.java | 4 +- .../jdebug/spawner}/remote/RemoteReader.java | 2 +- .../jdebug/spawner}/remote/SystemMain.java | 46 +++---- .../jdebug/spawner/DebugMoleSpawnerTest.java | 35 ++++++ .../jdebug/spawner/HelloWorldExampleTest.java | 16 +++ .../JdiControllerImplIntegrationTest.java | 2 +- .../jdebug/spawner/PrimitiveTestingMain.java | 10 ++ .../mole/jdebug/spawner}/SystemMainTest.java | 26 ++-- .../mole/jdebug/spawner}/TestInspectable.java | 2 +- .../jdi/ClassInstantiationListenerTest.java | 8 +- .../spawner}/jdi/LocationRangeTest.java | 2 +- .../jdebug/spawner}/jdi/ThreadStateTest.java | 2 +- .../remote/EntryListenerReaderWriterTest.java | 8 +- .../remote/JdiControllerReaderWriterTest.java | 4 +- .../spawner}/remote/RemoteReaderTest.java | 2 +- mole/build.gradle | 5 +- 79 files changed, 670 insertions(+), 291 deletions(-) rename commons/src/main/java/cern/molr/commons/domain/{Mission.java => JdiMission.java} (92%) rename commons/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/json/MissionTypeAdapter.java (59%) rename commons/src/test/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/json/MissionTypeAdapterTest.java (88%) create mode 100644 gradle.properties rename gui/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/gui/DebugPane.java (95%) rename gui/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/gui/SessionsListPane.java (94%) rename gui/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/gui/SwingUtils.java (97%) create mode 100644 inspector/src/main/java/io/molr/mole/jdebug/domain/Missions.java create mode 100644 inspector/src/main/java/io/molr/mole/jdebug/spawner/ConnectorInspector.java rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/DebugMoleSpawner.java (69%) create mode 100644 inspector/src/main/java/io/molr/mole/jdebug/spawner/JdiMissionSpawner.java rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/controller/JdiController.java (94%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/controller/JdiControllerImpl.java (87%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/controller/JdiEntryRegistry.java (92%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/controller/JdiEventHandler.java (95%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/controller/JdiInstanceBuilder.java (81%) create mode 100644 inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/LocalDelegatingStatefulJdiController.java rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/controller/SourceCodeLoader.java (96%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/controller/StatefulJdiController.java (69%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/controller/StatefulJdiControllerImpl.java (91%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/controller/SteppingJdiEventHandler.java (95%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/domain/InstantiationRequest.java (69%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/domain/Session.java (63%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/domain/SourceFetcher.java (75%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/domain/impl/InstantiationRequestImpl.java (65%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/domain/impl/SessionImpl.java (52%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/domain/impl/SessionRegistry.java (86%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/entry/EntryListener.java (96%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/entry/EntryState.java (96%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/entry/EntryStateBuilder.java (89%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/entry/impl/EntryStateImpl.java (95%) create mode 100644 inspector/src/main/java/io/molr/mole/jdebug/spawner/examples/HelloWorld.java create mode 100644 inspector/src/main/java/io/molr/mole/jdebug/spawner/examples/HelloWorldExample.java rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/jdi/ClassInstantiationListener.java (98%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/jdi/LocationRange.java (98%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/jdi/ThreadState.java (93%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/package-info.java (87%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/remote/EntryListenerMethod.java (61%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/remote/EntryListenerReader.java (95%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/remote/EntryListenerWriter.java (88%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/remote/JdiControllerCommand.java (59%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/remote/JdiControllerReader.java (96%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/remote/JdiControllerWriter.java (90%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/remote/RemoteReader.java (98%) rename inspector/src/main/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/remote/SystemMain.java (66%) create mode 100644 inspector/src/test/java/io/molr/mole/jdebug/spawner/DebugMoleSpawnerTest.java create mode 100644 inspector/src/test/java/io/molr/mole/jdebug/spawner/HelloWorldExampleTest.java rename inspector/src/test/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/JdiControllerImplIntegrationTest.java (96%) create mode 100644 inspector/src/test/java/io/molr/mole/jdebug/spawner/PrimitiveTestingMain.java rename inspector/src/test/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/SystemMainTest.java (61%) rename inspector/src/test/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/TestInspectable.java (94%) rename inspector/src/test/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/jdi/ClassInstantiationListenerTest.java (89%) rename inspector/src/test/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/jdi/LocationRangeTest.java (98%) rename inspector/src/test/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/jdi/ThreadStateTest.java (98%) rename inspector/src/test/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/remote/EntryListenerReaderWriterTest.java (88%) rename inspector/src/test/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/remote/JdiControllerReaderWriterTest.java (92%) rename inspector/src/test/java/{cern/molr/inspector => io/molr/mole/jdebug/spawner}/remote/RemoteReaderTest.java (96%) diff --git a/README.md b/README.md index b888516..1797bc7 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Ongoing work! This project is just in the process of being rewoked... -It is an attempt to use the java debugging api in order to expose missions which are pure java code through the molr API. Quite some way to go still ;-) +It is an attempt to use the java debugging api in order to expose jdiMissions which are pure java code through the molr API. Quite some way to go still ;-) Contributors: diff --git a/build.gradle b/build.gradle index 8b9892d..b081f2e 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ allprojects { apply plugin: "idea" apply plugin: "eclipse" apply plugin: "java" - apply plugin: 'jacoco' + //apply plugin: 'jacoco' sourceCompatibility = 1.8 targetCompatibility = 1.8 @@ -15,7 +15,7 @@ allprojects { dependencies { compile 'org.slf4j:slf4j-api:1.7.16' } - +/* jacoco { toolVersion = '0.8.4' } @@ -28,7 +28,7 @@ allprojects { csv.enabled = false } } - +*/ tasks.withType(JavaCompile) { options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" } @@ -49,7 +49,7 @@ project(":gui") { project(":inspector") { dependencies { compile project(":mole") - compile project(":jdiscript") + // compile project(":jdiscript") } } diff --git a/commons/build.gradle b/commons/build.gradle index 4e77b45..c877aa4 100644 --- a/commons/build.gradle +++ b/commons/build.gradle @@ -12,7 +12,7 @@ dependencies { implementation 'org.javassist:javassist:3.26.0-GA' compile group: "com.google.code.gson", name: "gson", version: "2.+" testCompile group: 'org.mockito', name: 'mockito-core', version: '3.+' - //testCompile group: 'org.mockito', name: 'mockito-core', version: '1.10.19' + // testCompile group: 'org.mockito', name: 'mockito-core', version: '1.10.19' testCompile group: 'junit', name: 'junit', version: '4.11' testCompile 'junit-addons:junit-addons:1.4' } diff --git a/commons/src/main/java/cern/molr/commons/domain/Mission.java b/commons/src/main/java/cern/molr/commons/domain/JdiMission.java similarity index 92% rename from commons/src/main/java/cern/molr/commons/domain/Mission.java rename to commons/src/main/java/cern/molr/commons/domain/JdiMission.java index 2201bff..9088f90 100644 --- a/commons/src/main/java/cern/molr/commons/domain/Mission.java +++ b/commons/src/main/java/cern/molr/commons/domain/JdiMission.java @@ -14,11 +14,11 @@ * @author mgalilee * @author tiagomr */ -public interface Mission { +public interface JdiMission { /** * @return A {@link String} with the fully qualified domain name to the type of {@link cern.molr.commons.mole.Mole} - * which will run the tasks of this {@link Mission}. + * which will run the tasks of this {@link JdiMission}. */ String getMoleClassName(); diff --git a/commons/src/main/java/cern/molr/commons/domain/impl/MissionImpl.java b/commons/src/main/java/cern/molr/commons/domain/impl/MissionImpl.java index a4c0361..de8de71 100644 --- a/commons/src/main/java/cern/molr/commons/domain/impl/MissionImpl.java +++ b/commons/src/main/java/cern/molr/commons/domain/impl/MissionImpl.java @@ -5,26 +5,26 @@ */ package cern.molr.commons.domain.impl; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import java.util.ArrayList; import java.util.List; /** - * Simple implementation of {@link Mission} + * Simple implementation of {@link JdiMission} * * @author tiagomr * @author mgalilee */ -public class MissionImpl implements Mission { +public class MissionImpl implements JdiMission { /** - * Name of the mole that can execute the {@link Mission} + * Name of the mole that can execute the {@link JdiMission} */ private String moleClassName; /** - * Class used by the exposed {@link Mission} + * Class used by the exposed {@link JdiMission} */ private String missionContentClassName; diff --git a/commons/src/main/java/cern/molr/commons/exception/MissionExecutionException.java b/commons/src/main/java/cern/molr/commons/exception/MissionExecutionException.java index 2549bb8..aaf6034 100644 --- a/commons/src/main/java/cern/molr/commons/exception/MissionExecutionException.java +++ b/commons/src/main/java/cern/molr/commons/exception/MissionExecutionException.java @@ -6,9 +6,11 @@ package cern.molr.commons.exception; +import cern.molr.commons.domain.JdiMission; + /** * Exception to be used whenever its not possible to - * {@link cern.molr.commons.mole.Mole#run(String, Object...)} a {@link cern.molr.commons.domain.Mission} + * {@link cern.molr.commons.mole.Mole#run(String, Object...)} a {@link JdiMission} * * @author timartin */ diff --git a/commons/src/main/java/cern/molr/commons/exception/MissionMaterializationException.java b/commons/src/main/java/cern/molr/commons/exception/MissionMaterializationException.java index 182a68d..9f3adee 100644 --- a/commons/src/main/java/cern/molr/commons/exception/MissionMaterializationException.java +++ b/commons/src/main/java/cern/molr/commons/exception/MissionMaterializationException.java @@ -6,9 +6,11 @@ package cern.molr.commons.exception; +import cern.molr.commons.domain.JdiMission; + /** * Exception to be used whenever its not possible to - * {@link cern.molr.commons.mission.MissionMaterializer#materialize(Class)} a {@link cern.molr.commons.domain.Mission} + * {@link cern.molr.commons.mission.MissionMaterializer#materialize(Class)} a {@link JdiMission} * * @author timartin */ diff --git a/commons/src/main/java/cern/molr/commons/mission/MissionMaterializer.java b/commons/src/main/java/cern/molr/commons/mission/MissionMaterializer.java index 4568a28..25837c7 100644 --- a/commons/src/main/java/cern/molr/commons/mission/MissionMaterializer.java +++ b/commons/src/main/java/cern/molr/commons/mission/MissionMaterializer.java @@ -6,11 +6,11 @@ package cern.molr.commons.mission; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import cern.molr.commons.exception.MissionMaterializationException; /** - * Interface that provides a way to instantiate {@link Mission}s + * Interface that provides a way to instantiate {@link JdiMission}s * * @author tiagomr */ @@ -19,9 +19,9 @@ public interface MissionMaterializer { /** * Tries to instantiate a mission from a given {@link Class} * - * @param classType {@link Class} from which the {@link Mission} will be generated - * @return A {@link Mission} - * @see Mission + * @param classType {@link Class} from which the {@link JdiMission} will be generated + * @return A {@link JdiMission} + * @see JdiMission */ - Mission materialize(Class classType) throws MissionMaterializationException; + JdiMission materialize(Class classType) throws MissionMaterializationException; } diff --git a/commons/src/main/java/cern/molr/commons/mission/MissionsDiscoverer.java b/commons/src/main/java/cern/molr/commons/mission/MissionsDiscoverer.java index 22638ab..14f38af 100644 --- a/commons/src/main/java/cern/molr/commons/mission/MissionsDiscoverer.java +++ b/commons/src/main/java/cern/molr/commons/mission/MissionsDiscoverer.java @@ -6,12 +6,12 @@ package cern.molr.commons.mission; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import java.util.Set; /** - * Interface that provides a way to discover {@link Mission}s + * Interface that provides a way to discover {@link JdiMission}s * * @author timartin * @author mgalilee @@ -19,9 +19,9 @@ public interface MissionsDiscoverer { /** - * Searches for available {@link Mission}s + * Searches for available {@link JdiMission}s * - * @return A {@link Set} of {@link Mission}s + * @return A {@link Set} of {@link JdiMission}s */ - Set availableMissions(); + Set availableMissions(); } diff --git a/commons/src/main/java/cern/molr/commons/mission/impl/AnnotatedMissionMaterializer.java b/commons/src/main/java/cern/molr/commons/mission/impl/AnnotatedMissionMaterializer.java index 7b22059..5f19b7e 100644 --- a/commons/src/main/java/cern/molr/commons/mission/impl/AnnotatedMissionMaterializer.java +++ b/commons/src/main/java/cern/molr/commons/mission/impl/AnnotatedMissionMaterializer.java @@ -6,7 +6,7 @@ package cern.molr.commons.mission.impl; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import cern.molr.commons.domain.impl.MissionImpl; import cern.molr.commons.exception.MissionMaterializationException; import cern.molr.commons.mission.MissionMaterializer; @@ -22,7 +22,7 @@ import java.util.stream.Collectors; /** - * Implementation of {@link MissionMaterializer} that can instantiate {@link Mission}s from {@link Class}es + * Implementation of {@link MissionMaterializer} that can instantiate {@link JdiMission}s from {@link Class}es * annotated with {@link RunWithMole} * * @author tiagomr @@ -32,7 +32,7 @@ public class AnnotatedMissionMaterializer implements MissionMaterializer { private static final Logger LOGGER = LoggerFactory.getLogger(AnnotatedMissionMaterializer.class); @Override - public Mission materialize(Class classType) throws MissionMaterializationException { + public JdiMission materialize(Class classType) throws MissionMaterializationException { if (null == classType) { throw new MissionMaterializationException(new IllegalArgumentException("Class type cannot be null")); } diff --git a/commons/src/main/java/cern/molr/commons/mission/impl/ClasspathMissionDiscoverer.java b/commons/src/main/java/cern/molr/commons/mission/impl/ClasspathMissionDiscoverer.java index a04865b..15da79e 100644 --- a/commons/src/main/java/cern/molr/commons/mission/impl/ClasspathMissionDiscoverer.java +++ b/commons/src/main/java/cern/molr/commons/mission/impl/ClasspathMissionDiscoverer.java @@ -5,7 +5,7 @@ */ package cern.molr.commons.mission.impl; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import cern.molr.commons.mission.MissionMaterializer; import cern.molr.commons.mission.MissionsDiscoverer; import cern.molr.commons.mole.RunWithMole; @@ -23,7 +23,7 @@ /** * Implementation of {@link MissionsDiscoverer} which makes use of the {@link RunWithMole} annotation to discover - * {@link Mission}s using classpath scans + * {@link JdiMission}s using classpath scans * * @author jepeders * @author tiagomr @@ -40,7 +40,7 @@ public ClasspathMissionDiscoverer(MissionMaterializer materializer) { } @Override - public Set availableMissions() { + public Set availableMissions() { final Set> missionClasses = new HashSet<>(); final Discoverer discoverer = new ClasspathDiscoverer(); discoverer.addAnnotationListener( diff --git a/commons/src/main/java/cern/molr/commons/mole/GenericMoleRunner.java b/commons/src/main/java/cern/molr/commons/mole/GenericMoleRunner.java index ebbb76b..62e0ecb 100644 --- a/commons/src/main/java/cern/molr/commons/mole/GenericMoleRunner.java +++ b/commons/src/main/java/cern/molr/commons/mole/GenericMoleRunner.java @@ -6,11 +6,12 @@ package cern.molr.commons.mole; +import cern.molr.commons.domain.JdiMission; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Main entry point for the JVM's to execute {@link cern.molr.commons.domain.Mission}s + * Main entry point for the JVM's to execute {@link JdiMission}s * * @author jepeders * @author tiagomr diff --git a/commons/src/main/java/cern/molr/commons/mole/Mole.java b/commons/src/main/java/cern/molr/commons/mole/Mole.java index aa16a82..32a99eb 100644 --- a/commons/src/main/java/cern/molr/commons/mole/Mole.java +++ b/commons/src/main/java/cern/molr/commons/mole/Mole.java @@ -6,7 +6,7 @@ package cern.molr.commons.mole; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import cern.molr.commons.exception.MissionExecutionException; import java.lang.reflect.Method; @@ -14,7 +14,7 @@ /** * Interface that allows for the dynamic creation of {@link Mole}s. {@link Mole}s are responsible for the discovery and - * execution of {@link Mission}s + * execution of {@link JdiMission}s * * @author tiagomr */ @@ -29,10 +29,10 @@ public interface Mole { List discover(Class clazz); /** - * Executes a {@link Mission} + * Executes a {@link JdiMission} * - * @param missionContentClassName A {@link String} with the fully qualified domain name of the {@link Mission}s content class - * @param args An array of {@link Object}s to be passed as arguments to the {@link Mission} + * @param missionContentClassName A {@link String} with the fully qualified domain name of the {@link JdiMission}s content class + * @param args An array of {@link Object}s to be passed as arguments to the {@link JdiMission} * @throws Exception Allows for any exception to be returned by the Mission execution behaviour, this is specific to * the execution implementation */ diff --git a/commons/src/main/java/cern/molr/commons/mole/RunWithMole.java b/commons/src/main/java/cern/molr/commons/mole/RunWithMole.java index 58d1e25..a0c18f6 100644 --- a/commons/src/main/java/cern/molr/commons/mole/RunWithMole.java +++ b/commons/src/main/java/cern/molr/commons/mole/RunWithMole.java @@ -5,7 +5,7 @@ */ package cern.molr.commons.mole; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -13,7 +13,7 @@ import java.lang.annotation.Target; /** - * Provides information about which classes shall be exposed as {@link Mission}s and which {@link Mole} implementation must be + * Provides information about which classes shall be exposed as {@link JdiMission}s and which {@link Mole} implementation must be * used to execute the discovery and execution methods. * * @author tiagomr diff --git a/commons/src/main/java/cern/molr/commons/registry/impl/InMemoryMissionsRegistry.java b/commons/src/main/java/cern/molr/commons/registry/impl/InMemoryMissionsRegistry.java index fc02d16..5d60386 100644 --- a/commons/src/main/java/cern/molr/commons/registry/impl/InMemoryMissionsRegistry.java +++ b/commons/src/main/java/cern/molr/commons/registry/impl/InMemoryMissionsRegistry.java @@ -6,16 +6,16 @@ package cern.molr.commons.registry.impl; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import cern.molr.commons.mission.MissionsDiscoverer; /** - * In memory {@link Mission} registry that searches for {@link Mission}s on the construction phase using a + * In memory {@link JdiMission} registry that searches for {@link JdiMission}s on the construction phase using a * {@link MissionsDiscoverer}. * * @see ObservableInMemoryEntriesRegistry */ -public class InMemoryMissionsRegistry extends ObservableInMemoryEntriesRegistry { +public class InMemoryMissionsRegistry extends ObservableInMemoryEntriesRegistry { public InMemoryMissionsRegistry() { } diff --git a/commons/src/main/java/cern/molr/jvm/MoleSpawner.java b/commons/src/main/java/cern/molr/jvm/MoleSpawner.java index 2ed416a..a11e470 100644 --- a/commons/src/main/java/cern/molr/jvm/MoleSpawner.java +++ b/commons/src/main/java/cern/molr/jvm/MoleSpawner.java @@ -6,7 +6,7 @@ package cern.molr.jvm; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; /** * Interface that is responsible for spawning JVMs executing cern.jarrace.mole.AgentRunner @@ -17,12 +17,12 @@ public interface MoleSpawner { /** * Spawns a mole in a new JVM with the same classpath as the calling JVM * - * @param mission + * @param jdiMission * @param args * @return * @throws Exception */ - T spawnMoleRunner(Mission mission, String... args) throws Exception; + T spawnMoleRunner(JdiMission jdiMission, String... args) throws Exception; /** * Spawns a mole in a new JVM @@ -33,5 +33,5 @@ public interface MoleSpawner { * @return * @throws Exception */ - T spawnMoleRunner(Mission service, String classpath, String... args) throws Exception; + T spawnMoleRunner(JdiMission service, String classpath, String... args) throws Exception; } diff --git a/commons/src/main/java/cern/molr/jvm/impl/SimpleMoleRunnerSpawner.java b/commons/src/main/java/cern/molr/jvm/impl/SimpleMoleRunnerSpawner.java index 7a8c0d2..bd531f5 100644 --- a/commons/src/main/java/cern/molr/jvm/impl/SimpleMoleRunnerSpawner.java +++ b/commons/src/main/java/cern/molr/jvm/impl/SimpleMoleRunnerSpawner.java @@ -6,7 +6,7 @@ package cern.molr.jvm.impl; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import cern.molr.commons.mole.GenericMoleRunner; import cern.molr.jvm.JvmSpawnHelper; import cern.molr.jvm.MoleSpawner; @@ -31,13 +31,13 @@ public class SimpleMoleRunnerSpawner implements MoleSpawner { private static final String CURRENT_CLASSPATH_VALUE = System.getProperty("java.class.path"); @Override - public Void spawnMoleRunner(Mission mission, String... args) throws IOException { - return spawnMoleRunner(mission, CURRENT_CLASSPATH_VALUE, args); + public Void spawnMoleRunner(JdiMission jdiMission, String... args) throws IOException { + return spawnMoleRunner(jdiMission, CURRENT_CLASSPATH_VALUE, args); } @Override - public Void spawnMoleRunner(Mission mission, String classpath, String... args) throws IOException { - if (null == mission) { + public Void spawnMoleRunner(JdiMission jdiMission, String classpath, String... args) throws IOException { + if (null == jdiMission) { throw new IllegalArgumentException("The mission must not be null"); } if(null == classpath) { @@ -53,8 +53,8 @@ public Void spawnMoleRunner(Mission mission, String classpath, String... args) t if(args != null) { argsList.addAll(Arrays.asList(args)); } - argsList.add(mission.getMoleClassName()); - argsList.add(mission.getMissionContentClassName()); + argsList.add(jdiMission.getMoleClassName()); + argsList.add(jdiMission.getMissionContentClassName()); ProcessBuilder processBuilder = JvmSpawnHelper.getProcessBuilder( JvmSpawnHelper.appendToolsJarToClasspath(classpath), diff --git a/commons/src/main/java/cern/molr/inspector/json/MissionTypeAdapter.java b/commons/src/main/java/io/molr/mole/jdebug/spawner/json/MissionTypeAdapter.java similarity index 59% rename from commons/src/main/java/cern/molr/inspector/json/MissionTypeAdapter.java rename to commons/src/main/java/io/molr/mole/jdebug/spawner/json/MissionTypeAdapter.java index 3c26c91..4adc9b8 100644 --- a/commons/src/main/java/cern/molr/inspector/json/MissionTypeAdapter.java +++ b/commons/src/main/java/io/molr/mole/jdebug/spawner/json/MissionTypeAdapter.java @@ -4,9 +4,9 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.json; +package io.molr.mole.jdebug.spawner.json; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import cern.molr.commons.domain.impl.MissionImpl; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; @@ -18,29 +18,29 @@ import java.util.stream.Collectors; /** - * A GSON serialiser and de-serialiser for {@link Mission} objects. + * A GSON serialiser and de-serialiser for {@link JdiMission} objects. */ -public class MissionTypeAdapter extends TypeAdapter { +public class MissionTypeAdapter extends TypeAdapter { private static final String LIST_SEPARATOR = ","; @Override - public void write(JsonWriter out, Mission mission) throws IOException { - Objects.requireNonNull(mission.getMoleClassName(), "Agent name cannot be null"); - Objects.requireNonNull(mission.getMissionContentClassName(), "Class name cannot be null"); - Objects.requireNonNull(mission.getTasksNames(), "Entry points list cannot be null"); + public void write(JsonWriter out, JdiMission jdiMission) throws IOException { + Objects.requireNonNull(jdiMission.getMoleClassName(), "Agent name cannot be null"); + Objects.requireNonNull(jdiMission.getMissionContentClassName(), "Class name cannot be null"); + Objects.requireNonNull(jdiMission.getTasksNames(), "Entry points list cannot be null"); out.beginObject() .name("agentName") - .value(mission.getMoleClassName()) + .value(jdiMission.getMoleClassName()) .name("className") - .value(mission.getMissionContentClassName()) + .value(jdiMission.getMissionContentClassName()) .name("entryPoints") - .value(mission.getTasksNames().stream().collect(Collectors.joining(LIST_SEPARATOR))) + .value(jdiMission.getTasksNames().stream().collect(Collectors.joining(LIST_SEPARATOR))) .endObject(); } @Override - public Mission read(JsonReader in) throws IOException { + public JdiMission read(JsonReader in) throws IOException { in.beginObject(); in.nextName(); final String agentName = in.nextString(); diff --git a/commons/src/test/java/cern/molr/commons/mission/impl/AnnotatedMissionMaterializerTest.java b/commons/src/test/java/cern/molr/commons/mission/impl/AnnotatedMissionMaterializerTest.java index 847735e..9d18033 100644 --- a/commons/src/test/java/cern/molr/commons/mission/impl/AnnotatedMissionMaterializerTest.java +++ b/commons/src/test/java/cern/molr/commons/mission/impl/AnnotatedMissionMaterializerTest.java @@ -7,7 +7,7 @@ package cern.molr.commons.mission.impl; import cern.molr.TestDefinitions; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import cern.molr.commons.exception.MissionMaterializationException; import org.junit.Rule; import org.junit.Test; @@ -62,8 +62,8 @@ public void testMaterializeWithMoleWithNoDefaultConstructor() { @Test public void testMaterialize() { - Mission materializedMission = annotatedMissionMaterializer.materialize(TestDefinitions.TestMission3.class); - List actualMethodNames = materializedMission.getTasksNames(); + JdiMission materializedJdiMission = annotatedMissionMaterializer.materialize(TestDefinitions.TestMission3.class); + List actualMethodNames = materializedJdiMission.getTasksNames(); List expectedMethodNames = TestDefinitions.METHODS_LIST.stream() .map(method -> method.getName()) .collect(Collectors.toList()); diff --git a/commons/src/test/java/cern/molr/commons/mission/impl/ClasspathMissionDiscovererTest.java b/commons/src/test/java/cern/molr/commons/mission/impl/ClasspathMissionDiscovererTest.java index ce05186..bd1202e 100644 --- a/commons/src/test/java/cern/molr/commons/mission/impl/ClasspathMissionDiscovererTest.java +++ b/commons/src/test/java/cern/molr/commons/mission/impl/ClasspathMissionDiscovererTest.java @@ -7,7 +7,7 @@ package cern.molr.commons.mission.impl; import cern.molr.TestDefinitions; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import cern.molr.commons.mission.MissionMaterializer; import org.junit.Before; import org.junit.Test; @@ -33,29 +33,29 @@ public class ClasspathMissionDiscovererTest { @Mock - private Mission mission1; + private JdiMission jdiMission1; @Mock - private Mission mission2; + private JdiMission jdiMission2; @Mock - private Mission mission3; + private JdiMission jdiMission3; @Mock private MissionMaterializer missionMaterializer; - private List allMission; + private List allJdiMission; private ClasspathMissionDiscoverer classpathMissionDiscoverer; @Before public void setUp() { - when(missionMaterializer.materialize(TestDefinitions.TestMission1.class)).thenReturn(mission1); - when(missionMaterializer.materialize(TestDefinitions.TestMission2.class)).thenReturn(mission2); - when(missionMaterializer.materialize(TestDefinitions.TestMission3.class)).thenReturn(mission3); - allMission = new ArrayList<>(Arrays.asList(mission1, mission2, mission3)); + when(missionMaterializer.materialize(TestDefinitions.TestMission1.class)).thenReturn(jdiMission1); + when(missionMaterializer.materialize(TestDefinitions.TestMission2.class)).thenReturn(jdiMission2); + when(missionMaterializer.materialize(TestDefinitions.TestMission3.class)).thenReturn(jdiMission3); + allJdiMission = new ArrayList<>(Arrays.asList(jdiMission1, jdiMission2, jdiMission3)); classpathMissionDiscoverer = new ClasspathMissionDiscoverer(missionMaterializer); } @Test public void testAvailableMissions() { - Set missions = classpathMissionDiscoverer.availableMissions(); - assertEquals(TestDefinitions.NUMBER_OF_TEST_MISSION_DEFINITIONS, missions.size()); - assertTrue(allMission.stream().allMatch(missions::contains)); + Set jdiMissions = classpathMissionDiscoverer.availableMissions(); + assertEquals(TestDefinitions.NUMBER_OF_TEST_MISSION_DEFINITIONS, jdiMissions.size()); + assertTrue(allJdiMission.stream().allMatch(jdiMissions::contains)); } } \ No newline at end of file diff --git a/commons/src/test/java/cern/molr/commons/registry/impl/InMemoryMissionsRegistryTest.java b/commons/src/test/java/cern/molr/commons/registry/impl/InMemoryMissionsRegistryTest.java index 92d96e6..1637b9e 100644 --- a/commons/src/test/java/cern/molr/commons/registry/impl/InMemoryMissionsRegistryTest.java +++ b/commons/src/test/java/cern/molr/commons/registry/impl/InMemoryMissionsRegistryTest.java @@ -6,7 +6,7 @@ package cern.molr.commons.registry.impl; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import cern.molr.commons.mission.MissionsDiscoverer; import junitx.util.PrivateAccessor; import org.junit.Before; @@ -33,26 +33,26 @@ public class InMemoryMissionsRegistryTest { private static final String ENTRIES_PRIVATE_FIELD_NAME = "entries"; @Mock - private Mission mission1; + private JdiMission jdiMission1; @Mock - private Mission mission2; - private Set testMissions; + private JdiMission jdiMission2; + private Set testJdiMissions; @Mock private MissionsDiscoverer missionsDiscoverer; private InMemoryMissionsRegistry inMemoryMissionsRegistry; @Before public void setUp() { - testMissions = new HashSet<>(Arrays.asList(mission1, mission2)); + testJdiMissions = new HashSet<>(Arrays.asList(jdiMission1, jdiMission2)); } @Test public void testInstantiateInMemoryMissionsRegistry() throws NoSuchFieldException { - Mockito.when(missionsDiscoverer.availableMissions()).thenReturn(testMissions); + Mockito.when(missionsDiscoverer.availableMissions()).thenReturn(testJdiMissions); inMemoryMissionsRegistry = new InMemoryMissionsRegistry(missionsDiscoverer); @SuppressWarnings("unchecked") - Set missions = (Set) PrivateAccessor.getField(inMemoryMissionsRegistry, ENTRIES_PRIVATE_FIELD_NAME); - assertEquals(2, missions.size()); - assertEquals(testMissions, missions); + Set jdiMissions = (Set) PrivateAccessor.getField(inMemoryMissionsRegistry, ENTRIES_PRIVATE_FIELD_NAME); + assertEquals(2, jdiMissions.size()); + assertEquals(testJdiMissions, jdiMissions); } } \ No newline at end of file diff --git a/commons/src/test/java/cern/molr/jvm/impl/SimpleMoleRunnerSpawnerTest.java b/commons/src/test/java/cern/molr/jvm/impl/SimpleMoleRunnerSpawnerTest.java index 6a8c640..28c7f0b 100644 --- a/commons/src/test/java/cern/molr/jvm/impl/SimpleMoleRunnerSpawnerTest.java +++ b/commons/src/test/java/cern/molr/jvm/impl/SimpleMoleRunnerSpawnerTest.java @@ -6,7 +6,7 @@ package cern.molr.jvm.impl; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import junit.framework.TestCase; import org.junit.Rule; import org.junit.Test; @@ -16,7 +16,6 @@ import org.mockito.junit.MockitoJUnitRunner; import java.io.IOException; -import java.util.Arrays; import static org.mockito.Mockito.when; @@ -31,7 +30,7 @@ public class SimpleMoleRunnerSpawnerTest extends TestCase { @Rule public ExpectedException expectedException = ExpectedException.none(); @Mock - private Mission mission; + private JdiMission jdiMission; private final SimpleMoleRunnerSpawner simpleMoleRunnerSpawner = new SimpleMoleRunnerSpawner(); @Test @@ -43,20 +42,20 @@ public void testSpawnMoleRunnerWithNullMission() throws IOException { @Test public void testSpawnMoleRunnerWithNullClasspath() throws IOException { expectedException.expect(IllegalArgumentException.class); - simpleMoleRunnerSpawner.spawnMoleRunner(mission, null, (String[]) null); + simpleMoleRunnerSpawner.spawnMoleRunner(jdiMission, null, (String[]) null); } @Test public void testSpawnMoleRunnerWithNullArgsElements() throws IOException { expectedException.expect(IllegalArgumentException.class); String args[] = {null, null}; - simpleMoleRunnerSpawner.spawnMoleRunner(mission, "", args); + simpleMoleRunnerSpawner.spawnMoleRunner(jdiMission, "", args); } @Test public void testSpawnMoleRunner() throws IOException { - when(mission.getMoleClassName()).thenReturn("MoleClassName"); - when(mission.getMissionContentClassName()).thenReturn("MissionContentClassName"); - simpleMoleRunnerSpawner.spawnMoleRunner(mission); + when(jdiMission.getMoleClassName()).thenReturn("MoleClassName"); + when(jdiMission.getMissionContentClassName()).thenReturn("MissionContentClassName"); + simpleMoleRunnerSpawner.spawnMoleRunner(jdiMission); } } \ No newline at end of file diff --git a/commons/src/test/java/cern/molr/inspector/json/MissionTypeAdapterTest.java b/commons/src/test/java/io/molr/mole/jdebug/spawner/json/MissionTypeAdapterTest.java similarity index 88% rename from commons/src/test/java/cern/molr/inspector/json/MissionTypeAdapterTest.java rename to commons/src/test/java/io/molr/mole/jdebug/spawner/json/MissionTypeAdapterTest.java index daed591..69bcce8 100644 --- a/commons/src/test/java/cern/molr/inspector/json/MissionTypeAdapterTest.java +++ b/commons/src/test/java/io/molr/mole/jdebug/spawner/json/MissionTypeAdapterTest.java @@ -4,9 +4,9 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.json; +package io.molr.mole.jdebug.spawner.json; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; import cern.molr.commons.domain.impl.MissionImpl; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; @@ -24,7 +24,7 @@ public class MissionTypeAdapterTest { private static final List ENTRY_POINTS = Arrays.asList("one", "two"); - private static final Mission SERVICE_IMPL = new MissionImpl("testAgent", "testClass", ENTRY_POINTS); + private static final JdiMission SERVICE_IMPL = new MissionImpl("testAgent", "testClass", ENTRY_POINTS); private static final MissionTypeAdapter TYPE_ADAPTER = new MissionTypeAdapter(); @Test @@ -60,11 +60,11 @@ public void failsToDeserialiseOnMalformedJson() throws IOException { read(json); } - private Mission read(String json) throws IOException { + private JdiMission read(String json) throws IOException { return TYPE_ADAPTER.read(new JsonReader(new StringReader(json))); } - private String write(Mission service) throws IOException { + private String write(JdiMission service) throws IOException { final StringWriter writer = new StringWriter(); TYPE_ADAPTER.write(new JsonWriter(writer), service); return writer.toString(); diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..936b4cf --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +assertJVersion=3.11.1 \ No newline at end of file diff --git a/gui/src/main/java/cern/molr/inspector/gui/DebugPane.java b/gui/src/main/java/io/molr/mole/jdebug/spawner/gui/DebugPane.java similarity index 95% rename from gui/src/main/java/cern/molr/inspector/gui/DebugPane.java rename to gui/src/main/java/io/molr/mole/jdebug/spawner/gui/DebugPane.java index 0bb9987..72b1201 100644 --- a/gui/src/main/java/cern/molr/inspector/gui/DebugPane.java +++ b/gui/src/main/java/io/molr/mole/jdebug/spawner/gui/DebugPane.java @@ -4,12 +4,12 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.gui; +package io.molr.mole.jdebug.spawner.gui; -import cern.molr.inspector.DebugMoleSpawner; -import cern.molr.inspector.controller.StatefulJdiController; -import cern.molr.inspector.domain.Session; -import cern.molr.inspector.entry.EntryState; +import io.molr.mole.jdebug.spawner.DebugMoleSpawner; +import io.molr.mole.jdebug.spawner.controller.StatefulJdiController; +import io.molr.mole.jdebug.spawner.domain.Session; +import io.molr.mole.jdebug.spawner.entry.EntryState; import javafx.application.Platform; import javafx.geometry.Insets; import javafx.geometry.Pos; @@ -59,7 +59,7 @@ public DebugPane(Session session) { this.session = session; initUI(); - missionContentClassName = session.getMission().getMissionContentClassName(); + missionContentClassName = session.getJdiMission().getMissionContentClassName(); initData(missionContentClassName); session.getController().addObserver(this); session.getController() diff --git a/gui/src/main/java/cern/molr/inspector/gui/SessionsListPane.java b/gui/src/main/java/io/molr/mole/jdebug/spawner/gui/SessionsListPane.java similarity index 94% rename from gui/src/main/java/cern/molr/inspector/gui/SessionsListPane.java rename to gui/src/main/java/io/molr/mole/jdebug/spawner/gui/SessionsListPane.java index 1a64a48..158e8fe 100644 --- a/gui/src/main/java/cern/molr/inspector/gui/SessionsListPane.java +++ b/gui/src/main/java/io/molr/mole/jdebug/spawner/gui/SessionsListPane.java @@ -4,11 +4,11 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.gui; +package io.molr.mole.jdebug.spawner.gui; import cern.molr.commons.registry.ObservableRegistry; -import cern.molr.inspector.domain.Session; -import cern.molr.inspector.domain.impl.SessionRegistry; +import io.molr.mole.jdebug.spawner.domain.Session; +import io.molr.mole.jdebug.spawner.domain.impl.SessionRegistry; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -104,7 +104,7 @@ public void updateItem(Session session, boolean empty) { if (empty) { setGraphic(null); } else { - Label label = new Label(session.getMission().getMissionContentClassName()); + Label label = new Label(session.getJdiMission().getMissionContentClassName()); setGraphic(label); } } diff --git a/gui/src/main/java/cern/molr/inspector/gui/SwingUtils.java b/gui/src/main/java/io/molr/mole/jdebug/spawner/gui/SwingUtils.java similarity index 97% rename from gui/src/main/java/cern/molr/inspector/gui/SwingUtils.java rename to gui/src/main/java/io/molr/mole/jdebug/spawner/gui/SwingUtils.java index 6540dfc..02597bb 100644 --- a/gui/src/main/java/cern/molr/inspector/gui/SwingUtils.java +++ b/gui/src/main/java/io/molr/mole/jdebug/spawner/gui/SwingUtils.java @@ -4,7 +4,7 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.gui; +package io.molr.mole.jdebug.spawner.gui; import javafx.application.Platform; import javafx.embed.swing.JFXPanel; diff --git a/inspector/build.gradle b/inspector/build.gradle index 49e55cb..67755c1 100644 --- a/inspector/build.gradle +++ b/inspector/build.gradle @@ -7,12 +7,16 @@ version = "0.1" dependencies { - compile files("${System.properties['java.home']}/../lib/tools.jar") + //compile files("${System.properties['java.home']}/../lib/tools.jar") compile group: "com.google.code.gson", name: "gson", version: "2.+" compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.+' + implementation 'org.jdiscript:jdiscript:0.9.0' + testCompile group: 'junit', name: 'junit', version: '4.11' testCompile group: 'org.mockito', name: 'mockito-core', version: '3.+' + testCompile group: 'org.assertj', name: 'assertj-core', version: assertJVersion + } javadoc { diff --git a/inspector/src/main/java/io/molr/mole/jdebug/domain/Missions.java b/inspector/src/main/java/io/molr/mole/jdebug/domain/Missions.java new file mode 100644 index 0000000..c5aa35e --- /dev/null +++ b/inspector/src/main/java/io/molr/mole/jdebug/domain/Missions.java @@ -0,0 +1,57 @@ +package io.molr.mole.jdebug.domain; + +import cern.molr.commons.domain.JdiMission; +import cern.molr.commons.domain.impl.MissionImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Collections; +import java.util.Optional; + +import static java.util.Objects.requireNonNull; + +/** + * Utility class that provides factory methods for mission domain objects. + * These domain objects describe the class to execute and the entry points. + *

+ * These objects are then later fed into a {@link io.molr.mole.jdebug.spawner.controller.JdiControllerImpl} for instantiation. + */ +public final class Missions { + + private final static Logger LOGGER = LoggerFactory.getLogger(Missions.class); + + private Missions() { + /* Only static methods */ + } + + public static JdiMission ofMain(Class mainClass) { + requireNonNull(mainClass, "mainClass must not be null."); + Optional mainMethod = mainMethod((Class) mainClass); + if (!mainMethod.isPresent()) { + throw new IllegalArgumentException("Class '" + mainClass + "' does not contain a valid main method! Cannot create a mission from it."); + } + return new MissionImpl(mainClass.getName(), mainClass.getName(), Collections.singletonList(mainMethod.get().getName())); + } + + private static Optional mainMethod(Class mainClass) { + return searchByName(mainClass) // + .filter(m -> Modifier.isStatic(m.getModifiers())) // + .filter(m -> m.getReturnType().equals(Void.TYPE)); + } + + private static boolean isStatic(Method method) { + return Modifier.isStatic(method.getModifiers()); + } + + private static Optional searchByName(Class mainClass) { + try { + return Optional.of(mainClass.getDeclaredMethod("main", String[].class)); + } catch (NoSuchMethodException e) { + return Optional.empty(); + } + } + + +} diff --git a/inspector/src/main/java/io/molr/mole/jdebug/spawner/ConnectorInspector.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/ConnectorInspector.java new file mode 100644 index 0000000..2177dde --- /dev/null +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/ConnectorInspector.java @@ -0,0 +1,32 @@ +package io.molr.mole.jdebug.spawner; + +import com.sun.jdi.Bootstrap; +import com.sun.jdi.VirtualMachineManager; + +public class ConnectorInspector { + + + public static void println(String s) { + System.out.println(s); + } + + public static void main(String[] args) { + VirtualMachineManager vmm = Bootstrap.virtualMachineManager(); + + vmm.allConnectors().forEach(c -> { + println(c.name() + ":"); + println(" " + c.description()); + c.defaultArguments().forEach((k, v) -> { + println(" " + v.name()); + println(" label: " + v.label()); + println(" required: " + v.mustSpecify()); + println(" default: " + v.value()); + println(" desc: " + v.description()); + }); + println(""); + }); + + println("Default Connector: " + vmm.defaultConnector().name()); + } +} + diff --git a/inspector/src/main/java/cern/molr/inspector/DebugMoleSpawner.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/DebugMoleSpawner.java similarity index 69% rename from inspector/src/main/java/cern/molr/inspector/DebugMoleSpawner.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/DebugMoleSpawner.java index d8b0720..01008dd 100644 --- a/inspector/src/main/java/cern/molr/inspector/DebugMoleSpawner.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/DebugMoleSpawner.java @@ -1,15 +1,15 @@ -package cern.molr.inspector; +package io.molr.mole.jdebug.spawner; import cern.molr.commons.annotations.Source; -import cern.molr.commons.domain.Mission; -import cern.molr.inspector.controller.StatefulJdiControllerImpl; -import cern.molr.inspector.domain.InstantiationRequest; -import cern.molr.inspector.domain.Session; -import cern.molr.inspector.domain.SourceFetcher; -import cern.molr.inspector.domain.impl.InstantiationRequestImpl; -import cern.molr.inspector.domain.impl.SessionImpl; -import cern.molr.inspector.json.MissionTypeAdapter; -import cern.molr.inspector.remote.SystemMain; +import cern.molr.commons.domain.JdiMission; +import io.molr.mole.jdebug.spawner.controller.StatefulJdiControllerImpl; +import io.molr.mole.jdebug.spawner.domain.InstantiationRequest; +import io.molr.mole.jdebug.spawner.domain.Session; +import io.molr.mole.jdebug.spawner.domain.SourceFetcher; +import io.molr.mole.jdebug.spawner.domain.impl.InstantiationRequestImpl; +import io.molr.mole.jdebug.spawner.domain.impl.SessionImpl; +import io.molr.mole.jdebug.spawner.json.MissionTypeAdapter; +import io.molr.mole.jdebug.spawner.remote.SystemMain; import cern.molr.jvm.JvmSpawnHelper; import cern.molr.jvm.MoleSpawner; import com.google.gson.Gson; @@ -27,11 +27,11 @@ public class DebugMoleSpawner implements MoleSpawner, SourceFetcher { private static final Logger LOGGER = LoggerFactory.getLogger(DebugMoleSpawner.class); - private static final String CURRENT_CLASSPATH_VALUE = System.getProperty("java.class.path"); + public static final String CURRENT_CLASSPATH_VALUE = System.getProperty("java.class.path"); private static final String INSPECTOR_MAIN_CLASS = SystemMain.class.getName(); private static final Gson GSON = new GsonBuilder() - .registerTypeAdapter(Mission.class, new MissionTypeAdapter().nullSafe()) + .registerTypeAdapter(JdiMission.class, new MissionTypeAdapter().nullSafe()) .create(); public String getSource(String classname) { @@ -46,15 +46,15 @@ public String getSource(String classname) { } @Override - public Session spawnMoleRunner(Mission mission, String... args) throws IOException { - if(mission == null) { + public Session spawnMoleRunner(JdiMission jdiMission, String... args) throws IOException { + if (jdiMission == null) { throw new IllegalArgumentException("The mission must not be null"); } - InstantiationRequest request = new InstantiationRequestImpl(CURRENT_CLASSPATH_VALUE, mission); + InstantiationRequest request = new InstantiationRequestImpl(CURRENT_CLASSPATH_VALUE, jdiMission); String[] completedArgs = new String[args.length + 1]; completedArgs[0] = GSON.toJson(request); int i = 1; - for(String arg : args) { + for (String arg : args) { completedArgs[i++] = arg; } @@ -65,11 +65,11 @@ public Session spawnMoleRunner(Mission mission, String... args) throws IOExcepti redirectStream(process.getErrorStream(), System.err); Runtime.getRuntime().addShutdownHook(new Thread(process::destroy)); - return new SessionImpl(mission, new StatefulJdiControllerImpl(process)); + return new SessionImpl(jdiMission, new StatefulJdiControllerImpl(process)); } @Override - public Session spawnMoleRunner(Mission mission, String classpath, String... args) throws Exception { + public Session spawnMoleRunner(JdiMission jdiMission, String classpath, String... args) throws Exception { return null; } @@ -87,4 +87,7 @@ private static void redirectStream(InputStream input, PrintStream output) { } }); } + + + } diff --git a/inspector/src/main/java/io/molr/mole/jdebug/spawner/JdiMissionSpawner.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/JdiMissionSpawner.java new file mode 100644 index 0000000..25b1145 --- /dev/null +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/JdiMissionSpawner.java @@ -0,0 +1,24 @@ +package io.molr.mole.jdebug.spawner; + +import cern.molr.commons.domain.JdiMission; +import io.molr.mole.jdebug.spawner.controller.JdiControllerImpl; +import io.molr.mole.jdebug.spawner.controller.LocalDelegatingStatefulJdiController; +import io.molr.mole.jdebug.spawner.controller.StatefulJdiController; +import io.molr.mole.jdebug.spawner.domain.InstantiationRequest; +import io.molr.mole.jdebug.spawner.domain.impl.InstantiationRequestImpl; +import io.molr.mole.jdebug.spawner.remote.SystemMain; + +public final class JdiMissionSpawner { + + private JdiMissionSpawner() { + /* only static methods */ + } + + public static StatefulJdiController start(JdiMission jdiMission) { + InstantiationRequest request = new InstantiationRequestImpl(DebugMoleSpawner.CURRENT_CLASSPATH_VALUE, jdiMission); + LocalDelegatingStatefulJdiController controller = new LocalDelegatingStatefulJdiController(jdiMission.getMissionContentClassName()); + JdiControllerImpl internal = SystemMain.startJdi(request, controller); + controller.setDelegate(internal); + return controller; + } +} diff --git a/inspector/src/main/java/cern/molr/inspector/controller/JdiController.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiController.java similarity index 94% rename from inspector/src/main/java/cern/molr/inspector/controller/JdiController.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiController.java index 21c9921..d47ec07 100644 --- a/inspector/src/main/java/cern/molr/inspector/controller/JdiController.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiController.java @@ -4,7 +4,7 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.controller; +package io.molr.mole.jdebug.spawner.controller; /** * A controller for a JDI instance that can control any running JVM instances by stepping through or terminating them. diff --git a/inspector/src/main/java/cern/molr/inspector/controller/JdiControllerImpl.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiControllerImpl.java similarity index 87% rename from inspector/src/main/java/cern/molr/inspector/controller/JdiControllerImpl.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiControllerImpl.java index 0e2a7c3..9ebd9c9 100644 --- a/inspector/src/main/java/cern/molr/inspector/controller/JdiControllerImpl.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiControllerImpl.java @@ -4,11 +4,11 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.controller; +package io.molr.mole.jdebug.spawner.controller; import cern.molr.commons.mole.GenericMoleRunner; -import cern.molr.commons.domain.Mission; -import cern.molr.inspector.entry.EntryListener; +import cern.molr.commons.domain.JdiMission; +import io.molr.mole.jdebug.spawner.entry.EntryListener; import com.sun.jdi.ThreadReference; import com.sun.jdi.connect.IllegalConnectorArgumentsException; import com.sun.jdi.connect.VMStartException; @@ -100,17 +100,18 @@ public static class Builder { private static final String CLASSPATH_PREFIX = "-cp "; private String classPath; - private Mission mission; + private JdiMission jdiMission; private EntryListener entryListener; public JdiControllerImpl build() throws IOException, IllegalConnectorArgumentsException, VMStartException { Objects.requireNonNull(classPath, "Classpath must be set"); Objects.requireNonNull(entryListener, "Listener must be set"); - Objects.requireNonNull(mission, "Mission to inspect must be set"); + Objects.requireNonNull(jdiMission, "Mission to inspect must be set"); - final String launchArguments = AGENT_RUNNER_CLASS + " " + mission.getMoleClassName() + " " + mission.getMissionContentClassName(); - final VMLauncher launcher = new VMLauncher(CLASSPATH_PREFIX + classPath, launchArguments); + String options = CLASSPATH_PREFIX + classPath; + final String launchArguments = jdiMission.getMoleClassName(); + final VMLauncher launcher = new VMLauncher(options, launchArguments); JdiEntryRegistry entryRegistry = new JdiEntryRegistry<>(); // early registration, to be notified if VM dies before reaching the first breakpoint @@ -120,7 +121,7 @@ public JdiControllerImpl build() throws IOException, IllegalConnectorArgumentsEx JDIScript jdi = new JdiInstanceBuilder() .setLauncher(launcher) - .setMission(mission) + .setJdiMission(jdiMission) .setEntryRegistry(entryRegistry) .setListener(entryListener) .setFlowInhibitor(whatever -> flowInhibitionWrapper.isInhibiting()) @@ -139,8 +140,8 @@ public Builder setClassPath(String path) { return this; } - public Builder setMission(Mission method) { - this.mission = method; + public Builder setJdiMission(JdiMission method) { + this.jdiMission = method; return this; } } diff --git a/inspector/src/main/java/cern/molr/inspector/controller/JdiEntryRegistry.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiEntryRegistry.java similarity index 92% rename from inspector/src/main/java/cern/molr/inspector/controller/JdiEntryRegistry.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiEntryRegistry.java index 7410a7c..a182045 100644 --- a/inspector/src/main/java/cern/molr/inspector/controller/JdiEntryRegistry.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiEntryRegistry.java @@ -4,9 +4,9 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.controller; +package io.molr.mole.jdebug.spawner.controller; -import cern.molr.inspector.entry.EntryListener; +import io.molr.mole.jdebug.spawner.entry.EntryListener; import com.sun.jdi.ThreadReference; import java.util.Optional; diff --git a/inspector/src/main/java/cern/molr/inspector/controller/JdiEventHandler.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiEventHandler.java similarity index 95% rename from inspector/src/main/java/cern/molr/inspector/controller/JdiEventHandler.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiEventHandler.java index 759ccd9..7480388 100644 --- a/inspector/src/main/java/cern/molr/inspector/controller/JdiEventHandler.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiEventHandler.java @@ -4,7 +4,7 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.controller; +package io.molr.mole.jdebug.spawner.controller; import com.sun.jdi.ThreadReference; import com.sun.jdi.VirtualMachine; @@ -22,7 +22,7 @@ public abstract class JdiEventHandler extends BaseEventHandler { * @param vm The virtual machine this event handler interacts with. */ public JdiEventHandler(VirtualMachine vm) { - super(vm); + setVM(vm); } /** diff --git a/inspector/src/main/java/cern/molr/inspector/controller/JdiInstanceBuilder.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiInstanceBuilder.java similarity index 81% rename from inspector/src/main/java/cern/molr/inspector/controller/JdiInstanceBuilder.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiInstanceBuilder.java index bd65f73..06f2789 100644 --- a/inspector/src/main/java/cern/molr/inspector/controller/JdiInstanceBuilder.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiInstanceBuilder.java @@ -4,11 +4,11 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.controller; +package io.molr.mole.jdebug.spawner.controller; -import cern.molr.commons.domain.Mission; -import cern.molr.inspector.entry.EntryListener; -import cern.molr.inspector.jdi.ClassInstantiationListener; +import cern.molr.commons.domain.JdiMission; +import io.molr.mole.jdebug.spawner.entry.EntryListener; +import io.molr.mole.jdebug.spawner.jdi.ClassInstantiationListener; import com.sun.jdi.VirtualMachine; import com.sun.jdi.connect.IllegalConnectorArgumentsException; import com.sun.jdi.connect.VMStartException; @@ -28,14 +28,14 @@ public class JdiInstanceBuilder { private VMLauncher launcher; - private Mission mission; + private JdiMission jdiMission; private Predicate flowInhibitor; private EntryListener entryListener; private JdiEntryRegistry registry; /** * Builds a new {@link JDIScript} by 1) asking the {@link VMLauncher} to launch a new process, - * 2) creates a listener to listen for the new instantiations of the {@link Mission} classes given in the + * 2) creates a listener to listen for the new instantiations of the {@link JdiMission} classes given in the * builder and 3) asks the running VM to break whenever such a mission is met. * * @return An instantiation of a {@link JDIScript}. @@ -43,7 +43,7 @@ public class JdiInstanceBuilder { */ public JDIScript build() throws IOException { Objects.requireNonNull(launcher, "Launcher must not be null"); - Objects.requireNonNull(mission, "Service must not be null"); + Objects.requireNonNull(jdiMission, "Service must not be null"); Objects.requireNonNull(registry, "Entry registry must be set"); Objects.requireNonNull(entryListener, "Listener must not be null"); Objects.requireNonNull(flowInhibitor, "Flow inhibitor must not be null"); @@ -53,11 +53,11 @@ public JDIScript build() throws IOException { JDIScript jdi = new JDIScript(virtualMachine); SteppingJdiEventHandler eventHandler = new SteppingJdiEventHandler(jdi, entryListener, registry, flowInhibitor); - Runtime.getRuntime().addShutdownHook(new Thread(launcher.getProcess()::destroy)); + Runtime.getRuntime().addShutdownHook(new Thread(virtualMachine.process()::destroy)); ClassInstantiationListener instantiationListener = - new ClassInstantiationListener(mission.getMissionContentClassName(), - classType -> mission.getTasksNames().forEach(methodName -> + new ClassInstantiationListener(jdiMission.getMissionContentClassName(), + classType -> jdiMission.getTasksNames().forEach(methodName -> eventHandler.registerClassInstantiation(classType, methodName))); ExecutorService executorService = Executors.newFixedThreadPool(1); @@ -88,8 +88,8 @@ public JdiInstanceBuilder setLauncher(VMLauncher launcher) { return this; } - public JdiInstanceBuilder setMission(Mission mission) { - this.mission = mission; + public JdiInstanceBuilder setJdiMission(JdiMission jdiMission) { + this.jdiMission = jdiMission; return this; } diff --git a/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/LocalDelegatingStatefulJdiController.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/LocalDelegatingStatefulJdiController.java new file mode 100644 index 0000000..8843cbc --- /dev/null +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/LocalDelegatingStatefulJdiController.java @@ -0,0 +1,118 @@ +package io.molr.mole.jdebug.spawner.controller; + +import io.molr.mole.jdebug.spawner.entry.EntryListener; +import io.molr.mole.jdebug.spawner.entry.EntryState; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +import static java.util.Objects.requireNonNull; + +/** + * This is first try of a wrapper implementation around a normal JdiController. This is far from beautiful, + * but the first goal is to get some useful debugging running, without all the text-based communication. + *

+ * There is some ugliness: As the listener has to be set to the builder of {@link JdiControllerImpl} ... the instance + * of this stateful controller is first created and then the delegate is set to it. As mentioned: Far from final ;-) + * + * @author kaifox + */ +public class LocalDelegatingStatefulJdiController implements StatefulJdiController, EntryListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(LocalDelegatingStatefulJdiController.class); + + private JdiController delegate; + + private boolean dead = false; + private Optional lastKnownState = Optional.empty(); + private final Set observers = new HashSet<>(); + + private final String missionContentClassName; + + public LocalDelegatingStatefulJdiController(String missionContentClassName) { + this.missionContentClassName = missionContentClassName; + } + + public void setDelegate(JdiController jdiController) { + this.delegate = requireNonNull(jdiController, "delegate JdiController must not be null"); + } + + @Override + public void onLocationChange(EntryState state) { + LOGGER.info("onLocationChange {}", state); + if (missionContentClassName.equals(state.getClassName())) { + LOGGER.info("in class {}, stepping available", missionContentClassName); + lastKnownState = Optional.of(state); + entryStateChanged(); + } else { + LOGGER.info("out of class {}, resuming", missionContentClassName); + resume(); + } + } + + @Override + public void onInspectionEnd(EntryState state) { + // not used + } + + @Override + public void onVmDeath() { + die(); + } + + @Override + public void stepForward() { + delegate.stepForward(); + setUnknownEntryState(); + } + + @Override + public void resume() { + delegate.resume(); + setUnknownEntryState(); + } + + @Override + public void terminate() { + delegate.terminate(); + setUnknownEntryState(); + } + + @Override + public boolean isDead() { + return dead; + } + + @Override + public Optional getLastKnownState() { + return lastKnownState; + } + + private void setUnknownEntryState() { + if (lastKnownState.isPresent()) { + lastKnownState = Optional.empty(); + entryStateChanged(); + } + } + + private void die() { + setUnknownEntryState(); + dead = true; + observers.forEach(JdiStateObserver::death); + } + + private void entryStateChanged() { + observers.forEach(JdiStateObserver::entryStateChanged); + } + + public void addObserver(JdiStateObserver jdiStateObserver) { + observers.add(jdiStateObserver); + } + + public void removeObserver(JdiStateObserver jdiStateObserver) { + observers.remove(jdiStateObserver); + } +} \ No newline at end of file diff --git a/inspector/src/main/java/cern/molr/inspector/controller/SourceCodeLoader.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/SourceCodeLoader.java similarity index 96% rename from inspector/src/main/java/cern/molr/inspector/controller/SourceCodeLoader.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/SourceCodeLoader.java index 5be764e..147b9cb 100644 --- a/inspector/src/main/java/cern/molr/inspector/controller/SourceCodeLoader.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/SourceCodeLoader.java @@ -4,7 +4,7 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.controller; +package io.molr.mole.jdebug.spawner.controller; import java.io.BufferedReader; import java.io.IOException; diff --git a/inspector/src/main/java/cern/molr/inspector/controller/StatefulJdiController.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/StatefulJdiController.java similarity index 69% rename from inspector/src/main/java/cern/molr/inspector/controller/StatefulJdiController.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/StatefulJdiController.java index ac6feb7..70b4b16 100644 --- a/inspector/src/main/java/cern/molr/inspector/controller/StatefulJdiController.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/StatefulJdiController.java @@ -1,11 +1,12 @@ -package cern.molr.inspector.controller; +package io.molr.mole.jdebug.spawner.controller; -import cern.molr.inspector.entry.EntryState; +import io.molr.mole.jdebug.spawner.entry.EntryState; import java.util.Optional; /** * Stateful extension of the {@link JdiController} interface + * * @author mgalilee */ public interface StatefulJdiController extends JdiController { @@ -17,8 +18,13 @@ public interface StatefulJdiController extends JdiController { void removeObserver(JdiStateObserver jdiStateObserver); + default boolean canStep() { + return !isDead() && getLastKnownState().isPresent(); + } + interface JdiStateObserver { void death(); + void entryStateChanged(); } } diff --git a/inspector/src/main/java/cern/molr/inspector/controller/StatefulJdiControllerImpl.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/StatefulJdiControllerImpl.java similarity index 91% rename from inspector/src/main/java/cern/molr/inspector/controller/StatefulJdiControllerImpl.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/StatefulJdiControllerImpl.java index dc3a3ad..c605832 100644 --- a/inspector/src/main/java/cern/molr/inspector/controller/StatefulJdiControllerImpl.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/StatefulJdiControllerImpl.java @@ -1,9 +1,9 @@ -package cern.molr.inspector.controller; +package io.molr.mole.jdebug.spawner.controller; -import cern.molr.inspector.entry.EntryListener; -import cern.molr.inspector.entry.EntryState; -import cern.molr.inspector.remote.EntryListenerReader; -import cern.molr.inspector.remote.JdiControllerWriter; +import io.molr.mole.jdebug.spawner.entry.EntryListener; +import io.molr.mole.jdebug.spawner.entry.EntryState; +import io.molr.mole.jdebug.spawner.remote.EntryListenerReader; +import io.molr.mole.jdebug.spawner.remote.JdiControllerWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/inspector/src/main/java/cern/molr/inspector/controller/SteppingJdiEventHandler.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/SteppingJdiEventHandler.java similarity index 95% rename from inspector/src/main/java/cern/molr/inspector/controller/SteppingJdiEventHandler.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/SteppingJdiEventHandler.java index 59757a5..2a045e9 100644 --- a/inspector/src/main/java/cern/molr/inspector/controller/SteppingJdiEventHandler.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/SteppingJdiEventHandler.java @@ -4,11 +4,11 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.controller; +package io.molr.mole.jdebug.spawner.controller; -import cern.molr.inspector.entry.EntryListener; -import cern.molr.inspector.entry.EntryStateBuilder; -import cern.molr.inspector.jdi.LocationRange; +import io.molr.mole.jdebug.spawner.entry.EntryListener; +import io.molr.mole.jdebug.spawner.entry.EntryStateBuilder; +import io.molr.mole.jdebug.spawner.jdi.LocationRange; import com.sun.jdi.*; import com.sun.jdi.event.*; import com.sun.jdi.request.StepRequest; diff --git a/inspector/src/main/java/cern/molr/inspector/domain/InstantiationRequest.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/InstantiationRequest.java similarity index 69% rename from inspector/src/main/java/cern/molr/inspector/domain/InstantiationRequest.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/InstantiationRequest.java index 2313f59..2852083 100644 --- a/inspector/src/main/java/cern/molr/inspector/domain/InstantiationRequest.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/InstantiationRequest.java @@ -4,12 +4,12 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.domain; +package io.molr.mole.jdebug.spawner.domain; -import cern.molr.commons.domain.Mission; +import cern.molr.commons.domain.JdiMission; /** - * A request to instantiate an inspector with a given classpath and a {@link Mission} to run. + * A request to instantiate an inspector with a given classpath and a {@link JdiMission} to run. */ public interface InstantiationRequest { @@ -21,10 +21,10 @@ public interface InstantiationRequest { String getClassPath(); /** - * The {@link Mission} that should be run with this request. + * The {@link JdiMission} that should be run with this request. * - * @return A {@link Mission} containing information about what main class to run with what arguments. + * @return A {@link JdiMission} containing information about what main class to run with what arguments. */ - Mission getMission(); + JdiMission getJdiMission(); } \ No newline at end of file diff --git a/inspector/src/main/java/cern/molr/inspector/domain/Session.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/Session.java similarity index 63% rename from inspector/src/main/java/cern/molr/inspector/domain/Session.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/Session.java index e69babb..860c728 100644 --- a/inspector/src/main/java/cern/molr/inspector/domain/Session.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/Session.java @@ -1,21 +1,21 @@ -package cern.molr.inspector.domain; +package io.molr.mole.jdebug.spawner.domain; -import cern.molr.commons.domain.Mission; -import cern.molr.inspector.controller.StatefulJdiController; +import cern.molr.commons.domain.JdiMission; +import io.molr.mole.jdebug.spawner.controller.StatefulJdiController; import java.time.ZonedDateTime; /** - * A generic {@link Session}, encapsulates the information of a currently running {@link Mission} + * A generic {@link Session}, encapsulates the information of a currently running {@link JdiMission} * * @author tiagomr */ public interface Session { /** - * @return the {@link Mission} being executed + * @return the {@link JdiMission} being executed */ - Mission getMission(); + JdiMission getJdiMission(); /** * @return the {@link StatefulJdiController} used to control the execution flow for this specific execution diff --git a/inspector/src/main/java/cern/molr/inspector/domain/SourceFetcher.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/SourceFetcher.java similarity index 75% rename from inspector/src/main/java/cern/molr/inspector/domain/SourceFetcher.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/SourceFetcher.java index c50f60c..33ae4a9 100644 --- a/inspector/src/main/java/cern/molr/inspector/domain/SourceFetcher.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/SourceFetcher.java @@ -1,4 +1,4 @@ -package cern.molr.inspector.domain; +package io.molr.mole.jdebug.spawner.domain; /** * Interface for fetching the source code of classes diff --git a/inspector/src/main/java/cern/molr/inspector/domain/impl/InstantiationRequestImpl.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/impl/InstantiationRequestImpl.java similarity index 65% rename from inspector/src/main/java/cern/molr/inspector/domain/impl/InstantiationRequestImpl.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/impl/InstantiationRequestImpl.java index f8ad263..f150943 100644 --- a/inspector/src/main/java/cern/molr/inspector/domain/impl/InstantiationRequestImpl.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/impl/InstantiationRequestImpl.java @@ -4,10 +4,10 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.domain.impl; +package io.molr.mole.jdebug.spawner.domain.impl; -import cern.molr.commons.domain.Mission; -import cern.molr.inspector.domain.InstantiationRequest; +import cern.molr.commons.domain.JdiMission; +import io.molr.mole.jdebug.spawner.domain.InstantiationRequest; /** * An immutable implementation of an {@link InstantiationRequest}. @@ -15,17 +15,17 @@ public class InstantiationRequestImpl implements InstantiationRequest { private final String classPath; - private final Mission mission; + private final JdiMission jdiMission; /** - * Creates a {@link InstantiationRequestImpl} using the given class path and {@link Mission}. + * Creates a {@link InstantiationRequestImpl} using the given class path and {@link JdiMission}. * * @param classPath The class path containing zero or more paths separated by the {@link java.io.File#pathSeparator}. - * @param mission The mission to execute. + * @param jdiMission The mission to execute. */ - public InstantiationRequestImpl(String classPath, Mission mission) { + public InstantiationRequestImpl(String classPath, JdiMission jdiMission) { this.classPath = classPath; - this.mission = mission; + this.jdiMission = jdiMission; } @Override @@ -33,8 +33,8 @@ public String getClassPath() { return classPath; } - public Mission getMission() { - return mission; + public JdiMission getJdiMission() { + return jdiMission; } } \ No newline at end of file diff --git a/inspector/src/main/java/cern/molr/inspector/domain/impl/SessionImpl.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/impl/SessionImpl.java similarity index 52% rename from inspector/src/main/java/cern/molr/inspector/domain/impl/SessionImpl.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/impl/SessionImpl.java index a109f6e..6bd50fd 100644 --- a/inspector/src/main/java/cern/molr/inspector/domain/impl/SessionImpl.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/impl/SessionImpl.java @@ -1,8 +1,8 @@ -package cern.molr.inspector.domain.impl; +package io.molr.mole.jdebug.spawner.domain.impl; -import cern.molr.commons.domain.Mission; -import cern.molr.inspector.controller.StatefulJdiController; -import cern.molr.inspector.domain.Session; +import cern.molr.commons.domain.JdiMission; +import io.molr.mole.jdebug.spawner.controller.StatefulJdiController; +import io.molr.mole.jdebug.spawner.domain.Session; import java.time.ZonedDateTime; @@ -12,17 +12,17 @@ public class SessionImpl implements Session { private final ZonedDateTime timestamp = ZonedDateTime.now(); - private final Mission mission; + private final JdiMission jdiMission; private final StatefulJdiController controller; - public SessionImpl(Mission mission, StatefulJdiController controller) { - this.mission = mission; + public SessionImpl(JdiMission jdiMission, StatefulJdiController controller) { + this.jdiMission = jdiMission; this.controller = controller; } @Override - public Mission getMission() { - return mission; + public JdiMission getJdiMission() { + return jdiMission; } @Override diff --git a/inspector/src/main/java/cern/molr/inspector/domain/impl/SessionRegistry.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/impl/SessionRegistry.java similarity index 86% rename from inspector/src/main/java/cern/molr/inspector/domain/impl/SessionRegistry.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/impl/SessionRegistry.java index eb10f65..a85b723 100644 --- a/inspector/src/main/java/cern/molr/inspector/domain/impl/SessionRegistry.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/domain/impl/SessionRegistry.java @@ -1,15 +1,15 @@ -package cern.molr.inspector.domain.impl; +package io.molr.mole.jdebug.spawner.domain.impl; import cern.molr.commons.registry.impl.ObservableInMemoryEntriesRegistry; -import cern.molr.inspector.controller.StatefulJdiController; -import cern.molr.inspector.domain.Session; +import io.molr.mole.jdebug.spawner.controller.StatefulJdiController; +import io.molr.mole.jdebug.spawner.domain.Session; import java.util.Set; import java.util.stream.Collectors; /** * {@link ObservableInMemoryEntriesRegistry} for {@link Session}s that subscribe to the - * {@link cern.molr.inspector.controller.StatefulJdiController} of its entries + * {@link StatefulJdiController} of its entries * @author mgalilee */ public class SessionRegistry extends ObservableInMemoryEntriesRegistry implements StatefulJdiController.JdiStateObserver { diff --git a/inspector/src/main/java/cern/molr/inspector/entry/EntryListener.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryListener.java similarity index 96% rename from inspector/src/main/java/cern/molr/inspector/entry/EntryListener.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryListener.java index fd4ab64..8e0a56e 100644 --- a/inspector/src/main/java/cern/molr/inspector/entry/EntryListener.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryListener.java @@ -4,7 +4,7 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.entry; +package io.molr.mole.jdebug.spawner.entry; /** * Handles callbacks from a JVM running an entry. This class is unique for each entry encountered in the running diff --git a/inspector/src/main/java/cern/molr/inspector/entry/EntryState.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryState.java similarity index 96% rename from inspector/src/main/java/cern/molr/inspector/entry/EntryState.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryState.java index 8fb2817..8742b16 100644 --- a/inspector/src/main/java/cern/molr/inspector/entry/EntryState.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryState.java @@ -4,7 +4,7 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.entry; +package io.molr.mole.jdebug.spawner.entry; /** * The state of a single entry running in JDI (Java Debugging Interface). An entry is defined as a single method in diff --git a/inspector/src/main/java/cern/molr/inspector/entry/EntryStateBuilder.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryStateBuilder.java similarity index 89% rename from inspector/src/main/java/cern/molr/inspector/entry/EntryStateBuilder.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryStateBuilder.java index ede26c6..ab633fb 100644 --- a/inspector/src/main/java/cern/molr/inspector/entry/EntryStateBuilder.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryStateBuilder.java @@ -1,6 +1,6 @@ -package cern.molr.inspector.entry; +package io.molr.mole.jdebug.spawner.entry; -import cern.molr.inspector.entry.impl.EntryStateImpl; +import io.molr.mole.jdebug.spawner.entry.impl.EntryStateImpl; import com.sun.jdi.AbsentInformationException; import com.sun.jdi.Location; import org.slf4j.Logger; diff --git a/inspector/src/main/java/cern/molr/inspector/entry/impl/EntryStateImpl.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/impl/EntryStateImpl.java similarity index 95% rename from inspector/src/main/java/cern/molr/inspector/entry/impl/EntryStateImpl.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/impl/EntryStateImpl.java index cca0319..e234a47 100644 --- a/inspector/src/main/java/cern/molr/inspector/entry/impl/EntryStateImpl.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/impl/EntryStateImpl.java @@ -4,9 +4,9 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.entry.impl; +package io.molr.mole.jdebug.spawner.entry.impl; -import cern.molr.inspector.entry.EntryState; +import io.molr.mole.jdebug.spawner.entry.EntryState; /** * An immutable implementation of an {@link EntryState}. diff --git a/inspector/src/main/java/io/molr/mole/jdebug/spawner/examples/HelloWorld.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/examples/HelloWorld.java new file mode 100644 index 0000000..82bd169 --- /dev/null +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/examples/HelloWorld.java @@ -0,0 +1,41 @@ +package io.molr.mole.jdebug.spawner.examples; + +//A test class you can use for simple debugging scripts. +public class HelloWorld { + private String helloTo; + + public HelloWorld() { + this("World"); + } + + public HelloWorld(String helloTo) { + this.helloTo = helloTo; + } + + public HelloWorld(String helloTo, String helloAnd) { + this(helloTo + " and " + helloAnd); + } + + public String sayHello() { + return "Hello, " + helloTo; + } + + public void setHelloTo(String helloTo) { + this.helloTo = helloTo; + } + + public static void main(String[] args) { + HelloWorld hello; + + hello = new HelloWorld(); + System.out.println(hello.sayHello()); + System.out.println(hello.sayHello()); + hello.setHelloTo("Barney"); + System.out.println(hello.sayHello()); + System.out.println(hello.sayHello()); + + hello = new HelloWorld("Fred", "Wilma"); + System.out.println(hello.sayHello()); + System.out.println(hello.sayHello()); + } +} diff --git a/inspector/src/main/java/io/molr/mole/jdebug/spawner/examples/HelloWorldExample.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/examples/HelloWorldExample.java new file mode 100644 index 0000000..0938c27 --- /dev/null +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/examples/HelloWorldExample.java @@ -0,0 +1,27 @@ +package io.molr.mole.jdebug.spawner.examples; + +import org.jdiscript.JDIScript; +import org.jdiscript.util.VMLauncher; + +import static org.jdiscript.util.Utils.unchecked; + +public class HelloWorldExample { + + public static void main(final String[] args) { + String OPTIONS = "-cp " + System.getProperty("java.class.path"); + + String MAIN = HelloWorld.class.getName(); + + System.out.println(OPTIONS); + + JDIScript j = new JDIScript(new VMLauncher(OPTIONS, MAIN).start()); + + j.onFieldAccess(MAIN, "helloTo", e -> { + j.onStepInto(e.thread(), j.once(se -> { + unchecked(() -> e.object().setValue(e.field(), j.vm().mirrorOf("JDIScript!"))); + })); + }); + + j.run(); + } +} diff --git a/inspector/src/main/java/cern/molr/inspector/jdi/ClassInstantiationListener.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/jdi/ClassInstantiationListener.java similarity index 98% rename from inspector/src/main/java/cern/molr/inspector/jdi/ClassInstantiationListener.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/jdi/ClassInstantiationListener.java index c1ee750..fe95f01 100644 --- a/inspector/src/main/java/cern/molr/inspector/jdi/ClassInstantiationListener.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/jdi/ClassInstantiationListener.java @@ -4,7 +4,7 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.jdi; +package io.molr.mole.jdebug.spawner.jdi; import com.sun.jdi.ClassType; import com.sun.jdi.ReferenceType; diff --git a/inspector/src/main/java/cern/molr/inspector/jdi/LocationRange.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/jdi/LocationRange.java similarity index 98% rename from inspector/src/main/java/cern/molr/inspector/jdi/LocationRange.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/jdi/LocationRange.java index 4943734..195e2d5 100644 --- a/inspector/src/main/java/cern/molr/inspector/jdi/LocationRange.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/jdi/LocationRange.java @@ -4,7 +4,7 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.jdi; +package io.molr.mole.jdebug.spawner.jdi; import com.sun.jdi.AbsentInformationException; import com.sun.jdi.Location; diff --git a/inspector/src/main/java/cern/molr/inspector/jdi/ThreadState.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/jdi/ThreadState.java similarity index 93% rename from inspector/src/main/java/cern/molr/inspector/jdi/ThreadState.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/jdi/ThreadState.java index 56ada94..43f60b2 100644 --- a/inspector/src/main/java/cern/molr/inspector/jdi/ThreadState.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/jdi/ThreadState.java @@ -4,9 +4,10 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.jdi; +package io.molr.mole.jdebug.spawner.jdi; import com.sun.jdi.Location; +import io.molr.mole.jdebug.spawner.entry.EntryState; /** * An immutable state for a {@link com.sun.jdi.ThreadReference}. @@ -37,14 +38,14 @@ public Location getCurrentLocation() { } /** - * @return The starting position for the task in this state (see {@link cern.molr.inspector.entry.EntryState}). + * @return The starting position for the task in this state (see {@link EntryState}). */ public Location getStartLocation() { return inspectableRange.getStart(); } /** - * @return The ending position for the task in this state (see {@link cern.molr.inspector.entry.EntryState}). + * @return The ending position for the task in this state (see {@link EntryState}). */ public Location getEndLocation() { return inspectableRange.getEnd(); diff --git a/inspector/src/main/java/cern/molr/inspector/package-info.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/package-info.java similarity index 87% rename from inspector/src/main/java/cern/molr/inspector/package-info.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/package-info.java index 8ed86cd..c8c2af0 100644 --- a/inspector/src/main/java/cern/molr/inspector/package-info.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/package-info.java @@ -16,8 +16,8 @@ *

* Instead of inspecting full files or classes, this implementation restricts the inspection to methods. A method * registered for inspection is defined as an entry. Whenever such an entry is reached, the running VM is - * suspended, and only continued when the {@link cern.molr.inspector.controller.JdiController} is requested to + * suspended, and only continued when the {@link io.molr.mole.jdebug.spawner.controller.JdiController} is requested to * resume the execution. The execution of the entry ends when the end of the method is reached. *

*/ -package cern.molr.inspector; \ No newline at end of file +package io.molr.mole.jdebug.spawner; \ No newline at end of file diff --git a/inspector/src/main/java/cern/molr/inspector/remote/EntryListenerMethod.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/EntryListenerMethod.java similarity index 61% rename from inspector/src/main/java/cern/molr/inspector/remote/EntryListenerMethod.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/EntryListenerMethod.java index adc22cd..9ac1f69 100644 --- a/inspector/src/main/java/cern/molr/inspector/remote/EntryListenerMethod.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/EntryListenerMethod.java @@ -1,6 +1,6 @@ -package cern.molr.inspector.remote; +package io.molr.mole.jdebug.spawner.remote; -import cern.molr.inspector.entry.EntryListener; +import io.molr.mole.jdebug.spawner.entry.EntryListener; /** * A list of available methods in {@link EntryListener}s. diff --git a/inspector/src/main/java/cern/molr/inspector/remote/EntryListenerReader.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/EntryListenerReader.java similarity index 95% rename from inspector/src/main/java/cern/molr/inspector/remote/EntryListenerReader.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/EntryListenerReader.java index 123e7fb..137feb1 100644 --- a/inspector/src/main/java/cern/molr/inspector/remote/EntryListenerReader.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/EntryListenerReader.java @@ -1,8 +1,8 @@ -package cern.molr.inspector.remote; +package io.molr.mole.jdebug.spawner.remote; -import cern.molr.inspector.entry.EntryListener; -import cern.molr.inspector.entry.EntryState; -import cern.molr.inspector.entry.impl.EntryStateImpl; +import io.molr.mole.jdebug.spawner.entry.EntryListener; +import io.molr.mole.jdebug.spawner.entry.EntryState; +import io.molr.mole.jdebug.spawner.entry.impl.EntryStateImpl; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import org.slf4j.Logger; diff --git a/inspector/src/main/java/cern/molr/inspector/remote/EntryListenerWriter.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/EntryListenerWriter.java similarity index 88% rename from inspector/src/main/java/cern/molr/inspector/remote/EntryListenerWriter.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/EntryListenerWriter.java index 31c37a3..e9edcdf 100644 --- a/inspector/src/main/java/cern/molr/inspector/remote/EntryListenerWriter.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/EntryListenerWriter.java @@ -1,7 +1,7 @@ -package cern.molr.inspector.remote; +package io.molr.mole.jdebug.spawner.remote; -import cern.molr.inspector.entry.EntryListener; -import cern.molr.inspector.entry.EntryState; +import io.molr.mole.jdebug.spawner.entry.EntryListener; +import io.molr.mole.jdebug.spawner.entry.EntryState; import com.google.gson.Gson; import java.io.PrintWriter; diff --git a/inspector/src/main/java/cern/molr/inspector/remote/JdiControllerCommand.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/JdiControllerCommand.java similarity index 59% rename from inspector/src/main/java/cern/molr/inspector/remote/JdiControllerCommand.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/JdiControllerCommand.java index c57fc81..b608131 100644 --- a/inspector/src/main/java/cern/molr/inspector/remote/JdiControllerCommand.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/JdiControllerCommand.java @@ -1,6 +1,6 @@ -package cern.molr.inspector.remote; +package io.molr.mole.jdebug.spawner.remote; -import cern.molr.inspector.controller.JdiController; +import io.molr.mole.jdebug.spawner.controller.JdiController; /** * Commands which can be issued to the {@link JdiController} remotely. diff --git a/inspector/src/main/java/cern/molr/inspector/remote/JdiControllerReader.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/JdiControllerReader.java similarity index 96% rename from inspector/src/main/java/cern/molr/inspector/remote/JdiControllerReader.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/JdiControllerReader.java index c891b48..5c03b86 100644 --- a/inspector/src/main/java/cern/molr/inspector/remote/JdiControllerReader.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/JdiControllerReader.java @@ -1,6 +1,6 @@ -package cern.molr.inspector.remote; +package io.molr.mole.jdebug.spawner.remote; -import cern.molr.inspector.controller.JdiController; +import io.molr.mole.jdebug.spawner.controller.JdiController; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/inspector/src/main/java/cern/molr/inspector/remote/JdiControllerWriter.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/JdiControllerWriter.java similarity index 90% rename from inspector/src/main/java/cern/molr/inspector/remote/JdiControllerWriter.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/JdiControllerWriter.java index 2cb51e8..a538988 100644 --- a/inspector/src/main/java/cern/molr/inspector/remote/JdiControllerWriter.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/JdiControllerWriter.java @@ -1,6 +1,6 @@ -package cern.molr.inspector.remote; +package io.molr.mole.jdebug.spawner.remote; -import cern.molr.inspector.controller.JdiController; +import io.molr.mole.jdebug.spawner.controller.JdiController; import java.io.PrintWriter; diff --git a/inspector/src/main/java/cern/molr/inspector/remote/RemoteReader.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/RemoteReader.java similarity index 98% rename from inspector/src/main/java/cern/molr/inspector/remote/RemoteReader.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/RemoteReader.java index 19baa3c..972403a 100644 --- a/inspector/src/main/java/cern/molr/inspector/remote/RemoteReader.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/RemoteReader.java @@ -1,4 +1,4 @@ -package cern.molr.inspector.remote; +package io.molr.mole.jdebug.spawner.remote; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/inspector/src/main/java/cern/molr/inspector/remote/SystemMain.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/SystemMain.java similarity index 66% rename from inspector/src/main/java/cern/molr/inspector/remote/SystemMain.java rename to inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/SystemMain.java index ff5132f..00fdf54 100644 --- a/inspector/src/main/java/cern/molr/inspector/remote/SystemMain.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/remote/SystemMain.java @@ -4,15 +4,15 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.remote; - -import cern.molr.commons.domain.Mission; -import cern.molr.inspector.controller.JdiController; -import cern.molr.inspector.controller.JdiControllerImpl; -import cern.molr.inspector.domain.InstantiationRequest; -import cern.molr.inspector.domain.impl.InstantiationRequestImpl; -import cern.molr.inspector.entry.EntryListener; -import cern.molr.inspector.json.MissionTypeAdapter; +package io.molr.mole.jdebug.spawner.remote; + +import cern.molr.commons.domain.JdiMission; +import io.molr.mole.jdebug.spawner.controller.JdiController; +import io.molr.mole.jdebug.spawner.controller.JdiControllerImpl; +import io.molr.mole.jdebug.spawner.domain.InstantiationRequest; +import io.molr.mole.jdebug.spawner.domain.impl.InstantiationRequestImpl; +import io.molr.mole.jdebug.spawner.entry.EntryListener; +import io.molr.mole.jdebug.spawner.json.MissionTypeAdapter; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.sun.jdi.connect.IllegalConnectorArgumentsException; @@ -29,7 +29,7 @@ public class SystemMain implements Closeable { private static final Gson GSON = new GsonBuilder() - .registerTypeAdapter(Mission.class, new MissionTypeAdapter().nullSafe()) + .registerTypeAdapter(JdiMission.class, new MissionTypeAdapter().nullSafe()) .create(); private final ExecutorService executor = Executors.newSingleThreadExecutor(); @@ -66,28 +66,30 @@ public static void main(String[] args) throws Exception { System.err.println("Expected 1 argument, but received " + args.length); } else { InstantiationRequest request = GSON.fromJson(args[0], InstantiationRequestImpl.class); - PrintWriter outputWriter = new PrintWriter(System.out); - EntryListenerWriter writer = new EntryListenerWriter(outputWriter); - - JdiControllerImpl controller = startJdi(request, writer); - new JdiControllerReader(new BufferedReader(new InputStreamReader(System.in)), controller); - new SystemMain(controller, writer); + create(request); } } - private static JdiControllerImpl startJdi(InstantiationRequest request, EntryListener entryListener) throws Exception { + public static SystemMain create(InstantiationRequest request) { + PrintWriter outputWriter = new PrintWriter(System.out); + EntryListenerWriter writer = new EntryListenerWriter(outputWriter); + + JdiControllerImpl controller = startJdi(request, writer); + new JdiControllerReader(new BufferedReader(new InputStreamReader(System.in)), controller); + return new SystemMain(controller, writer); + } + + public static JdiControllerImpl startJdi(InstantiationRequest request, EntryListener entryListener) { try { return JdiControllerImpl.builder() .setClassPath(request.getClassPath()) .setEntryListener(entryListener) - .setMission(request.getMission()) + .setJdiMission(request.getJdiMission()) .build(); } catch (IllegalConnectorArgumentsException e) { - System.err.println("Bad connection parameters " + request + " when starting JDI:" + e); - throw e; + throw new RuntimeException("Bad connection parameters " + request + " when starting JDI.", e); } catch (Exception e) { - System.err.println("Failure when starting JDI instance:" + e); - throw e; + throw new RuntimeException("Failure when starting JDI instance.", e); } } diff --git a/inspector/src/test/java/io/molr/mole/jdebug/spawner/DebugMoleSpawnerTest.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/DebugMoleSpawnerTest.java new file mode 100644 index 0000000..36f947e --- /dev/null +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/DebugMoleSpawnerTest.java @@ -0,0 +1,35 @@ +package io.molr.mole.jdebug.spawner; + +import cern.molr.commons.domain.JdiMission; +import io.molr.mole.jdebug.domain.Missions; +import io.molr.mole.jdebug.spawner.controller.StatefulJdiController; +import org.assertj.core.api.Assertions; +import org.junit.Test; + +import java.util.concurrent.CountDownLatch; + +public class DebugMoleSpawnerTest { + + @Test + public void firstSpawning() throws InterruptedException { + JdiMission jdiMission = Missions.ofMain(PrimitiveTestingMain.class); + Assertions.assertThat(jdiMission).isNotNull(); + + StatefulJdiController controller = JdiMissionSpawner.start(jdiMission); + Assertions.assertThat(controller).isNotNull(); + + + CountDownLatch finished = new CountDownLatch(1); + while (true) { + Thread.sleep(1000); + if (controller.isDead()) { + break; + } + controller.stepForward(); + } + + //finished.await(); + + } + +} diff --git a/inspector/src/test/java/io/molr/mole/jdebug/spawner/HelloWorldExampleTest.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/HelloWorldExampleTest.java new file mode 100644 index 0000000..6fdcd56 --- /dev/null +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/HelloWorldExampleTest.java @@ -0,0 +1,16 @@ +package io.molr.mole.jdebug.spawner; + +import io.molr.mole.jdebug.spawner.examples.HelloWorldExample; +import org.junit.Test; + +public class HelloWorldExampleTest { + + @Test(timeout = 2000) + public void mainDoesNotTimeOut() { + /* If this test times out, there is likely a classpath problem. For example, one source of not being able to launch the VM was of haveing invalid classpath entried. + For example, in the original jdiscript documentation it is recommended to have something like: "compile files("${System.properties['java.home']}/../lib/tools.jar")" + as a dependecy in build.gradle. However, it looks like this is not needed in java 11 anymore and even causes the launch to fail ...*/ + HelloWorldExample.main(new String[]{}); + } + +} diff --git a/inspector/src/test/java/cern/molr/inspector/JdiControllerImplIntegrationTest.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/JdiControllerImplIntegrationTest.java similarity index 96% rename from inspector/src/test/java/cern/molr/inspector/JdiControllerImplIntegrationTest.java rename to inspector/src/test/java/io/molr/mole/jdebug/spawner/JdiControllerImplIntegrationTest.java index 0ff3186..841c909 100644 --- a/inspector/src/test/java/cern/molr/inspector/JdiControllerImplIntegrationTest.java +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/JdiControllerImplIntegrationTest.java @@ -3,7 +3,7 @@ * verbatim in the file “COPYING“. In applying this licence, CERN does not waive the privileges and immunities granted * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector; +package io.molr.mole.jdebug.spawner; import org.junit.Test; diff --git a/inspector/src/test/java/io/molr/mole/jdebug/spawner/PrimitiveTestingMain.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/PrimitiveTestingMain.java new file mode 100644 index 0000000..d997809 --- /dev/null +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/PrimitiveTestingMain.java @@ -0,0 +1,10 @@ +package io.molr.mole.jdebug.spawner; + +public class PrimitiveTestingMain { + + public static void main(String... args) { + System.out.println("Step 1"); + System.out.println("Step 2"); + System.out.println("Step 3"); + } +} diff --git a/inspector/src/test/java/cern/molr/inspector/SystemMainTest.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/SystemMainTest.java similarity index 61% rename from inspector/src/test/java/cern/molr/inspector/SystemMainTest.java rename to inspector/src/test/java/io/molr/mole/jdebug/spawner/SystemMainTest.java index 1c0528f..3ea2bc8 100644 --- a/inspector/src/test/java/cern/molr/inspector/SystemMainTest.java +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/SystemMainTest.java @@ -3,13 +3,13 @@ * verbatim in the file “COPYING“. In applying this licence, CERN does not waive the privileges and immunities granted * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector; +package io.molr.mole.jdebug.spawner; -import cern.molr.commons.domain.Mission; -import cern.molr.inspector.domain.InstantiationRequest; -import cern.molr.inspector.domain.impl.InstantiationRequestImpl; -import cern.molr.inspector.json.MissionTypeAdapter; -import cern.molr.inspector.remote.SystemMain; +import cern.molr.commons.domain.JdiMission; +import io.molr.mole.jdebug.spawner.domain.InstantiationRequest; +import io.molr.mole.jdebug.spawner.domain.impl.InstantiationRequestImpl; +import io.molr.mole.jdebug.spawner.json.MissionTypeAdapter; +import io.molr.mole.jdebug.spawner.remote.SystemMain; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.junit.Before; @@ -24,14 +24,14 @@ public class SystemMainTest { private static final Gson GSON = new GsonBuilder() - .registerTypeAdapter(Mission.class, new MissionTypeAdapter().nullSafe()) + .registerTypeAdapter(JdiMission.class, new MissionTypeAdapter().nullSafe()) .create(); - private Mission mockedMission; + private JdiMission mockedJdiMission; @Before public void setup() { - mockedMission = mock(Mission.class); + mockedJdiMission = mock(JdiMission.class); } @Test @@ -40,10 +40,10 @@ public void canStartAnInspector() throws Exception { final String inspectionClass = "cern.jarrace.inspector.remote.CliMain"; final String mainClass = "cern.jarrace.inspector.remote.CliMain"; final List entryPoints = Collections.singletonList("main"); - when(mockedMission.getMoleClassName()).thenReturn(mainClass); - when(mockedMission.getMissionContentClassName()).thenReturn(inspectionClass); - when(mockedMission.getTasksNames()).thenReturn(entryPoints); - final InstantiationRequest request = new InstantiationRequestImpl(classPath, mockedMission); + when(mockedJdiMission.getMoleClassName()).thenReturn(mainClass); + when(mockedJdiMission.getMissionContentClassName()).thenReturn(inspectionClass); + when(mockedJdiMission.getTasksNames()).thenReturn(entryPoints); + final InstantiationRequest request = new InstantiationRequestImpl(classPath, mockedJdiMission); SystemMain.main(new String[]{GSON.toJson(request)}); } diff --git a/inspector/src/test/java/cern/molr/inspector/TestInspectable.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/TestInspectable.java similarity index 94% rename from inspector/src/test/java/cern/molr/inspector/TestInspectable.java rename to inspector/src/test/java/io/molr/mole/jdebug/spawner/TestInspectable.java index e436dae..1587d8d 100644 --- a/inspector/src/test/java/cern/molr/inspector/TestInspectable.java +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/TestInspectable.java @@ -4,7 +4,7 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector; +package io.molr.mole.jdebug.spawner; /** * A class that can be used for testing the use of an inspectable class. diff --git a/inspector/src/test/java/cern/molr/inspector/jdi/ClassInstantiationListenerTest.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/jdi/ClassInstantiationListenerTest.java similarity index 89% rename from inspector/src/test/java/cern/molr/inspector/jdi/ClassInstantiationListenerTest.java rename to inspector/src/test/java/io/molr/mole/jdebug/spawner/jdi/ClassInstantiationListenerTest.java index 63336b2..fa56171 100644 --- a/inspector/src/test/java/cern/molr/inspector/jdi/ClassInstantiationListenerTest.java +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/jdi/ClassInstantiationListenerTest.java @@ -4,13 +4,13 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.jdi; +package io.molr.mole.jdebug.spawner.jdi; import com.sun.jdi.ClassType; import com.sun.jdi.event.ClassPrepareEvent; import org.junit.Before; import org.junit.Test; -import org.mockito.Matchers; +import org.mockito.ArgumentMatchers; import java.util.function.Consumer; @@ -58,14 +58,14 @@ public void canCallCallback() { public void canNotFailIfReferenceTypeIsNull() { when(mockedEvent.referenceType()).thenReturn(null); listener.classPrepare(mockedEvent); - verify(mockedConsumer, never()).accept(Matchers.any(ClassType.class)); + verify(mockedConsumer, never()).accept(ArgumentMatchers.any(ClassType.class)); } @Test public void canNotCallCallbackIfClassTypeIsNotSameAsClass() { when(mockedType.name()).thenReturn("I don't exist"); listener.classPrepare(mockedEvent); - verify(mockedConsumer, never()).accept(Matchers.any(ClassType.class)); + verify(mockedConsumer, never()).accept(ArgumentMatchers.any(ClassType.class)); } } diff --git a/inspector/src/test/java/cern/molr/inspector/jdi/LocationRangeTest.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/jdi/LocationRangeTest.java similarity index 98% rename from inspector/src/test/java/cern/molr/inspector/jdi/LocationRangeTest.java rename to inspector/src/test/java/io/molr/mole/jdebug/spawner/jdi/LocationRangeTest.java index f38ab80..12a74df 100644 --- a/inspector/src/test/java/cern/molr/inspector/jdi/LocationRangeTest.java +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/jdi/LocationRangeTest.java @@ -4,7 +4,7 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.jdi; +package io.molr.mole.jdebug.spawner.jdi; import com.sun.jdi.AbsentInformationException; import com.sun.jdi.Location; diff --git a/inspector/src/test/java/cern/molr/inspector/jdi/ThreadStateTest.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/jdi/ThreadStateTest.java similarity index 98% rename from inspector/src/test/java/cern/molr/inspector/jdi/ThreadStateTest.java rename to inspector/src/test/java/io/molr/mole/jdebug/spawner/jdi/ThreadStateTest.java index bc05a00..84f5ab8 100644 --- a/inspector/src/test/java/cern/molr/inspector/jdi/ThreadStateTest.java +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/jdi/ThreadStateTest.java @@ -4,7 +4,7 @@ * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ -package cern.molr.inspector.jdi; +package io.molr.mole.jdebug.spawner.jdi; import com.sun.jdi.Location; import org.junit.Before; diff --git a/inspector/src/test/java/cern/molr/inspector/remote/EntryListenerReaderWriterTest.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/remote/EntryListenerReaderWriterTest.java similarity index 88% rename from inspector/src/test/java/cern/molr/inspector/remote/EntryListenerReaderWriterTest.java rename to inspector/src/test/java/io/molr/mole/jdebug/spawner/remote/EntryListenerReaderWriterTest.java index 4be0669..c067ac2 100644 --- a/inspector/src/test/java/cern/molr/inspector/remote/EntryListenerReaderWriterTest.java +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/remote/EntryListenerReaderWriterTest.java @@ -1,8 +1,8 @@ -package cern.molr.inspector.remote; +package io.molr.mole.jdebug.spawner.remote; -import cern.molr.inspector.entry.EntryListener; -import cern.molr.inspector.entry.EntryState; -import cern.molr.inspector.entry.impl.EntryStateImpl; +import io.molr.mole.jdebug.spawner.entry.EntryListener; +import io.molr.mole.jdebug.spawner.entry.EntryState; +import io.molr.mole.jdebug.spawner.entry.impl.EntryStateImpl; import org.junit.Before; import org.junit.Test; diff --git a/inspector/src/test/java/cern/molr/inspector/remote/JdiControllerReaderWriterTest.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/remote/JdiControllerReaderWriterTest.java similarity index 92% rename from inspector/src/test/java/cern/molr/inspector/remote/JdiControllerReaderWriterTest.java rename to inspector/src/test/java/io/molr/mole/jdebug/spawner/remote/JdiControllerReaderWriterTest.java index 8f52570..071f252 100644 --- a/inspector/src/test/java/cern/molr/inspector/remote/JdiControllerReaderWriterTest.java +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/remote/JdiControllerReaderWriterTest.java @@ -1,6 +1,6 @@ -package cern.molr.inspector.remote; +package io.molr.mole.jdebug.spawner.remote; -import cern.molr.inspector.controller.JdiController; +import io.molr.mole.jdebug.spawner.controller.JdiController; import org.junit.Before; import org.junit.Test; diff --git a/inspector/src/test/java/cern/molr/inspector/remote/RemoteReaderTest.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/remote/RemoteReaderTest.java similarity index 96% rename from inspector/src/test/java/cern/molr/inspector/remote/RemoteReaderTest.java rename to inspector/src/test/java/io/molr/mole/jdebug/spawner/remote/RemoteReaderTest.java index 17dabf7..8681e9c 100644 --- a/inspector/src/test/java/cern/molr/inspector/remote/RemoteReaderTest.java +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/remote/RemoteReaderTest.java @@ -1,4 +1,4 @@ -package cern.molr.inspector.remote; +package io.molr.mole.jdebug.spawner.remote; import org.junit.Before; import org.junit.Test; diff --git a/mole/build.gradle b/mole/build.gradle index 183a664..50dd50c 100644 --- a/mole/build.gradle +++ b/mole/build.gradle @@ -9,8 +9,5 @@ version = "0.1" dependencies { compile 'org.codehaus.jackson:jackson-mapper-asl:1.9.13' compile 'org.springframework:spring-context:4.2.4.RELEASE' - - - compile files("${System.properties['java.home']}/../lib/tools.jar") - compile group: 'junit', name: 'junit', version: '4.11' + compile group: 'junit', name: 'junit', version: '4.11' } \ No newline at end of file From 9ec575d6c70ec2e66f0cad7b29381b960e32ef3c Mon Sep 17 00:00:00 2001 From: kaifox Date: Mon, 10 Feb 2020 23:39:11 +0100 Subject: [PATCH 2/4] first working version!!!! --- inspector/build.gradle | 8 +- .../{Missions.java => JdiMissions.java} | 26 ++- .../mole/jdebug/mole/JdiMissionExecutor.java | 155 ++++++++++++++++++ .../mole/jdebug/mole/JdiMissionStructure.java | 60 +++++++ .../io/molr/mole/jdebug/mole/JdiMole.java | 66 ++++++++ .../mole/jdebug/sourcecode/SourceCodes.java | 29 ++++ .../mole/jdebug/spawner/DebugMoleSpawner.java | 14 +- .../spawner/controller/JdiControllerImpl.java | 4 +- .../LocalDelegatingStatefulJdiController.java | 2 + .../spawner/entry/EntryStateBuilder.java | 3 +- .../molr/mole/jdebug/JdiMoleDemoServer.java | 41 +++++ .../molr/mole/jdebug/LandTheFalconMain.java | 13 ++ .../jdebug/sourcecode/SourceCodesTest.java | 26 +++ .../jdebug/spawner/DebugMoleSpawnerTest.java | 4 +- .../jdebug/spawner/PrimitiveTestingMain.java | 3 + 15 files changed, 433 insertions(+), 21 deletions(-) rename inspector/src/main/java/io/molr/mole/jdebug/domain/{Missions.java => JdiMissions.java} (68%) create mode 100644 inspector/src/main/java/io/molr/mole/jdebug/mole/JdiMissionExecutor.java create mode 100644 inspector/src/main/java/io/molr/mole/jdebug/mole/JdiMissionStructure.java create mode 100644 inspector/src/main/java/io/molr/mole/jdebug/mole/JdiMole.java create mode 100644 inspector/src/main/java/io/molr/mole/jdebug/sourcecode/SourceCodes.java create mode 100644 inspector/src/test/java/io/molr/mole/jdebug/JdiMoleDemoServer.java create mode 100644 inspector/src/test/java/io/molr/mole/jdebug/LandTheFalconMain.java create mode 100644 inspector/src/test/java/io/molr/mole/jdebug/sourcecode/SourceCodesTest.java diff --git a/inspector/build.gradle b/inspector/build.gradle index 67755c1..7fc315c 100644 --- a/inspector/build.gradle +++ b/inspector/build.gradle @@ -11,14 +11,20 @@ dependencies { compile group: "com.google.code.gson", name: "gson", version: "2.+" compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.+' + compile group: "io.molr", name: "molr-mole-core", version: "+" + compile group: "com.google.guava", name: "guava", version: "28.2-jre" + implementation 'org.jdiscript:jdiscript:0.9.0' testCompile group: 'junit', name: 'junit', version: '4.11' testCompile group: 'org.mockito', name: 'mockito-core', version: '3.+' testCompile group: 'org.assertj', name: 'assertj-core', version: assertJVersion + testCompile group: "io.molr", name: "molr-mole-server", version: "+" + + } javadoc { - // enabled = false + // enabled = false } \ No newline at end of file diff --git a/inspector/src/main/java/io/molr/mole/jdebug/domain/Missions.java b/inspector/src/main/java/io/molr/mole/jdebug/domain/JdiMissions.java similarity index 68% rename from inspector/src/main/java/io/molr/mole/jdebug/domain/Missions.java rename to inspector/src/main/java/io/molr/mole/jdebug/domain/JdiMissions.java index c5aa35e..c2458a2 100644 --- a/inspector/src/main/java/io/molr/mole/jdebug/domain/Missions.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/domain/JdiMissions.java @@ -2,15 +2,19 @@ import cern.molr.commons.domain.JdiMission; import cern.molr.commons.domain.impl.MissionImpl; +import com.google.common.collect.ImmutableMap; +import io.molr.commons.domain.Mission; +import io.molr.mole.jdebug.mole.JdiMissionStructure; +import io.molr.mole.jdebug.sourcecode.SourceCodes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.Collections; -import java.util.Optional; +import java.util.*; import static java.util.Objects.requireNonNull; +import static java.util.stream.Collectors.toSet; /** * Utility class that provides factory methods for mission domain objects. @@ -18,11 +22,11 @@ *

* These objects are then later fed into a {@link io.molr.mole.jdebug.spawner.controller.JdiControllerImpl} for instantiation. */ -public final class Missions { +public final class JdiMissions { - private final static Logger LOGGER = LoggerFactory.getLogger(Missions.class); + private final static Logger LOGGER = LoggerFactory.getLogger(JdiMissions.class); - private Missions() { + private JdiMissions() { /* Only static methods */ } @@ -54,4 +58,16 @@ private static Optional searchByName(Class mainClass) { } + public static Map createMap(Set availableMissions) { + return availableMissions.stream().collect(ImmutableMap.toImmutableMap(m -> molrMissionOf(m), m -> m)); + } + + public static Set molrMissionsFrom(Set availableMissions) { + return availableMissions.stream().map(m -> molrMissionOf(m)).collect(toSet()); + } + + public static Mission molrMissionOf(JdiMission m) { + return new Mission(m.getMissionContentClassName()); + } + } diff --git a/inspector/src/main/java/io/molr/mole/jdebug/mole/JdiMissionExecutor.java b/inspector/src/main/java/io/molr/mole/jdebug/mole/JdiMissionExecutor.java new file mode 100644 index 0000000..7c11483 --- /dev/null +++ b/inspector/src/main/java/io/molr/mole/jdebug/mole/JdiMissionExecutor.java @@ -0,0 +1,155 @@ +package io.molr.mole.jdebug.mole; + +import io.molr.commons.domain.*; +import io.molr.mole.core.tree.MissionExecutor; +import io.molr.mole.jdebug.spawner.JdiMissionSpawner; +import io.molr.mole.jdebug.spawner.controller.StatefulJdiController; +import io.molr.mole.jdebug.spawner.entry.EntryState; +import reactor.core.publisher.Flux; +import reactor.core.publisher.ReplayProcessor; +import reactor.core.scheduler.Schedulers; + +import java.util.Collections; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicReference; + +import static io.molr.commons.domain.Result.FAILED; +import static io.molr.commons.domain.Result.SUCCESS; +import static io.molr.commons.domain.RunState.*; +import static io.molr.commons.domain.StrandCommand.STEP_OVER; + +public class JdiMissionExecutor implements MissionExecutor { + + private final Strand onlyStrand = Strand.ofId("0"); + + private final JdiMissionStructure structure; + + private final ReplayProcessor stateSink = ReplayProcessor.cacheLast(); + private final Flux stateStream = stateSink.publishOn(Schedulers.newSingle("Jdi MissionState publisher")); + + + /* variables for mission state ...*/ + private final AtomicReference actualBlock = new AtomicReference<>(); + private final AtomicReference onlyStrandRunState = new AtomicReference<>(UNDEFINED); + private final ConcurrentHashMap blockRunStates = new ConcurrentHashMap(); + private final ConcurrentHashMap blockResults = new ConcurrentHashMap<>(); + + + private final StatefulJdiController jdiController; + + public JdiMissionExecutor(JdiMissionStructure structure) { + this.structure = structure; + this.jdiController = JdiMissionSpawner.start(structure.jdiMission()); + + jdiController.addObserver(new StatefulJdiController.JdiStateObserver() { + @Override + public void death() { + Block actual = actualBlock.getAndSet(null); + if (actual != null) { + blockRunStates.put(actual, FINISHED); + /* How to define success? */ + blockResults.put(actual, SUCCESS); + } + onlyStrandRunState.set(FINISHED); + publishState(Collections.emptySet()); + /* TODO: What to do here? */ + } + + @Override + public void entryStateChanged() { + /*TODO: watch out for concurrency!?*/ + Optional state = jdiController.getLastKnownState(); + boolean dead = jdiController.isDead(); + + Optional block = state.map(e -> structure.blockForLine(e.getLine())); + updateBlock(block); + + publishState(allowedCommands(state, dead)); + } + }); + } + + + private void publishState(Set allowedCommands) { + MissionState.Builder builder = MissionState.builder(Result.summaryOf(blockResults.values()))// + .add(onlyStrand, onlyStrandRunState.get(), actualBlock.get(), allowedCommands); + blockResults.entrySet().forEach(e -> builder.blockResult(e.getKey(), e.getValue())); + blockRunStates.entrySet().forEach(e -> builder.blockRunState(e.getKey(), e.getValue())); + stateSink.onNext(builder.build()); + } + + private Set allowedCommands(Optional state, boolean dead) { + if (state.isPresent() && !dead) { + return Collections.singleton(STEP_OVER); + } else { + return Collections.emptySet(); + } + } + + private void updateBlock(Optional block) { + /* XXX Concurrency by far not solved!!! However, this might have to be done on lower levels ... to be seen.*/ + if (block.isPresent()) { + Block newBlock = block.get(); + + Block oldBlock = actualBlock.getAndSet(newBlock); + if (oldBlock != null) { + blockRunStates.put(oldBlock, FINISHED); + /* How to define success? */ + blockResults.put(oldBlock, SUCCESS); + } + blockRunStates.put(newBlock, PAUSED); + onlyStrandRunState.set(PAUSED); + } else { + Block actual = actualBlock.get(); + if (actual != null) { + blockRunStates.put(actual, RUNNING); + onlyStrandRunState.set(RUNNING); + } + } + } + + @Override + public Flux states() { + return stateStream; + } + + + @Override + public void instruct(Strand strand, StrandCommand command) { + /* This for sure will also change in the future ... multithreading etc... for the moment it has to do ;-)*/ + if (!onlyStrand.equals(strand)) { + throw new IllegalArgumentException(strand + " is not a valid strand of this mission."); + } + instruct(command); + } + + private void instruct(StrandCommand command) { + if (STEP_OVER.equals(command)) { + jdiController.stepForward(); + } else { + throw new IllegalArgumentException("Command '" + command + "' is not allowed! Only '" + STEP_OVER + "' is allowed for the moment!"); + } + } + + @Override + public void instructRoot(StrandCommand command) { + instructRoot(command); + } + + + @Override + public Flux outputs() { + /* For the moment no outputs provided ... to be seen how we handle this. (e.g. std out??) */ + return Flux.never(); + } + + @Override + public Flux representations() { + /* Representation does not change for the moment ... however, most probably it will in the future ;-) + (e.g. step into methods ?)*/ + return Flux.just(structure.representation()); + } + +} diff --git a/inspector/src/main/java/io/molr/mole/jdebug/mole/JdiMissionStructure.java b/inspector/src/main/java/io/molr/mole/jdebug/mole/JdiMissionStructure.java new file mode 100644 index 0000000..f4db27e --- /dev/null +++ b/inspector/src/main/java/io/molr/mole/jdebug/mole/JdiMissionStructure.java @@ -0,0 +1,60 @@ +package io.molr.mole.jdebug.mole; + +import cern.molr.commons.domain.JdiMission; +import com.google.common.collect.ImmutableMap; +import io.molr.commons.domain.Block; +import io.molr.commons.domain.ImmutableMissionRepresentation; +import io.molr.commons.domain.MissionRepresentation; +import io.molr.mole.jdebug.sourcecode.SourceCodes; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; + +public class JdiMissionStructure { + + private final JdiMission jdiMission; + private final MissionRepresentation representation; + private final Map numberedLines; + + public JdiMissionStructure(JdiMission jdiMission, MissionRepresentation representation, Map numberedLines) { + this.jdiMission = jdiMission; + this.representation = representation; + this.numberedLines = numberedLines; + } + + public static final JdiMissionStructure from(JdiMission mission) { + String className = mission.getMissionContentClassName(); + List codeLines = SourceCodes.sourceLinesFor(className); + return fromLines(mission, codeLines); + } + + public MissionRepresentation representation() { + return this.representation; + } + + public static JdiMissionStructure fromLines(JdiMission mission, List lines) { + AtomicLong nextId = new AtomicLong(0); + + ImmutableMap.Builder mapBuilder = ImmutableMap.builder(); + + Block root = Block.idAndText("" + nextId.getAndIncrement(), mission.getMissionContentClassName()); + ImmutableMissionRepresentation.Builder builder = ImmutableMissionRepresentation.builder(root); + for (int i = 0; i < lines.size(); i++) { + Block block = Block.idAndText("" + nextId.getAndIncrement(), lines.get(i)); + builder.parentToChild(root, block); + /* line numbers start with one ... so we have to do +1 here*/ + mapBuilder.put(i + 1, block); + } + + return new JdiMissionStructure(mission, builder.build(), mapBuilder.build()); + } + + public Block blockForLine(int line) { + return numberedLines.get(line); + } + + public JdiMission jdiMission() { + return jdiMission; + } +} diff --git a/inspector/src/main/java/io/molr/mole/jdebug/mole/JdiMole.java b/inspector/src/main/java/io/molr/mole/jdebug/mole/JdiMole.java new file mode 100644 index 0000000..5101d7b --- /dev/null +++ b/inspector/src/main/java/io/molr/mole/jdebug/mole/JdiMole.java @@ -0,0 +1,66 @@ +package io.molr.mole.jdebug.mole; + +import cern.molr.commons.domain.JdiMission; +import com.google.common.collect.ImmutableMap; +import io.molr.commons.domain.*; +import io.molr.mole.core.tree.AbstractJavaMole; +import io.molr.mole.core.tree.MissionExecutor; +import io.molr.mole.jdebug.domain.JdiMissions; + +import java.util.Map; +import java.util.Set; + + +/** + * This is currently a very brute-force version of a mole which in the ends shall be able to execute (almost) arbitrary + * java code and controlling it using the java debugging interfacce (jdi). This is the first try in resurrecting + * the molr code from the early days. It was tried to use quite a top layer of abstraction from the old code, to see if/how + * we can profit most from the existing code. It might well be that some of these layers are still not required and + * rather add complexity ... but this has to be seen in later steps. There is still quite some work ahead: + *
    + *
  • First of all it seems that there has to be looked quite a lot into the concurrent behaviour of the debugging. + * It seems that the old classes are not fully clean on this
  • + *
  • A lot of classes to throw away and refactor to one project in this repo.
  • + *
  • State handling is currently a big hack on the top layers ... Most probably jdi can do better
  • + *
  • Currently only stepping is supported (no pause or resum) ... to be seen if this can be done better + * (and still keep track of the cursor)
  • + *
  • Multithreading .... completely not tackled
  • + *
  • loops will come back (as we saw already in python)
  • + *
  • step into!?
  • + *
  • How to get output?
  • + *
  • parameters?
  • + *
  • cleanup of the running java stuff!
  • + *
  • ... and more to see ;-)
  • + *
+ * In summary: Just a first step ... + */ +public class JdiMole extends AbstractJavaMole { + + private final Map missions; + private final Map structures; + + public JdiMole(Set availableMissions) { + super(JdiMissions.molrMissionsFrom(availableMissions)); + this.missions = JdiMissions.createMap(availableMissions); + this.structures = createStructures(availableMissions); + } + + private static Map createStructures(Set availableMissions) { + return availableMissions.stream().collect(ImmutableMap.toImmutableMap(JdiMissions::molrMissionOf, JdiMissionStructure::from)); + } + + @Override + protected MissionExecutor executorFor(Mission mission, Map params) { + return new JdiMissionExecutor(JdiMissionStructure.from(missions.get(mission))); + } + + @Override + protected MissionRepresentation missionRepresentationOf(Mission mission) { + return structures.get(mission).representation(); + } + + @Override + protected MissionParameterDescription missionParameterDescriptionOf(Mission mission) { + return MissionParameterDescription.empty(); + } +} diff --git a/inspector/src/main/java/io/molr/mole/jdebug/sourcecode/SourceCodes.java b/inspector/src/main/java/io/molr/mole/jdebug/sourcecode/SourceCodes.java new file mode 100644 index 0000000..84c9e78 --- /dev/null +++ b/inspector/src/main/java/io/molr/mole/jdebug/sourcecode/SourceCodes.java @@ -0,0 +1,29 @@ +package io.molr.mole.jdebug.sourcecode; + +import cern.molr.commons.annotations.Source; + +import java.util.Arrays; +import java.util.Base64; +import java.util.List; + +public final class SourceCodes { + + private SourceCodes() { + /* only static methods */ + } + + public static String sourceCodeFor(String classname) { + try { + Source classSource = (Source) Class.forName(classname + "Source").newInstance(); + String base64Source = classSource.base64Value(); + return new String(Base64.getDecoder().decode(base64Source)); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | ClassCastException exception) { + throw new RuntimeException("Could not load source code for class '" + classname + "'.", exception); + } + } + + public static List sourceLinesFor(String className) { + String sourceCodeText = sourceCodeFor(className); + return Arrays.asList(sourceCodeText.split("\n")); + } +} diff --git a/inspector/src/main/java/io/molr/mole/jdebug/spawner/DebugMoleSpawner.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/DebugMoleSpawner.java index 01008dd..1f2428b 100644 --- a/inspector/src/main/java/io/molr/mole/jdebug/spawner/DebugMoleSpawner.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/DebugMoleSpawner.java @@ -1,7 +1,7 @@ package io.molr.mole.jdebug.spawner; -import cern.molr.commons.annotations.Source; import cern.molr.commons.domain.JdiMission; +import io.molr.mole.jdebug.sourcecode.SourceCodes; import io.molr.mole.jdebug.spawner.controller.StatefulJdiControllerImpl; import io.molr.mole.jdebug.spawner.domain.InstantiationRequest; import io.molr.mole.jdebug.spawner.domain.Session; @@ -18,7 +18,6 @@ import org.slf4j.LoggerFactory; import java.io.*; -import java.util.Base64; import java.util.concurrent.Executors; /** @@ -34,15 +33,8 @@ public class DebugMoleSpawner implements MoleSpawner, SourceFetcher { .registerTypeAdapter(JdiMission.class, new MissionTypeAdapter().nullSafe()) .create(); - public String getSource(String classname) { - try { - Source classSource = (Source) Class.forName(classname + "Source").newInstance(); - String base64Source = classSource.base64Value(); - return new String(Base64.getDecoder().decode(base64Source)); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | ClassCastException exception) { - LOGGER.error("Could not load source code for class", classname, exception); - return ""; - } + public String getSource(String classname) { + return SourceCodes.sourceCodeFor(classname); } @Override diff --git a/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiControllerImpl.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiControllerImpl.java index 9ebd9c9..30cc24b 100644 --- a/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiControllerImpl.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/JdiControllerImpl.java @@ -52,7 +52,9 @@ public static Builder builder() { @Override public void close() { entryRegistry.unregister(); - onClose.run(); + if (onClose != null) { + onClose.run(); + } } public InputStream getProcessError() { diff --git a/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/LocalDelegatingStatefulJdiController.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/LocalDelegatingStatefulJdiController.java index 8843cbc..3853d09 100644 --- a/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/LocalDelegatingStatefulJdiController.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/LocalDelegatingStatefulJdiController.java @@ -8,6 +8,7 @@ import java.util.HashSet; import java.util.Optional; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; import static java.util.Objects.requireNonNull; @@ -43,6 +44,7 @@ public void setDelegate(JdiController jdiController) { @Override public void onLocationChange(EntryState state) { LOGGER.info("onLocationChange {}", state); + System.out.println(missionContentClassName); if (missionContentClassName.equals(state.getClassName())) { LOGGER.info("in class {}, stepping available", missionContentClassName); lastKnownState = Optional.of(state); diff --git a/inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryStateBuilder.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryStateBuilder.java index ab633fb..06e5978 100644 --- a/inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryStateBuilder.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/entry/EntryStateBuilder.java @@ -17,7 +17,8 @@ public class EntryStateBuilder { public static Optional ofLocation(Location location) { try { - final String className = location.sourcePath(); + location.sourceName(); + final String className = location.declaringType().name(); final String methodName = location.method().name(); final EntryState entryState = new EntryStateImpl(className, methodName, location.lineNumber()); return Optional.of(entryState); diff --git a/inspector/src/test/java/io/molr/mole/jdebug/JdiMoleDemoServer.java b/inspector/src/test/java/io/molr/mole/jdebug/JdiMoleDemoServer.java new file mode 100644 index 0000000..99ce080 --- /dev/null +++ b/inspector/src/test/java/io/molr/mole/jdebug/JdiMoleDemoServer.java @@ -0,0 +1,41 @@ +package io.molr.mole.jdebug; + +import cern.molr.commons.domain.JdiMission; +import io.molr.mole.core.api.Mole; +import io.molr.mole.jdebug.domain.JdiMissions; +import io.molr.mole.jdebug.mole.JdiMole; +import io.molr.mole.server.conf.SingleMoleRestServiceConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import java.util.Set; + +@SpringBootApplication +@Import(SingleMoleRestServiceConfiguration.class) +public class JdiMoleDemoServer { + + private static ApplicationContext ctx; + + @Bean + public Mole mole(Set jdiMissions) { + return new JdiMole(jdiMissions); + } + + + @Bean + public JdiMission landTheFalcon() { + return JdiMissions.ofMain(LandTheFalconMain.class); + } + + + public static void main(String... args) { + if (System.getProperty("server.port") == null) { + System.setProperty("server.port", "8800"); + } + SpringApplication.run(JdiMoleDemoServer.class); + } +} diff --git a/inspector/src/test/java/io/molr/mole/jdebug/LandTheFalconMain.java b/inspector/src/test/java/io/molr/mole/jdebug/LandTheFalconMain.java new file mode 100644 index 0000000..148e33d --- /dev/null +++ b/inspector/src/test/java/io/molr/mole/jdebug/LandTheFalconMain.java @@ -0,0 +1,13 @@ +package io.molr.mole.jdebug; + +import cern.molr.commons.annotations.SourceMe; + +@SourceMe +public class LandTheFalconMain { + + public static void main(String... args) { + System.out.println("Locate target"); + System.out.println("entry burn"); + System.out.println("final burn"); + } +} diff --git a/inspector/src/test/java/io/molr/mole/jdebug/sourcecode/SourceCodesTest.java b/inspector/src/test/java/io/molr/mole/jdebug/sourcecode/SourceCodesTest.java new file mode 100644 index 0000000..6499747 --- /dev/null +++ b/inspector/src/test/java/io/molr/mole/jdebug/sourcecode/SourceCodesTest.java @@ -0,0 +1,26 @@ +package io.molr.mole.jdebug.sourcecode; + +import io.molr.mole.jdebug.spawner.PrimitiveTestingMain; +import org.assertj.core.api.Assertions; +import org.junit.Test; + +import static io.molr.mole.jdebug.sourcecode.SourceCodes.sourceCodeFor; +import static org.assertj.core.api.Assertions.assertThat; + +public class SourceCodesTest { + + @Test + public void sourceCodeIsAvailable() { + assertThat(sourceCodeFor(classname())).isNotBlank(); + } + + @Test + public void sourceCodeLineAreAvailable() { + assertThat(SourceCodes.sourceLinesFor(classname()).size()).isGreaterThan(5); + } + + private String classname() { + return PrimitiveTestingMain.class.getName(); + } + +} diff --git a/inspector/src/test/java/io/molr/mole/jdebug/spawner/DebugMoleSpawnerTest.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/DebugMoleSpawnerTest.java index 36f947e..78d0012 100644 --- a/inspector/src/test/java/io/molr/mole/jdebug/spawner/DebugMoleSpawnerTest.java +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/DebugMoleSpawnerTest.java @@ -1,7 +1,7 @@ package io.molr.mole.jdebug.spawner; import cern.molr.commons.domain.JdiMission; -import io.molr.mole.jdebug.domain.Missions; +import io.molr.mole.jdebug.domain.JdiMissions; import io.molr.mole.jdebug.spawner.controller.StatefulJdiController; import org.assertj.core.api.Assertions; import org.junit.Test; @@ -12,7 +12,7 @@ public class DebugMoleSpawnerTest { @Test public void firstSpawning() throws InterruptedException { - JdiMission jdiMission = Missions.ofMain(PrimitiveTestingMain.class); + JdiMission jdiMission = JdiMissions.ofMain(PrimitiveTestingMain.class); Assertions.assertThat(jdiMission).isNotNull(); StatefulJdiController controller = JdiMissionSpawner.start(jdiMission); diff --git a/inspector/src/test/java/io/molr/mole/jdebug/spawner/PrimitiveTestingMain.java b/inspector/src/test/java/io/molr/mole/jdebug/spawner/PrimitiveTestingMain.java index d997809..d462a71 100644 --- a/inspector/src/test/java/io/molr/mole/jdebug/spawner/PrimitiveTestingMain.java +++ b/inspector/src/test/java/io/molr/mole/jdebug/spawner/PrimitiveTestingMain.java @@ -1,5 +1,8 @@ package io.molr.mole.jdebug.spawner; +import cern.molr.commons.annotations.SourceMe; + +@SourceMe public class PrimitiveTestingMain { public static void main(String... args) { From c4888b833c0f4db44dbcec95f33df048fa10b6b6 Mon Sep 17 00:00:00 2001 From: kaifox Date: Mon, 10 Feb 2020 23:43:09 +0100 Subject: [PATCH 3/4] fixed javadoc --- .../src/main/java/io/molr/mole/jdebug/domain/JdiMissions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inspector/src/main/java/io/molr/mole/jdebug/domain/JdiMissions.java b/inspector/src/main/java/io/molr/mole/jdebug/domain/JdiMissions.java index c2458a2..a504464 100644 --- a/inspector/src/main/java/io/molr/mole/jdebug/domain/JdiMissions.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/domain/JdiMissions.java @@ -19,7 +19,7 @@ /** * Utility class that provides factory methods for mission domain objects. * These domain objects describe the class to execute and the entry points. - *

+ *

* These objects are then later fed into a {@link io.molr.mole.jdebug.spawner.controller.JdiControllerImpl} for instantiation. */ public final class JdiMissions { From 9b7440f12bf9984fd01cb579116d98f2b82d4140 Mon Sep 17 00:00:00 2001 From: kaifox Date: Mon, 10 Feb 2020 23:46:50 +0100 Subject: [PATCH 4/4] cleanup --- .../controller/LocalDelegatingStatefulJdiController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/LocalDelegatingStatefulJdiController.java b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/LocalDelegatingStatefulJdiController.java index 3853d09..12f404e 100644 --- a/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/LocalDelegatingStatefulJdiController.java +++ b/inspector/src/main/java/io/molr/mole/jdebug/spawner/controller/LocalDelegatingStatefulJdiController.java @@ -15,7 +15,7 @@ /** * This is first try of a wrapper implementation around a normal JdiController. This is far from beautiful, * but the first goal is to get some useful debugging running, without all the text-based communication. - *

+ *

* There is some ugliness: As the listener has to be set to the builder of {@link JdiControllerImpl} ... the instance * of this stateful controller is first created and then the delegate is set to it. As mentioned: Far from final ;-) *