diff --git a/plugins/org.eclipse.payara.tools.ui/src/org/eclipse/payara/tools/ui/micro/MicroProjectTab.java b/plugins/org.eclipse.payara.tools.ui/src/org/eclipse/payara/tools/ui/micro/MicroProjectTab.java index a0292215..47f15d1f 100644 --- a/plugins/org.eclipse.payara.tools.ui/src/org/eclipse/payara/tools/ui/micro/MicroProjectTab.java +++ b/plugins/org.eclipse.payara.tools.ui/src/org/eclipse/payara/tools/ui/micro/MicroProjectTab.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2020 Payara Foundation + * Copyright (c) 2020-2021 Payara Foundation * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 @@ -19,6 +19,7 @@ import java.io.FileNotFoundException; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.eclipse.core.resources.IProject; @@ -47,9 +48,12 @@ import static org.eclipse.payara.tools.micro.MicroConstants.ATTR_MICRO_VERSION; import static org.eclipse.payara.tools.micro.MicroConstants.ATTR_BUILD_ARTIFACT; import static org.eclipse.payara.tools.micro.MicroConstants.ATTR_DEBUG_PORT; +import static org.eclipse.payara.tools.micro.MicroConstants.ATTR_RELOAD_ARTIFACT; import static org.eclipse.payara.tools.micro.MicroConstants.WAR_BUILD_ARTIFACT; import static org.eclipse.payara.tools.micro.MicroConstants.EXPLODED_WAR_BUILD_ARTIFACT; import static org.eclipse.payara.tools.micro.MicroConstants.UBER_JAR_BUILD_ARTIFACT; +import static org.eclipse.payara.tools.micro.MicroConstants.AUTO_DEPLOY_ARTIFACT; +import static org.eclipse.payara.tools.micro.MicroConstants.HOT_DEPLOY_ARTIFACT; import org.eclipse.payara.tools.micro.BuildTool; import org.eclipse.payara.tools.ui.micro.wizards.Messages; import org.eclipse.swt.SWT; @@ -62,186 +66,197 @@ public class MicroProjectTab extends AbstractJavaMainTab { - private Text contextPathText, microVersionText, debugPortText; - private Combo buildArtifactCombo; - - @Override - public void createControl(Composite parent) { - Composite mainComposite = SWTFactory.createComposite(parent, 1, 1, GridData.FILL_HORIZONTAL); - createProjectEditor(mainComposite); - - Group group = SWTFactory.createGroup(mainComposite, Messages.contextPathComponentLabel, 1, 1, GridData.FILL_HORIZONTAL); - contextPathText = SWTFactory.createSingleText(group, 1); - contextPathText.addModifyListener(getDefaultListener()); - - group = SWTFactory.createGroup(mainComposite, Messages.microVersionComponentLabel, 1, 1, GridData.FILL_HORIZONTAL); - microVersionText = SWTFactory.createSingleText(group, 1); - microVersionText.addModifyListener(getDefaultListener()); - - group = SWTFactory.createGroup(mainComposite, Messages.buildArtifactComponentLabel, 1, 1, GridData.FILL_HORIZONTAL); - buildArtifactCombo = SWTFactory.createCombo( - group, SWT.READ_ONLY, 1, - new String[]{EMPTY_STRING, WAR_BUILD_ARTIFACT, EXPLODED_WAR_BUILD_ARTIFACT, UBER_JAR_BUILD_ARTIFACT} - ); - buildArtifactCombo.addModifyListener(getDefaultListener()); - - group = SWTFactory.createGroup(mainComposite, Messages.debugPortComponentLabel, 1, 1, GridData.FILL_HORIZONTAL); - debugPortText = SWTFactory.createSingleText(group, 1); - debugPortText.addModifyListener(getDefaultListener()); - - setControl(mainComposite); - } - - @Override - public void initializeFrom(ILaunchConfiguration config) { - updateMicroSettingsFromConfig(config); - super.initializeFrom(config); - } - - private void updateMicroSettingsFromConfig(ILaunchConfiguration config) { - String contextPath = EMPTY_STRING; - try { - contextPath = config.getAttribute(ATTR_CONTEXT_PATH, contextPath); - } catch (CoreException ce) { - setErrorMessage(ce.getStatus().getMessage()); - } - contextPathText.setText(contextPath); - - String microVersion = EMPTY_STRING; - try { - microVersion = config.getAttribute(ATTR_MICRO_VERSION, microVersion); - } catch (CoreException ce) { - setErrorMessage(ce.getStatus().getMessage()); - } - microVersionText.setText(microVersion); - - String buildType = EMPTY_STRING; - try { - buildType = config.getAttribute(ATTR_BUILD_ARTIFACT, microVersion); - } catch (CoreException ce) { - setErrorMessage(ce.getStatus().getMessage()); - } - buildArtifactCombo.setText(buildType); - - String debugPort = String.valueOf(DEFAULT_DEBUG_PORT); - try { - debugPort = config.getAttribute(ATTR_DEBUG_PORT, debugPort); - } catch (CoreException ce) { - setErrorMessage(ce.getStatus().getMessage()); - } - debugPortText.setText(debugPort); - } - - public Image getImage() { - return MavenImages.IMG_LAUNCH_MAIN; - } - - @Override - public boolean isValid(ILaunchConfiguration config) { - setErrorMessage(null); - setMessage(null); - String name = fProjText.getText().trim(); - if (name.isEmpty()) { - setErrorMessage(LauncherMessages.JavaMainTab_missing_project); - return false; - } - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - IStatus status = workspace.validateName(name, IResource.PROJECT); - if (!status.isOK()) { - setErrorMessage(NLS.bind(LauncherMessages.JavaMainTab_19, new String[]{status.getMessage()})); - return false; - } - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name); - if (!project.exists()) { - setErrorMessage(NLS.bind(LauncherMessages.JavaMainTab_20, new String[]{name})); - return false; - } - if (!project.isOpen()) { - setErrorMessage(NLS.bind(LauncherMessages.JavaMainTab_21, new String[]{name})); - return false; - } - try { + private Text contextPathText, microVersionText, debugPortText; + private Combo buildArtifactCombo, reloadArtifactCombo; + + @Override + public void createControl(Composite parent) { + Composite mainComposite = SWTFactory.createComposite(parent, 1, 1, GridData.FILL_HORIZONTAL); + createProjectEditor(mainComposite); + + Group group = SWTFactory.createGroup(mainComposite, Messages.contextPathComponentLabel, 1, 1, + GridData.FILL_HORIZONTAL); + contextPathText = SWTFactory.createSingleText(group, 1); + contextPathText.addModifyListener(getDefaultListener()); + + group = SWTFactory.createGroup(mainComposite, Messages.microVersionComponentLabel, 1, 1, + GridData.FILL_HORIZONTAL); + microVersionText = SWTFactory.createSingleText(group, 1); + microVersionText.addModifyListener(getDefaultListener()); + + group = SWTFactory.createGroup(mainComposite, Messages.buildArtifactComponentLabel, 1, 1, + GridData.FILL_HORIZONTAL); + buildArtifactCombo = SWTFactory.createCombo(group, SWT.READ_ONLY, 1, new String[] { EMPTY_STRING, + WAR_BUILD_ARTIFACT, EXPLODED_WAR_BUILD_ARTIFACT, UBER_JAR_BUILD_ARTIFACT }); + buildArtifactCombo.addModifyListener(getDefaultListener()); + + group = SWTFactory.createGroup(mainComposite, Messages.debugPortComponentLabel, 1, 1, GridData.FILL_HORIZONTAL); + debugPortText = SWTFactory.createSingleText(group, 1); + debugPortText.addModifyListener(getDefaultListener()); + + group = SWTFactory.createGroup(mainComposite, Messages.reloadArtifactComponentLabel, 1, 1, + GridData.FILL_HORIZONTAL); + reloadArtifactCombo = SWTFactory.createCombo(group, SWT.READ_ONLY, 1, + new String[] { EMPTY_STRING, AUTO_DEPLOY_ARTIFACT, HOT_DEPLOY_ARTIFACT }); + reloadArtifactCombo.addModifyListener(getDefaultListener()); + reloadArtifactCombo.setToolTipText(Messages.reloadArtifactComponentTooltip); + + setControl(mainComposite); + } + + @Override + public void initializeFrom(ILaunchConfiguration config) { + updateMicroSettingsFromConfig(config); + super.initializeFrom(config); + } + + private void updateMicroSettingsFromConfig(ILaunchConfiguration config) { + String contextPath = EMPTY_STRING; + try { + contextPath = config.getAttribute(ATTR_CONTEXT_PATH, contextPath); + } catch (CoreException ce) { + setErrorMessage(ce.getStatus().getMessage()); + } + contextPathText.setText(contextPath); + + String microVersion = EMPTY_STRING; + try { + microVersion = config.getAttribute(ATTR_MICRO_VERSION, microVersion); + } catch (CoreException ce) { + setErrorMessage(ce.getStatus().getMessage()); + } + microVersionText.setText(microVersion); + + String buildType = EMPTY_STRING; + try { + buildType = config.getAttribute(ATTR_BUILD_ARTIFACT, buildType); + } catch (CoreException ce) { + setErrorMessage(ce.getStatus().getMessage()); + } + buildArtifactCombo.setText(buildType); + + String debugPort = String.valueOf(DEFAULT_DEBUG_PORT); + try { + debugPort = config.getAttribute(ATTR_DEBUG_PORT, debugPort); + } catch (CoreException ce) { + setErrorMessage(ce.getStatus().getMessage()); + } + debugPortText.setText(debugPort); + + String reloadType = EMPTY_STRING; + try { + reloadType = config.getAttribute(ATTR_RELOAD_ARTIFACT, reloadType); + } catch (CoreException ce) { + setErrorMessage(ce.getStatus().getMessage()); + } + reloadArtifactCombo.setText(reloadType); + } + + public Image getImage() { + return MavenImages.IMG_LAUNCH_MAIN; + } + + @Override + public boolean isValid(ILaunchConfiguration config) { + setErrorMessage(null); + setMessage(null); + String name = fProjText.getText().trim(); + if (name.isEmpty()) { + setErrorMessage(LauncherMessages.JavaMainTab_missing_project); + return false; + } + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IStatus status = workspace.validateName(name, IResource.PROJECT); + if (!status.isOK()) { + setErrorMessage(NLS.bind(LauncherMessages.JavaMainTab_19, new String[] { status.getMessage() })); + return false; + } + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name); + if (!project.exists()) { + setErrorMessage(NLS.bind(LauncherMessages.JavaMainTab_20, new String[] { name })); + return false; + } + if (!project.isOpen()) { + setErrorMessage(NLS.bind(LauncherMessages.JavaMainTab_21, new String[] { name })); + return false; + } + try { BuildTool.getToolSupport(project).getExecutableHome(); } catch (FileNotFoundException e) { setErrorMessage(e.getMessage()); - return false; + return false; } - return true; - } - - @Override - public void setDefaults(ILaunchConfigurationWorkingCopy config) { - IJavaElement javaElement = getContext(); - if (javaElement != null) { - initializeJavaProject(javaElement, config); - } else { - config.setAttribute(ATTR_PROJECT_NAME, EMPTY_STRING); - } - config.setAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, "org.eclipse.payara.tools.micro.processFactory"); - } - - @Override - public void performApply(ILaunchConfigurationWorkingCopy config) { - String projectName = fProjText.getText().trim(); - try { - if (!projectName.isEmpty()) { - IProject project = getWorkspaceRoot().getProject(projectName); - if (!project.exists()) { - setErrorMessage(NLS.bind(LauncherMessages.JavaMainTab_20, new String[]{projectName})); - return; - } - BuildTool buildTool = BuildTool.getToolSupport(project); - if (buildTool == null) { - setErrorMessage(Messages.projectBuildNotFound); - throw new IllegalStateException(Messages.projectBuildNotFound); - } - - String debugPort = debugPortText.getText(); - if (debugPort.isEmpty()) { - debugPort = String.valueOf(DEFAULT_DEBUG_PORT); - } - config.setAttribute(ATTR_CONTEXT_PATH, contextPathText.getText()); - config.setAttribute(ATTR_MICRO_VERSION, microVersionText.getText()); - config.setAttribute(ATTR_BUILD_ARTIFACT, buildArtifactCombo.getText()); - config.setAttribute(ATTR_DEBUG_PORT, debugPort); - config.setAttribute(ATTR_PROJECT_NAME, projectName); - config.setAttribute(ATTR_WORKING_DIRECTORY, project.getLocation().toOSString()); - config.setAttribute(ATTR_BUILD_SCOPE, "${projects:" + project.getName() + "}"); - Map env = config.getAttribute(ATTR_ENVIRONMENT_VARIABLES, Collections.emptyMap()); - if (env.isEmpty()) { - config.setAttribute(ATTR_ENVIRONMENT_VARIABLES, env = new HashMap<>()); - } - if (!env.containsKey(JAVA_HOME_ENV_VAR)) { - env.put(JAVA_HOME_ENV_VAR, getJavaHome(project)); - } - config.setAttribute(ATTR_LOCATION, buildTool.getExecutableHome()); - config.setAttribute( - ATTR_TOOL_ARGUMENTS, - buildTool.getStartCommand( - contextPathText.getText(), - microVersionText.getText(), - buildArtifactCombo.getText(), - debugPortText.getText().isEmpty() ? String.valueOf(DEFAULT_DEBUG_PORT) : debugPortText.getText() - ) - ); - - } - } catch (FileNotFoundException ex) { - setErrorMessage(ex.getMessage()); - } catch (Exception ex) { - throw new IllegalStateException(ex); - } - } - - public static String getJavaHome(IProject project) throws CoreException { - IJavaProject javaProject = JavaCore.create(project); - IVMInstall install = JavaRuntime.getVMInstall(javaProject); - return install.getInstallLocation().getAbsolutePath(); - } - - @Override - public String getName() { - return Messages.microProjectTabTitle; - } + return true; + } + + @Override + public void setDefaults(ILaunchConfigurationWorkingCopy config) { + IJavaElement javaElement = getContext(); + if (javaElement != null) { + initializeJavaProject(javaElement, config); + } else { + config.setAttribute(ATTR_PROJECT_NAME, EMPTY_STRING); + } + config.setAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, "org.eclipse.payara.tools.micro.processFactory"); + } + + @Override + public void performApply(ILaunchConfigurationWorkingCopy config) { + String projectName = fProjText.getText().trim(); + try { + if (!projectName.isEmpty()) { + IProject project = getWorkspaceRoot().getProject(projectName); + if (!project.exists()) { + setErrorMessage(NLS.bind(LauncherMessages.JavaMainTab_20, new String[] { projectName })); + return; + } + BuildTool buildTool = BuildTool.getToolSupport(project); + if (buildTool == null) { + setErrorMessage(Messages.projectBuildNotFound); + throw new IllegalStateException(Messages.projectBuildNotFound); + } + + String debugPort = debugPortText.getText(); + if (debugPort.isEmpty()) { + debugPort = String.valueOf(DEFAULT_DEBUG_PORT); + } + config.setAttribute(ATTR_CONTEXT_PATH, contextPathText.getText()); + config.setAttribute(ATTR_MICRO_VERSION, microVersionText.getText()); + config.setAttribute(ATTR_BUILD_ARTIFACT, buildArtifactCombo.getText()); + config.setAttribute(ATTR_DEBUG_PORT, debugPort); + config.setAttribute(ATTR_RELOAD_ARTIFACT, reloadArtifactCombo.getText()); + config.setAttribute(ATTR_PROJECT_NAME, projectName); + config.setAttribute(ATTR_WORKING_DIRECTORY, project.getLocation().toOSString()); + config.setAttribute(ATTR_BUILD_SCOPE, "${projects:" + project.getName() + "}"); + Map env = config.getAttribute(ATTR_ENVIRONMENT_VARIABLES, Collections.emptyMap()); + if (env.isEmpty()) { + config.setAttribute(ATTR_ENVIRONMENT_VARIABLES, env = new HashMap<>()); + } + if (!env.containsKey(JAVA_HOME_ENV_VAR)) { + env.put(JAVA_HOME_ENV_VAR, getJavaHome(project)); + } + config.setAttribute(ATTR_LOCATION, buildTool.getExecutableHome()); + boolean hotDeploy = HOT_DEPLOY_ARTIFACT.equals(reloadArtifactCombo.getText()); + List startCmd = buildTool.getStartCommand(contextPathText.getText(), microVersionText.getText(), + buildArtifactCombo.getText(), debugPort, hotDeploy); + config.setAttribute(ATTR_TOOL_ARGUMENTS, String.join(" ", startCmd)); + } + } catch (FileNotFoundException ex) { + setErrorMessage(ex.getMessage()); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + + public static String getJavaHome(IProject project) throws CoreException { + IJavaProject javaProject = JavaCore.create(project); + IVMInstall install = JavaRuntime.getVMInstall(javaProject); + return install.getInstallLocation().getAbsolutePath(); + } + + @Override + public String getName() { + return Messages.microProjectTabTitle; + } } diff --git a/plugins/org.eclipse.payara.tools.ui/src/org/eclipse/payara/tools/ui/micro/wizards/Messages.java b/plugins/org.eclipse.payara.tools.ui/src/org/eclipse/payara/tools/ui/micro/wizards/Messages.java index abcba413..0e9da3ed 100644 --- a/plugins/org.eclipse.payara.tools.ui/src/org/eclipse/payara/tools/ui/micro/wizards/Messages.java +++ b/plugins/org.eclipse.payara.tools.ui/src/org/eclipse/payara/tools/ui/micro/wizards/Messages.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2020 Payara Foundation + * Copyright (c) 2020-2021 Payara Foundation * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 @@ -48,5 +48,7 @@ public class Messages extends org.eclipse.osgi.util.NLS { public static String projectBuildNotFound; public static String buildArtifactComponentLabel; public static String debugPortComponentLabel; + public static String reloadArtifactComponentLabel; + public static String reloadArtifactComponentTooltip; } diff --git a/plugins/org.eclipse.payara.tools.ui/src/org/eclipse/payara/tools/ui/micro/wizards/Messages.properties b/plugins/org.eclipse.payara.tools.ui/src/org/eclipse/payara/tools/ui/micro/wizards/Messages.properties index 84eaa174..9c56f707 100644 --- a/plugins/org.eclipse.payara.tools.ui/src/org/eclipse/payara/tools/ui/micro/wizards/Messages.properties +++ b/plugins/org.eclipse.payara.tools.ui/src/org/eclipse/payara/tools/ui/micro/wizards/Messages.properties @@ -26,4 +26,6 @@ microVersionValidationMessage=Enter the Payara Micro version microProjectTabTitle=Micro Project projectBuildNotFound=Project build type not detected buildArtifactComponentLabel=Build Artifact -debugPortComponentLabel=Debug Port \ No newline at end of file +debugPortComponentLabel=Debug Port +reloadArtifactComponentLabel=Reload Artifact on save +reloadArtifactComponentTooltip=Reload Artifact feature is only available for Exploded War \ No newline at end of file diff --git a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/Messages.java b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/Messages.java index 8608d632..83369204 100644 --- a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/Messages.java +++ b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/Messages.java @@ -8,7 +8,7 @@ ******************************************************************************/ /****************************************************************************** - * Copyright (c) 2018 Payara Foundation + * Copyright (c) 2018-2021 Payara Foundation * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -95,4 +95,10 @@ public class Messages extends NLS { public static String wrongUsernamePassword; public static String badGateway; public static String domainNotMatch; + + public static String errorInTerminatingMicro; + public static String errorInInitializingMicroWatcher; + public static String errorInReloadingMicro; + + } diff --git a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/Messages.properties b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/Messages.properties index 1c515b61..085c0b2b 100644 --- a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/Messages.properties +++ b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/Messages.properties @@ -73,3 +73,7 @@ checkVpnOrProxy=Please also check for antivirus software, firewall configuration wrongUsernamePassword=Wrong user name or password. badGateway=The response code BAD GATEWAY was returned. Please check your proxy settings. domainNotMatch=A Payara Server may be running on the same admin or HTTP port, but with a different root installation. + +errorInTerminatingMicro=Error occurred while terminating payara-micro +errorInInitializingMicroWatcher=Payara Micro watcher task initialization failed +errorInReloadingMicro=Payara Micro reload action failed diff --git a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/BuildTool.java b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/BuildTool.java index da9cb3e0..4aa65c88 100644 --- a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/BuildTool.java +++ b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/BuildTool.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2020 Payara Foundation + * Copyright (c) 2020-2021 Payara Foundation * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 @@ -10,36 +10,42 @@ package org.eclipse.payara.tools.micro; import java.io.FileNotFoundException; +import java.util.List; + import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; public abstract class BuildTool { - protected final IProject project; - - public static final String MAVEN_NATURE = "org.eclipse.m2e.core.maven2Nature"; - - protected BuildTool(IProject project) { - this.project = project; - } - - public abstract String getExecutableHome() throws FileNotFoundException; - - public abstract String getStartCommand(String contextPath, String microVersion, String buildType, String debugPort); - - public static boolean isMavenProject(IProject project) { - try { - return project.hasNature(MAVEN_NATURE); - } catch (CoreException e) { - return false; - } - } - - public static BuildTool getToolSupport(IProject project) { - if (isMavenProject(project)) { - return new MavenBuildTool(project); - } else { - return new GradleBuildTool(project); - } - } + protected final IProject project; + + public static final String MAVEN_NATURE = "org.eclipse.m2e.core.maven2Nature"; + + protected BuildTool(IProject project) { + this.project = project; + } + + public abstract String getExecutableHome() throws FileNotFoundException; + + public abstract List getStartCommand(String contextPath, String microVersion, String buildType, + String debugPort, boolean hotDeploy); + + public abstract List getReloadCommand(boolean hotDeploy, List sourcesChanged, + boolean metadataChanged); + + public static boolean isMavenProject(IProject project) { + try { + return project.hasNature(MAVEN_NATURE); + } catch (CoreException e) { + return false; + } + } + + public static BuildTool getToolSupport(IProject project) { + if (isMavenProject(project)) { + return new MavenBuildTool(project); + } else { + return new GradleBuildTool(project); + } + } } diff --git a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/GradleBuildTool.java b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/GradleBuildTool.java index 82e9b956..979ec22b 100644 --- a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/GradleBuildTool.java +++ b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/GradleBuildTool.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2020 Payara Foundation + * Copyright (c) 2020-2021 Payara Foundation * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 @@ -12,6 +12,9 @@ import java.io.File; import java.io.FileNotFoundException; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.Platform; import static org.eclipse.payara.tools.micro.MicroConstants.WAR_BUILD_ARTIFACT; @@ -20,64 +23,90 @@ public class GradleBuildTool extends BuildTool { - public GradleBuildTool(IProject project) { - super(project); - } + public GradleBuildTool(IProject project) { + super(project); + } + + @Override + public String getExecutableHome() throws FileNotFoundException { + String gradleHome = System.getenv("GRADLE_HOME"); + if (gradleHome == null) { + throw new FileNotFoundException("set GRADLE_HOME the environment variable to gradle installation folder"); + } + + boolean gradleHomeEndsWithPathSep = gradleHome.charAt(gradleHome.length() - 1) == File.separatorChar; + String gradleExecStr = null; + String executor = gradleHome; + if (!gradleHomeEndsWithPathSep) { + executor += File.separatorChar; + } + executor += "bin" + File.separatorChar + "gradle"; + if (Platform.OS_WIN32.contentEquals(Platform.getOS())) { + if (Paths.get(executor + ".bat").toFile().exists()) { + gradleExecStr = executor + ".bat"; + } else if (Paths.get(executor + ".cmd").toFile().exists()) { + gradleExecStr = executor + ".cmd"; + } else { + throw new FileNotFoundException(String.format("Gradle executable %s.cmd not found.", executor)); + } + } else if (Paths.get(executor).toFile().exists()) { + gradleExecStr = executor; + } + // Gradle executable should exist. + if (gradleExecStr == null || !Paths.get(gradleExecStr).toFile().exists()) { + throw new FileNotFoundException(String.format("Gradle executable [%s] not found", gradleExecStr)); + } + return gradleExecStr; + } + + @Override + public List getStartCommand(String contextPath, String microVersion, String buildType, String debugPort, + boolean hotDeploy) { + + List commands = new ArrayList<>(); + if (WAR_BUILD_ARTIFACT.equals(buildType)) { + commands.add("war"); + commands.add("-DpayaraMicro.deployWar=true"); + } else if (EXPLODED_WAR_BUILD_ARTIFACT.equals(buildType)) { + commands.add("warExplode"); + commands.add("-DpayaraMicro.deployWar=true"); + commands.add("-DpayaraMicro.exploded=true"); + } else if (UBER_JAR_BUILD_ARTIFACT.equals(buildType)) { + commands.add("microBundle"); + commands.add("-DpayaraMicro.useUberJar=true"); + } else { + commands.add("build"); + } + commands.add("microStart"); + if (contextPath != null && !contextPath.trim().isEmpty()) { + commands.add("-DpayaraMicro.contextRoot=" + contextPath); + } + if (microVersion != null && !microVersion.trim().isEmpty()) { + commands.add("-DpayaraMicro.payaraVersion=" + microVersion); + } + if (hotDeploy) { + commands.add("-DpayaraMicro.hotDeploy=true"); + } + commands.add("-Ddebug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=" + debugPort); + return commands; + } - @Override - public String getExecutableHome() throws FileNotFoundException { - String gradleHome = System.getenv("GRADLE_HOME"); - if (gradleHome == null) { - throw new FileNotFoundException("set GRADLE_HOME the environment variable to gradle installation folder"); - } + public List getReloadCommand(boolean hotDeploy, List sourcesChanged, boolean metadataChanged) { - boolean gradleHomeEndsWithPathSep = gradleHome.charAt(gradleHome.length() - 1) == File.separatorChar; - String gradleExecStr = null; - String executor = gradleHome; - if (!gradleHomeEndsWithPathSep) { - executor += File.separatorChar; - } - executor += "bin" + File.separatorChar + "gradle"; - if (Platform.OS_WIN32.contentEquals(Platform.getOS())) { - if (Paths.get(executor + ".bat").toFile().exists()) { - gradleExecStr = executor + ".bat"; - } else if (Paths.get(executor + ".cmd").toFile().exists()) { - gradleExecStr = executor + ".cmd"; - } else { - throw new FileNotFoundException(String.format("Gradle executable %s.cmd not found.", executor)); - } - } else if (Paths.get(executor).toFile().exists()) { - gradleExecStr = executor; - } - // Gradle executable should exist. - if (gradleExecStr == null || !Paths.get(gradleExecStr).toFile().exists()) { - throw new FileNotFoundException(String.format("Gradle executable [%s] not found", gradleExecStr)); - } - return gradleExecStr; - } + List commands = new ArrayList<>(); + commands.add("warExplode"); + commands.add("microReload"); - @Override - public String getStartCommand(String contextPath, String microVersion, String buildType, String debugPort) { - StringBuilder sb = new StringBuilder(); - if (WAR_BUILD_ARTIFACT.equals(buildType)) { - sb.append("war -DpayaraMicro.deployWar=true"); - } else if (EXPLODED_WAR_BUILD_ARTIFACT.equals(buildType)) { - sb.append("warExplode -DpayaraMicro.deployWar=true -DpayaraMicro.exploded=true"); - } else if (UBER_JAR_BUILD_ARTIFACT.equals(buildType)) { - sb.append("microBundle -DpayaraMicro.useUberJar=true"); - } else { - sb.append("build"); - } - sb.append(" microStart"); - if (contextPath != null && !contextPath.trim().isEmpty()) { - sb.append(" -DpayaraMicro.contextRoot=").append(contextPath); - } - if (microVersion != null && !microVersion.trim().isEmpty()) { - sb.append(" -DpayaraMicro.payaraVersion=").append(microVersion); - } - sb.append(" -Ddebug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=") - .append(debugPort); - return sb.toString(); - } + if (hotDeploy) { + commands.add("-DpayaraMicro.hotDeploy=true"); + if (metadataChanged) { + commands.add("-DpayaraMicro.metadataChanged=true"); + } + if (!sourcesChanged.isEmpty()) { + commands.add("-DpayaraMicro.sourcesChanged=" + String.join(",", sourcesChanged)); + } + } + return commands; + } } diff --git a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/MavenBuildTool.java b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/MavenBuildTool.java index e7ec7da6..63f8d12b 100644 --- a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/MavenBuildTool.java +++ b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/MavenBuildTool.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2020 Payara Foundation + * Copyright (c) 2020-2021 Payara Foundation * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 @@ -12,6 +12,9 @@ import java.io.File; import java.io.FileNotFoundException; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.Platform; import static org.eclipse.payara.tools.micro.MicroConstants.EXPLODED_WAR_BUILD_ARTIFACT; @@ -20,72 +23,102 @@ public class MavenBuildTool extends BuildTool { - public MavenBuildTool(IProject project) { - super(project); - } + private static final String PLUGIN = " fish.payara.maven.plugins:payara-micro-maven-plugin:"; + + public MavenBuildTool(IProject project) { + super(project); + } + + @Override + public String getExecutableHome() throws FileNotFoundException { + String mavenHome = System.getenv("M2_HOME"); + if (mavenHome == null) { + mavenHome = System.getenv("MAVEN_HOME"); + } + + if (mavenHome == null) { + throw new FileNotFoundException("set MAVEN_HOME the environment variable to maven installation folder"); + } + + boolean mavenHomeEndsWithPathSep = mavenHome.charAt(mavenHome.length() - 1) == File.separatorChar; + String mavenExecStr = null; + String executor = mavenHome; + if (!mavenHomeEndsWithPathSep) { + executor += File.separatorChar; + } + executor += "bin" + File.separatorChar + "mvn"; + if (Platform.OS_WIN32.contentEquals(Platform.getOS())) { + if (Paths.get(executor + ".bat").toFile().exists()) { + mavenExecStr = executor + ".bat"; + } else if (Paths.get(executor + ".cmd").toFile().exists()) { + mavenExecStr = executor + ".cmd"; + } else { + throw new FileNotFoundException(String.format("Maven executable %s.cmd not found.", executor)); + } + } else if (Paths.get(executor).toFile().exists()) { + mavenExecStr = executor; + } + // Maven executable should exist. + if (mavenExecStr == null || !Paths.get(mavenExecStr).toFile().exists()) { + throw new FileNotFoundException(String.format("Maven executable [%s] not found", mavenExecStr)); + } + return mavenExecStr; + } + + @Override + public List getStartCommand(String contextPath, String microVersion, String buildType, String debugPort, + boolean hotDeploy) { - @Override - public String getExecutableHome() throws FileNotFoundException { - String mavenHome = System.getenv("M2_HOME"); - if (mavenHome == null) { - mavenHome = System.getenv("MAVEN_HOME"); - } + List commands = new ArrayList<>(); + if (WAR_BUILD_ARTIFACT.equals(buildType)) { + commands.add("resources:resources"); + commands.add("compiler:compile"); + commands.add("war:war"); + commands.add("-DdeployWar=true"); + } else if (EXPLODED_WAR_BUILD_ARTIFACT.equals(buildType)) { + commands.add("resources:resources"); + commands.add("compiler:compile"); + commands.add("war:exploded"); + commands.add("-DdeployWar=true"); + commands.add("-Dexploded=true"); + } else if (UBER_JAR_BUILD_ARTIFACT.equals(buildType)) { + commands.add("package"); + commands.add(PLUGIN + "bundle"); + commands.add("-DuseUberJar=true"); + } else { + commands.add("package"); + } + commands.add(PLUGIN + "start"); + if (contextPath != null && !contextPath.trim().isEmpty()) { + commands.add("-DcontextRoot=" + contextPath); + } + if (microVersion != null && !microVersion.trim().isEmpty()) { + commands.add("-DpayaraVersion=" + microVersion); + } + if (hotDeploy) { + commands.add("-DhotDeploy=true"); + } + commands.add("-Ddebug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=" + debugPort); + return commands; + } - if (mavenHome == null) { - throw new FileNotFoundException("set MAVEN_HOME the environment variable to maven installation folder"); - } + public List getReloadCommand(boolean hotDeploy, List sourcesChanged, boolean metadataChanged) { - boolean mavenHomeEndsWithPathSep = mavenHome.charAt(mavenHome.length() - 1) == File.separatorChar; - String mavenExecStr = null; - String executor = mavenHome; - if (!mavenHomeEndsWithPathSep) { - executor += File.separatorChar; - } - executor += "bin" + File.separatorChar + "mvn"; - if (Platform.OS_WIN32.contentEquals(Platform.getOS())) { - if (Paths.get(executor + ".bat").toFile().exists()) { - mavenExecStr = executor + ".bat"; - } else if (Paths.get(executor + ".cmd").toFile().exists()) { - mavenExecStr = executor + ".cmd"; - } else { - throw new FileNotFoundException(String.format("Maven executable %s.cmd not found.", executor)); - } - } else if (Paths.get(executor).toFile().exists()) { - mavenExecStr = executor; - } - // Maven executable should exist. - if (mavenExecStr == null || !Paths.get(mavenExecStr).toFile().exists()) { - throw new FileNotFoundException(String.format("Maven executable [%s] not found", mavenExecStr)); - } - return mavenExecStr; - } + List commands = new ArrayList<>(); + commands.add("resources:resources"); + commands.add("compiler:compile"); + commands.add("war:exploded"); + commands.add("payara-micro:reload"); - @Override - public String getStartCommand( - String contextPath, - String microVersion, - String buildType, - String debugPort) { - String plugin = " fish.payara.maven.plugins:payara-micro-maven-plugin:"; - StringBuilder sb = new StringBuilder(); - if (WAR_BUILD_ARTIFACT.equals(buildType)) { - sb.append("resources:resources compiler:compile war:war -DdeployWar=true"); - } else if (EXPLODED_WAR_BUILD_ARTIFACT.equals(buildType)) { - sb.append("resources:resources compiler:compile war:exploded -DdeployWar=true -Dexploded=true"); - } else if (UBER_JAR_BUILD_ARTIFACT.equals(buildType)) { - sb.append("package").append(plugin).append("bundle").append(" -DuseUberJar=true"); - } else { - sb.append("package"); - } - sb.append(plugin).append("start"); - if (contextPath != null && !contextPath.trim().isEmpty()) { - sb.append(" -DcontextRoot=").append(contextPath); - } - if (microVersion != null && !microVersion.trim().isEmpty()) { - sb.append(" -DpayaraVersion=").append(microVersion); - } - sb.append(" -Ddebug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=") - .append(debugPort); - return sb.toString(); - } + if (hotDeploy) { + commands.add("-DhotDeploy=true"); + if (metadataChanged) { + commands.add("-DmetadataChanged=true"); + } + if (!sourcesChanged.isEmpty()) { + commands.add("-DsourcesChanged=" + String.join(",", sourcesChanged)); + } + } + return commands; + } } diff --git a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/MicroConstants.java b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/MicroConstants.java index de1a4fe5..96c0666e 100644 --- a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/MicroConstants.java +++ b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/MicroConstants.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2020 Payara Foundation + * Copyright (c) 2020-2021 Payara Foundation * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 @@ -11,23 +11,29 @@ public interface MicroConstants { - String PLUGIN_ID = "org.eclipse.payara.tools"; + String PLUGIN_ID = "org.eclipse.payara.tools"; + + String PROJECT_NAME_ATTR = "org.eclipse.jdt.launching.PROJECT_ATTR"; - String DEFAULT_HOST = "localhost"; - int DEFAULT_DEBUG_PORT = 9889; + String DEFAULT_HOST = "localhost"; + int DEFAULT_DEBUG_PORT = 9889; - String ATTR_HOST_NAME = "hostname"; - String ATTR_PORT = "port"; + String ATTR_HOST_NAME = "hostname"; + String ATTR_PORT = "port"; - String JAVA_HOME_ENV_VAR = "JAVA_HOME"; + String JAVA_HOME_ENV_VAR = "JAVA_HOME"; - String ATTR_CONTEXT_PATH = "contextPath"; - String ATTR_MICRO_VERSION = "microVersion"; - String ATTR_BUILD_ARTIFACT = "buildArtifact"; - String ATTR_DEBUG_PORT = "debugPort"; + String ATTR_CONTEXT_PATH = "contextPath"; + String ATTR_MICRO_VERSION = "microVersion"; + String ATTR_BUILD_ARTIFACT = "buildArtifact"; + String ATTR_DEBUG_PORT = "debugPort"; + String ATTR_RELOAD_ARTIFACT = "reloadArtifact"; - String WAR_BUILD_ARTIFACT = "War"; - String EXPLODED_WAR_BUILD_ARTIFACT = "Exploded War"; - String UBER_JAR_BUILD_ARTIFACT = "Uber Jar"; + String WAR_BUILD_ARTIFACT = "War"; + String EXPLODED_WAR_BUILD_ARTIFACT = "Exploded War"; + String UBER_JAR_BUILD_ARTIFACT = "Uber Jar"; + + String AUTO_DEPLOY_ARTIFACT = "Auto Deploy"; + String HOT_DEPLOY_ARTIFACT = "Hot Deploy"; } diff --git a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/MicroRuntimeProcess.java b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/MicroRuntimeProcess.java index 6260a186..293752be 100644 --- a/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/MicroRuntimeProcess.java +++ b/plugins/org.eclipse.payara.tools/src/org/eclipse/payara/tools/micro/MicroRuntimeProcess.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2020 Payara Foundation + * Copyright (c) 2020-2021 Payara Foundation * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 @@ -9,92 +9,187 @@ */ package org.eclipse.payara.tools.micro; +import static org.eclipse.payara.tools.Messages.errorInInitializingMicroWatcher; +import static org.eclipse.payara.tools.Messages.errorInReloadingMicro; +import static org.eclipse.payara.tools.Messages.errorInTerminatingMicro; +import static org.eclipse.payara.tools.micro.MicroConstants.ATTR_RELOAD_ARTIFACT; +import static org.eclipse.payara.tools.micro.MicroConstants.HOT_DEPLOY_ARTIFACT; +import static org.eclipse.payara.tools.micro.MicroConstants.PROJECT_NAME_ATTR; + +import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Platform; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.model.IDisconnect; import org.eclipse.debug.core.model.RuntimeProcess; + import com.sun.jna.Pointer; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.WinNT; -import java.util.logging.Level; -import java.util.logging.Logger; - public class MicroRuntimeProcess extends RuntimeProcess { - private ILaunch debuggerConnection; - - private static final String ERROR_MESSAGE = "Error occurred while terminating payara-micro"; - - private static final Logger LOG = Logger.getLogger(MicroRuntimeProcess.class.getName()); - - public MicroRuntimeProcess(ILaunch launch, Process process, String name, Map attributes) { - super(launch, process, name, attributes); - } - - ILaunch getDebuggerConnection() { - return debuggerConnection; - } - - void setDebuggerConnection(ILaunch debuggerConnection) { - this.debuggerConnection = debuggerConnection; - } - - @Override - public void terminate() throws DebugException { - terminateInstance(); - super.terminate(); - disconnectDebuggerConnection(); - } - - private void disconnectDebuggerConnection() throws DebugException { - if (debuggerConnection != null - && debuggerConnection instanceof IDisconnect - && ((IDisconnect) debuggerConnection).canDisconnect()) { - ((IDisconnect) debuggerConnection).disconnect(); - } - } - - private void terminateInstance() { - try { - Process process = (Process) getSystemProcess(); - long pid; - try { - Method method = process.getClass().getDeclaredMethod("pid"); - method.setAccessible(true); - pid = (long) method.invoke(process); - } catch (NoSuchMethodException ex) { - Field field = process.getClass().getDeclaredField("handle"); - field.setAccessible(true); - long handleValue = field.getLong(process); - Kernel32 kernel = Kernel32.INSTANCE; - WinNT.HANDLE handle = new WinNT.HANDLE(); - handle.setPointer(Pointer.createConstant(handleValue)); - pid = kernel.GetProcessId(handle); - } - killProcess(String.valueOf(pid)); - } catch (Exception ex) { - LOG.log(Level.SEVERE, ERROR_MESSAGE, ex); - } - } - - private void killProcess(String processId) throws IOException, InterruptedException { - String command; - final Runtime re = Runtime.getRuntime(); - if (Platform.OS_WIN32.equals(Platform.getOS())) { - command = "taskkill /F /T /PID " + processId; - } else { - command = "kill " + processId; - } - Process killProcess = re.exec(command); - int result = killProcess.waitFor(); - if (result != 0) { - LOG.severe(ERROR_MESSAGE); - } - } + private ILaunch debuggerConnection; + + private IResourceChangeListener sourceChangeListener; + + private static final Logger LOG = Logger.getLogger(MicroRuntimeProcess.class.getName()); + + public MicroRuntimeProcess(ILaunch launch, Process process, String name, Map attributes) { + super(launch, process, name, attributes); + watchResources(launch.getLaunchConfiguration(), process); + } + + ILaunch getDebuggerConnection() { + return debuggerConnection; + } + + void setDebuggerConnection(ILaunch debuggerConnection) { + this.debuggerConnection = debuggerConnection; + } + + private void watchResources(ILaunchConfiguration config, Process process) { + try { + final String projectName = config.getAttribute(PROJECT_NAME_ATTR, ""); + String reloadArtifact = config.getAttribute(ATTR_RELOAD_ARTIFACT, ""); + if (!reloadArtifact.isEmpty()) { + this.sourceChangeListener = new IResourceChangeListener() { + public void resourceChanged(IResourceChangeEvent event) { + List filesChanged = getAllAffectedResources(event.getDelta(), IFile.class, + IResourceDelta.CHANGED, projectName); + boolean hotDeploy = reloadArtifact.equals(HOT_DEPLOY_ARTIFACT); + List sourcesChanged = new ArrayList<>(); + boolean metadataChanged = false; + if (hotDeploy) { + for (IFile fileChanged : filesChanged) { + String path = fileChanged.getFullPath().toString(); + String ext = fileChanged.getFileExtension(); + if (!path.endsWith("class")) { + sourcesChanged.add(path); + } + if (ext.equals("xml") || ext.equals("properties")) { + metadataChanged = true; + } + } + } + if (!filesChanged.isEmpty()) { + try { + IProject project = filesChanged.get(0).getProject(); + BuildTool tool = BuildTool.getToolSupport(project); + List commands = new ArrayList<>(); + commands.add(tool.getExecutableHome()); + commands.addAll(tool.getReloadCommand(hotDeploy, sourcesChanged, metadataChanged)); + ProcessBuilder pb = new ProcessBuilder(commands); + pb.directory(new File(project.getLocationURI())); + pb.redirectErrorStream(true); + pb.redirectOutput(ProcessBuilder.Redirect.INHERIT); + pb.start(); + } catch (Exception ex) { + LOG.log(Level.SEVERE, errorInReloadingMicro, ex); + } + } + } + }; + ResourcesPlugin.getWorkspace().addResourceChangeListener(this.sourceChangeListener, + IResourceChangeEvent.POST_BUILD); + } + } catch (CoreException ex) { + LOG.log(Level.SEVERE, errorInInitializingMicroWatcher, ex); + } + } + + private List getAllAffectedResources(IResourceDelta delta, Class clazz, int deltaKind, + String projectName) { + List files = new ArrayList(); + + for (IResourceDelta child : delta.getAffectedChildren()) { + IResource resource = child.getResource(); + + if (resource.getProject().getName().equals(projectName)) { + + if (resource != null && clazz.isAssignableFrom(resource.getClass())) { + if ((child.getKind() & deltaKind) != 0) { + files.add((T) resource); + } + } else { + files.addAll(getAllAffectedResources(child, clazz, deltaKind, projectName)); + } + } + } + return files; + } + + @Override + public void terminate() throws DebugException { + terminateInstance(); + super.terminate(); + disconnectDebuggerConnection(); + if (this.sourceChangeListener != null) { + ResourcesPlugin.getWorkspace().removeResourceChangeListener(this.sourceChangeListener); + } + } + + private void disconnectDebuggerConnection() throws DebugException { + if (debuggerConnection != null && debuggerConnection instanceof IDisconnect + && ((IDisconnect) debuggerConnection).canDisconnect()) { + ((IDisconnect) debuggerConnection).disconnect(); + } + } + + private void terminateInstance() { + try { + Process process = (Process) getSystemProcess(); + long pid; + try { + Method method = process.getClass().getDeclaredMethod("pid"); + method.setAccessible(true); + pid = (long) method.invoke(process); + } catch (NoSuchMethodException ex) { + Field field = process.getClass().getDeclaredField("handle"); + field.setAccessible(true); + long handleValue = field.getLong(process); + Kernel32 kernel = Kernel32.INSTANCE; + WinNT.HANDLE handle = new WinNT.HANDLE(); + handle.setPointer(Pointer.createConstant(handleValue)); + pid = kernel.GetProcessId(handle); + } + killProcess(String.valueOf(pid)); + } catch (Exception ex) { + LOG.log(Level.SEVERE, errorInTerminatingMicro, ex); + } + } + + private void killProcess(String processId) throws IOException, InterruptedException { + String command; + final Runtime re = Runtime.getRuntime(); + if (Platform.OS_WIN32.equals(Platform.getOS())) { + command = "taskkill /F /T /PID " + processId; + } else { + command = "kill " + processId; + } + Process killProcess = re.exec(command); + int result = killProcess.waitFor(); + if (result != 0) { + LOG.severe(errorInTerminatingMicro); + } + } }