This is an automated email from the ASF dual-hosted git repository.

lkishalmi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 525912c  [NETBEANS-2654] Add debugger support for Gradle Web Projects 
(#1289)
525912c is described below

commit 525912c8077fd5c148b2f00e2fb740bd2830637a
Author: Laszlo Kishalmi <laszlo.kisha...@gmail.com>
AuthorDate: Sat Jun 15 06:54:58 2019 -0700

    [NETBEANS-2654] Add debugger support for Gradle Web Projects (#1289)
    
    * [NETBEANS-2654, NETBEANS-2655] Added a convenient debugger SPI to attach
    debug process to a Gradle Project. Fix the JVM Platform selection.
    
    * [NETBEANS-2654] Added a debugger hook for Gradle Web Projects.
    
    * Added version bump, and very minimal docs.
---
 groovy/gradle.java/apichanges.xml                  |  126 +++
 groovy/gradle.java/arch.xml                        | 1060 ++++++++++++++++++++
 groovy/gradle.java/manifest.mf                     |    2 +-
 groovy/gradle.java/nbproject/project.xml           |    1 +
 .../gradle/java/GradleJavaDebuggerImpl.java        |  161 +++
 .../gradle/java/output/JDPAProcessorFactory.java   |   94 +-
 .../gradle/java/spi/debug/GradleJavaDebugger.java  |   44 +
 groovy/gradle.javaee/nbproject/project.xml         |    2 +-
 .../modules/gradle/javaee/action-mapping.xml       |    3 +
 .../modules/gradle/javaee/execute/DeployHook.java  |   41 +-
 10 files changed, 1443 insertions(+), 91 deletions(-)

diff --git a/groovy/gradle.java/apichanges.xml 
b/groovy/gradle.java/apichanges.xml
new file mode 100644
index 0000000..eb7f050
--- /dev/null
+++ b/groovy/gradle.java/apichanges.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<?xml-stylesheet type="text/xml" 
href="../../nbbuild/javadoctools/apichanges.xsl"?>
+<!DOCTYPE apichanges PUBLIC "-//NetBeans//DTD API changes list 1.0//EN" 
"../../nbbuild/javadoctools/apichanges.dtd">
+
+<!--
+
+INFO FOR PEOPLE ADDING CHANGES:
+
+Check the DTD (apichanges.dtd) for details on the syntax. You do not
+need to regenerate the HTML, as this is part of Javadoc generation; just
+change the XML. Rough syntax of a change (several parts optional):
+
+<change>
+    <api name="compiler"/>
+    <summary>Some brief description here, can use <b>XHTML</b></summary>
+    <version major="1" minor="99"/>
+    <date day="13" month="6" year="2001"/>
+    <author login="jrhacker"/>
+    <compatibility addition="yes"/>
+    <description>
+        The main description of the change here.
+        Again can use full <b>XHTML</b> as needed.
+    </description>
+    <class package="org.openide.compiler" name="DoWhatIWantCompiler"/>
+    <issue number="14309"/>
+</change>
+
+Also permitted elements: <package>, <branch>. <version> is API spec
+version, recommended for all new changes. <compatibility> should say
+if things were added/modified/deprecated/etc. and give all information
+related to upgrading old code. List affected top-level classes and
+link to issue numbers if applicable. See the DTD for more details.
+
+Changes need not be in any particular order, they are sorted in various
+ways by the stylesheet anyway.
+
+Dates are assumed to mean "on the trunk". If you *also* make the same
+change on a stabilization branch, use the <branch> tag to indicate this
+and explain why the change was made on a branch in the <description>.
+
+Please only change this file on the trunk! Rather: you can change it
+on branches if you want, but these changes will be ignored; only the
+trunk version of this file is important.
+
+Deprecations do not count as incompatible, assuming that code using the
+deprecated calls continues to see their documented behavior. But do
+specify deprecation="yes" in <compatibility>.
+
+This file is not a replacement for Javadoc: it is intended to list changes,
+not describe the complete current behavior, for which ordinary documentation
+is the proper place.
+
+-->
+
+<apichanges>
+
+    <!-- First, a list of API names you may use: -->
+    <apidefs>
+        <apidef name="general">Gradle Java Project API</apidef>
+        <!-- etc. -->
+    </apidefs>
+
+    <!-- ACTUAL CHANGES BEGIN HERE: -->
+
+    <changes>
+    </changes>
+
+    <!-- Now the surrounding HTML text and document structure: -->
+
+    <htmlcontents>
+<!--
+
+                            NO NO NO NO NO!
+
+         ==============>    DO NOT EDIT ME!  <==============
+
+          AUTOMATICALLY GENERATED FROM APICHANGES.XML, DO NOT EDIT
+
+                SEE projects/projectuiapi/apichanges.xml
+
+        -->
+        <head>
+            <title>Change History for the Gradle Java Project API</title>
+            <link rel="stylesheet" href="prose.css" type="text/css"/>
+        </head>
+        <body>
+
+            <p class="overviewlink">
+                <a href="overview-summary.html">Overview</a>
+            </p>
+
+            <h1>Introduction</h1>
+
+            <p>This document lists changes made to the <a 
href="@org-netbeans-modules-gradle-java@/index.html">Gradle Java Project 
API</a>.</p>
+
+            <!-- The actual lists of changes, as summaries and details: -->
+            <hr/>
+            <standard-changelists 
module-code-name="org.netbeans.modules.gradle.java/0"/>
+
+            <hr/>
+            <p>@FOOTER@</p>
+
+        </body>
+    </htmlcontents>
+
+</apichanges>
diff --git a/groovy/gradle.java/arch.xml b/groovy/gradle.java/arch.xml
new file mode 100644
index 0000000..3fb2ded
--- /dev/null
+++ b/groovy/gradle.java/arch.xml
@@ -0,0 +1,1060 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<!DOCTYPE api-answers PUBLIC "-//NetBeans//DTD Arch Answers//EN" 
"../../nbbuild/antsrc/org/netbeans/nbbuild/Arch.dtd" [
+  <!ENTITY api-questions SYSTEM 
"../../nbbuild/antsrc/org/netbeans/nbbuild/Arch-api-questions.xml">
+]>
+
+<api-answers
+  question-version="1.29"
+  author="lkisha...@apache.org"
+>
+
+  &api-questions;
+
+
+<!--
+        <question id="arch-overall" when="init">
+            Describe the overall architecture.
+            <hint>
+            What will be API for
+            <a 
href="http://openide.netbeans.org/tutorial/api-design.html#design.apiandspi";>
+                clients and what support API</a>?
+            What parts will be pluggable?
+            How will plug-ins be registered? Please use <code>&lt;api 
type="export"/&gt;</code>
+            to describe your general APIs.
+            If possible please provide
+            simple diagrams.
+            </hint>
+        </question>
+-->
+ <answer id="arch-overall">
+  <ul>
+   <li>
+    <api group="java" name="GradleJavaProjectAPI" type="export" 
category="devel">
+     <p>
+      The Gradle Java Project API provides some miscellaneous friend APIs and 
SPIs relating to
+      Gradle Java projects.
+     </p>
+    </api>
+   </li>
+  </ul>
+ </answer>
+
+
+
+
+
+
+<!--
+        <question id="arch-usecases" when="init">
+            Describe the main <a 
href="http://openide.netbeans.org/tutorial/api-design.html#usecase";>
+            use cases</a> of the new API. Who will use it at
+            what circumstances and what will be the typical code to write
+            to use the module.
+        </question>
+-->
+ <answer id="arch-usecases">
+  <p>
+     API/SPI to be used by modules wanting to enhance the Gradle Java 
project's integration in the IDE.
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="resources-read" when="final">
+            Does your module read any resources from layers? For what purpose?
+
+            <hint>
+            As this is some kind of intermodule dependency, it is a kind of 
API.
+            Please describe it and classify according to
+            <a 
href="http://openide.netbeans.org/tutorial/api-design.html#categories";>
+            common stability categories</a>.
+            </hint>
+        </question>
+-->
+ <answer id="resources-read">
+
+ </answer>
+
+
+ <answer id="exec-property">
+ </answer>
+
+ <answer id="resources-file">
+ </answer>
+
+
+
+
+<!--
+        <question id="arch-quality" when="init">
+            How will the <a 
href="http://www.netbeans.org/community/guidelines/q-evangelism.html"; 
shape="rect">quality</a>
+            of your code be tested and
+            how are future regressions going to be prevented?
+            <hint>
+            What kind of testing do
+            you want to use? How much functionality, in which areas,
+            should be covered by the tests? How you find out that your
+            project was successful?
+            </hint>
+        </question>
+-->
+ <answer id="arch-quality">
+  <p>
+   XXX no answer for arch-quality
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="arch-time" when="init">
+            What are the time estimates of the work?
+            <hint>
+            Please express your estimates of how long the design, 
implementation,
+            stabilization are likely to last. How many people will be needed to
+            implement this and what is the expected milestone by which the 
work should be
+            ready?
+            </hint>
+        </question>
+-->
+ <answer id="arch-time">
+  <p>
+   XXX no answer for arch-time
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="arch-what" when="init">
+            What is this project good for?
+            <hint>
+            Please provide here a few lines describing the project,
+            what problem it should solve, provide links to documentation,
+            specifications, etc.
+            </hint>
+        </question>
+-->
+ <answer id="arch-what">
+  <p>
+   XXX no answer for arch-what
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="arch-where" when="impl">
+            Where one can find sources for your module?
+            <hint>
+                Please provide link to the Hg web client at
+                http://hg.netbeans.org/
+                or just use tag defaultanswer generate='here'
+            </hint>
+        </question>
+-->
+ <answer id="arch-where">
+  <defaultanswer generate='here' />
+ </answer>
+
+
+
+<!--
+        <question id="compat-deprecation" when="init">
+            How the introduction of your project influences functionality
+            provided by previous version of the product?
+            <hint>
+            If you are planning to deprecate/remove/change any existing APIs,
+            list them here accompanied with the reason explaining why you
+            are doing so.
+            </hint>
+        </question>
+-->
+ <answer id="compat-deprecation">
+  <p>
+   XXX no answer for compat-deprecation
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="compat-i18n" when="impl">
+            Is your module correctly internationalized?
+            <hint>
+            Correct internationalization means that it obeys instructions
+            at <a 
href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/i18n-branding.html";
 shape="rect">
+            NetBeans I18N pages</a>.
+            </hint>
+        </question>
+-->
+ <answer id="compat-i18n">
+  <p>
+   XXX no answer for compat-i18n
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="compat-standards" when="init">
+            Does the module implement or define any standards? Is the
+            implementation exact or does it deviate somehow?
+        </question>
+-->
+ <answer id="compat-standards">
+  <p>
+   XXX no answer for compat-standards
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="compat-version" when="impl">
+            Can your module coexist with earlier and future
+            versions of itself? Can you correctly read all old settings? Will 
future
+            versions be able to read your current settings? Can you read
+            or politely ignore settings stored by a future version?
+
+            <hint>
+            Very helpful for reading settings is to store version number
+            there, so future versions can decide whether how to read/convert
+            the settings and older versions can ignore the new ones.
+            </hint>
+        </question>
+-->
+ <answer id="compat-version">
+  <p>
+   XXX no answer for compat-version
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="dep-jre" when="final">
+            Which version of JRE do you need (1.2, 1.3, 1.4, etc.)?
+            <hint>
+            It is expected that if your module runs on 1.x that it will run
+            on 1.x+1 if no, state that please. Also describe here cases where
+            you run different code on different versions of JRE and why.
+            </hint>
+        </question>
+-->
+ <answer id="dep-jre">
+  <p>
+   XXX no answer for dep-jre
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="dep-jrejdk" when="final">
+            Do you require the JDK or is the JRE enough?
+        </question>
+-->
+ <answer id="dep-jrejdk">
+  <p>
+   XXX no answer for dep-jrejdk
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="dep-nb" when="init">
+            What other NetBeans projects and modules does this one depend on?
+            <hint>
+            Depending on other NetBeans projects influnces the ability of
+            users of your work to customize their own branded version of
+            NetBeans by enabling and disabling some modules. Too
+            much dependencies restrict this kind of customization. If that
+            is your case, then you may want to split your functionality into
+            pieces of autoload, eager and regular modules which can be
+            enabled independently. Usually the answer to this question
+            is generated from your <code>project.xml</code> file, but
+            if it is not guessed correctly, you can suppress it by
+            specifying &lt;defaultanswer generate="none"/&gt; and
+            write here your own. Please describe such projects as imported 
APIs using
+            the <code>&lt;api name="identification" type="import or export" 
category="stable" url="where is the description" /&gt;</code>.
+            By doing this information gets listed in the summary page of your
+            javadoc.
+            </hint>
+        </question>
+-->
+ <answer id="dep-nb">
+  <defaultanswer generate='here' />
+ </answer>
+
+
+
+<!--
+        <question id="dep-non-nb" when="init">
+            What other projects outside NetBeans does this one depend on?
+
+            <hint>
+            Depending on 3rd party libraries is always problematic,
+            especially if they are not open source, as that complicates
+            the licensing scheme of NetBeans. Please enumerate your
+            external dependencies here, so it is correctly understood since
+            the begining what are the legal implications of your project.
+            Also please note that
+            some non-NetBeans projects are packaged as NetBeans modules
+            (see <a href="http://libs.netbeans.org/"; 
shape="rect">libraries</a>) and
+            it is preferred to use this approach when more modules may
+            depend and share such third-party libraries.
+            </hint>
+        </question>
+-->
+ <answer id="dep-non-nb">
+  <p>
+   XXX no answer for dep-non-nb
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="dep-platform" when="init">
+            On which platforms does your module run? Does it run in the same
+            way on each?
+            <hint>
+            If you plan any dependency on OS or any usage of native code,
+            please describe why you are doing so and describe how you envision
+            to enforce the portability of your code.
+            Please note that there is a support for <a 
href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html#how-os-specific";
 shape="rect">OS conditionally
+            enabled modules</a> which together with autoload/eager modules
+            can allow you to enable to provide the best OS aware support
+            on certain OSes while providing compatibility bridge on the not
+            supported ones.
+            Also please list the supported
+            OSes/HW platforms and mentioned the lovest version of JDK required
+            for your project to run on. Also state whether JRE is enough or
+            you really need JDK.
+            </hint>
+        </question>
+-->
+ <answer id="dep-platform">
+  <p>
+   XXX no answer for dep-platform
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="deploy-dependencies" when="final">
+            What do other modules need to do to declare a dependency on this 
one,
+            in addition to or instead of the normal module dependency 
declaration
+            (e.g. tokens to require)?
+            <hint>
+                Provide a sample of the actual lines you would add to a module 
manifest
+                to declare a dependency, for example OpenIDE-Module-Requires: 
some.token.
+                If other modules should not depend on this module, or should 
just use a
+                simple regular module dependency, you can just answer 
"nothing". If you
+                intentionally expose a semistable API to clients using 
implementation
+                dependencies, you should mention that here (but there is no 
need to give
+                an example of usage).
+            </hint>
+        </question>
+-->
+ <answer id="deploy-dependencies">
+  <p>
+   XXX no answer for deploy-dependencies
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="deploy-jar" when="impl">
+            Do you deploy just module JAR file(s) or other files as well?
+            <hint>
+            Usually a module consist of one JAR file (perhaps with Class-Path
+            extensions) and also a configuration file that enables it. If you
+            have any other files, use
+            &lt;api group="java.io.File" name="yourname" type="export" 
category="friend"&gt;...&lt;/api&gt;
+            to define the location, name and stability of your files (of course
+            changing "yourname" and "friend" to suit your needs).
+
+            If it uses more than one JAR, describe where they are located, how
+            they refer to each other.
+            If it consist of module JAR(s) and other files, please describe
+            what is their purpose, why other files are necessary. Please
+            make sure that installation/uninstallation leaves the system
+            in state as it was before installation.
+            </hint>
+        </question>
+-->
+ <answer id="deploy-jar">
+  <p>
+   XXX no answer for deploy-jar
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="deploy-nbm" when="impl">
+            Can you deploy an NBM via the Update Center?
+            <hint>
+            If not why?
+            </hint>
+        </question>
+-->
+ <answer id="deploy-nbm">
+  <p>
+   XXX no answer for deploy-nbm
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="deploy-packages" when="init">
+            Are packages of your module made inaccessible by not declaring them
+            public?
+
+            <hint>
+            By default NetBeans build harness treats all packages are private.
+            If you export some of them - either as public or friend packages,
+            you should have a reason. If the reason is described elsewhere
+            in this document, you can ignore this question.
+            </hint>
+        </question>
+-->
+ <answer id="deploy-packages">
+  <p>
+   XXX no answer for deploy-packages
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="deploy-shared" when="final">
+            Do you need to be installed in the shared location only, or in the 
user directory only,
+            or can your module be installed anywhere?
+            <hint>
+            Installation location shall not matter, if it does explain why.
+            Consider also whether <code>InstalledFileLocator</code> can help.
+            </hint>
+        </question>
+-->
+ <answer id="deploy-shared">
+  <p>
+   XXX no answer for deploy-shared
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="exec-ant-tasks" when="impl">
+            Do you define or register any ant tasks that other can use?
+
+            <hint>
+            If you provide an ant task that users can use, you need to be very
+            careful about its syntax and behaviour, as it most likely forms an
+                 API for end users and as there is a lot of end users, their 
reaction
+            when such API gets broken can be pretty strong.
+            </hint>
+        </question>
+-->
+ <answer id="exec-ant-tasks">
+  <p>
+   XXX no answer for exec-ant-tasks
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="exec-classloader" when="impl">
+            Does your code create its own class loader(s)?
+            <hint>
+            A bit unusual. Please explain why and what for.
+            </hint>
+        </question>
+-->
+ <answer id="exec-classloader">
+  <p>
+   XXX no answer for exec-classloader
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="exec-component" when="impl">
+            Is execution of your code influenced by any (string) property
+            of any of your components?
+
+            <hint>
+            Often <code>JComponent.getClientProperty</code>, 
<code>Action.getValue</code>
+            or <code>PropertyDescriptor.getValue</code>, etc. are used to 
influence
+            a behavior of some code. This of course forms an interface that 
should
+            be documented. Also if one depends on some interface that an object
+            implements (<code>component instanceof Runnable</code>) that forms 
an
+            API as well.
+            </hint>
+        </question>
+-->
+ <answer id="exec-component">
+  <p>
+   XXX no answer for exec-component
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="exec-introspection" when="impl">
+            Does your module use any kind of runtime type information 
(<code>instanceof</code>,
+            work with <code>java.lang.Class</code>, etc.)?
+            <hint>
+            Check for cases when you have an object of type A and you also
+            expect it to (possibly) be of type B and do some special action. 
That
+            should be documented. The same applies on operations in meta-level
+            (Class.isInstance(...), Class.isAssignableFrom(...), etc.).
+            </hint>
+        </question>
+-->
+ <answer id="exec-introspection">
+  <p>
+   XXX no answer for exec-introspection
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="exec-privateaccess" when="final">
+            Are you aware of any other parts of the system calling some of
+            your methods by reflection?
+            <hint>
+            If so, describe the "contract" as an API. Likely private or friend 
one, but
+            still API and consider rewrite of it.
+            </hint>
+        </question>
+-->
+ <answer id="exec-privateaccess">
+  <p>
+   XXX no answer for exec-privateaccess
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="exec-process" when="impl">
+            Do you execute an external process from your module? How do you 
ensure
+            that the result is the same on different platforms? Do you parse 
output?
+            Do you depend on result code?
+            <hint>
+            If you feed an input, parse the output please declare that as an 
API.
+            </hint>
+        </question>
+-->
+ <answer id="exec-process">
+  <p>
+   XXX no answer for exec-process
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="exec-reflection" when="impl">
+            Does your code use Java Reflection to execute other code?
+            <hint>
+            This usually indicates a missing or insufficient API in the other
+            part of the system. If the other side is not aware of your 
dependency
+            this contract can be easily broken.
+            </hint>
+        </question>
+-->
+ <answer id="exec-reflection">
+  <p>
+   XXX no answer for exec-reflection
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="exec-threading" when="init">
+            What threading models, if any, does your module adhere to? How the
+            project behaves with respect to threading?
+            <hint>
+                Is your API threadsafe? Can it be accessed from any threads or
+                just from some dedicated ones? Any special relation to AWT and
+                its Event Dispatch thread? Also
+                if your module calls foreign APIs which have a specific 
threading model,
+                indicate how you comply with the requirements for 
multithreaded access
+                (synchronization, mutexes, etc.) applicable to those APIs.
+                If your module defines any APIs, or has complex internal 
structures
+                that might be used from multiple threads, declare how you 
protect
+                data against concurrent access, race conditions, deadlocks, 
etc.,
+                and whether such rules are enforced by runtime warnings, 
errors, assertions, etc.
+                Examples: a class might be non-thread-safe (like Java 
Collections); might
+                be fully thread-safe (internal locking); might require access 
through a mutex
+                (and may or may not automatically acquire that mutex on behalf 
of a client method);
+                might be able to run only in the event queue; etc.
+                Also describe when any events are fired: synchronously, 
asynchronously, etc.
+                Ideas: <a 
href="http://core.netbeans.org/proposals/threading/index.html#recommendations"; 
shape="rect">Threading Recommendations</a> (in progress)
+            </hint>
+        </question>
+-->
+ <answer id="exec-threading">
+  <p>
+   XXX no answer for exec-threading
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="format-clipboard" when="impl">
+            Which data flavors (if any) does your code read from or insert to
+            the clipboard (by access to clipboard on means calling methods on 
<code>java.awt.datatransfer.Transferable</code>?
+
+            <hint>
+            Often Node's deal with clipboard by usage of 
<code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
+            Check your code for overriding these methods.
+            </hint>
+        </question>
+-->
+ <answer id="format-clipboard">
+  <p>
+   XXX no answer for format-clipboard
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="format-dnd" when="impl">
+            Which protocols (if any) does your code understand during Drag 
&amp; Drop?
+            <hint>
+            Often Node's deal with clipboard by usage of <code>Node.drag, 
Node.getDropType</code>.
+            Check your code for overriding these methods. Btw. if they are not 
overridden, they
+            by default delegate to <code>Node.clipboardCopy, Node.clipboardCut 
and Node.pasteTypes</code>.
+            </hint>
+        </question>
+-->
+ <answer id="format-dnd">
+  <p>
+   XXX no answer for format-dnd
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="format-types" when="impl">
+            Which protocols and file formats (if any) does your module read or 
write on disk,
+            or transmit or receive over the network? Do you generate an ant 
build script?
+            Can it be edited and modified?
+
+            <hint>
+            <p>
+            Files can be read and written by other programs, modules and 
users. If they influence
+            your behaviour, make sure you either document the format or claim 
that it is a private
+            api (using the &lt;api&gt; tag).
+            </p>
+
+            <p>
+            If you generate an ant build file, this is very likely going to be 
seen by end users and
+            they will be attempted to edit it. You should be ready for that 
and provide here a link
+            to documentation that you have for such purposes and also describe 
how you are going to
+            understand such files during next release, when you (very likely) 
slightly change the
+            format.
+            </p>
+            </hint>
+        </question>
+-->
+ <answer id="format-types">
+  <p>
+   XXX no answer for format-types
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="lookup-lookup" when="init">
+            Does your module use <code>org.openide.util.Lookup</code>
+            or any similar technology to find any components to communicate 
with? Which ones?
+
+            <hint>
+            NetBeans is build around a generic registry of services called
+            lookup. It is preferable to use it for registration and discovery
+            if possible. See
+            <a 
href="http://www.netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/lookup/doc-files/index.html";
 shape="rect">
+            The Solution to Comunication Between Components
+            </a>. If you do not plan to use lookup and insist usage
+            of other solution, then please describe why it is not working for
+            you.
+            <br/>
+            When filling the final version of your arch document, please
+            describe the interfaces you are searching for, where
+            are defined, whether you are searching for just one or more of 
them,
+            if the order is important, etc. Also classify the stability of such
+            API contract. Use &lt;api group=&amp;lookup&amp; /&gt; tag, so
+            your information gets listed in the summary page of your javadoc.
+            </hint>
+        </question>
+-->
+ <answer id="lookup-lookup">
+  <p>
+    <api group="lookup" name="GradleJavaDebugger" type="export" 
category="private">
+     <p>
+         This module provides a lookup implementation for GradleJavaDebugger 
+         which makes it easy to attach a configured Java debugger to a running
+         process.
+     </p>
+    </api>
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="lookup-register" when="final">
+            Do you register anything into lookup for other code to find?
+            <hint>
+            Do you register using layer file or using a declarative annotation 
such as <code>@ServiceProvider</code>?
+            Who is supposed to find your component?
+            </hint>
+        </question>
+-->
+ <answer id="lookup-register">
+  <p>
+   XXX no answer for lookup-register
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="lookup-remove" when="final">
+            Do you remove entries of other modules from lookup?
+            <hint>
+            Why? Of course, that is possible, but it can be dangerous. Is the 
module
+            your are masking resource from aware of what you are doing?
+            </hint>
+        </question>
+-->
+ <answer id="lookup-remove">
+  <p>
+   XXX no answer for lookup-remove
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="perf-exit" when="final">
+            Does your module run any code on exit?
+        </question>
+-->
+ <answer id="perf-exit">
+  <p>
+   XXX no answer for perf-exit
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="perf-huge_dialogs" when="final">
+            Does your module contain any dialogs or wizards with a large 
number of
+            GUI controls such as combo boxes, lists, trees, or text areas?
+        </question>
+-->
+ <answer id="perf-huge_dialogs">
+  <p>
+   XXX no answer for perf-huge_dialogs
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="perf-limit" when="init">
+            Are there any hard-coded or practical limits in the number or size 
of
+            elements your code can handle?
+            <hint>
+                Most of algorithms have increasing memory and speed complexity
+                with respect to size of data they operate on. What is the 
critical
+                part of your project that can be seen as a bottleneck with
+                respect to speed or required memory? What are the practical
+                sizes of data you tested your project with? What is your 
estimate
+                of potential size of data that would cause visible performance
+                problems? Is there some kind of check to detect such situation
+                and prevent "hard" crashes - for example the 
CloneableEditorSupport
+                checks for size of a file to be opened in editor
+                and if it is larger than 1Mb it shows a dialog giving the
+                user the right to decide - e.g. to cancel or commit suicide.
+            </hint>
+        </question>
+-->
+ <answer id="perf-limit">
+  <p>
+   XXX no answer for perf-limit
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="perf-mem" when="final">
+            How much memory does your component consume? Estimate
+            with a relation to the number of windows, etc.
+        </question>
+-->
+ <answer id="perf-mem">
+  <p>
+   XXX no answer for perf-mem
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="perf-menus" when="final">
+            Does your module use dynamically updated context menus, or
+            context-sensitive actions with complicated and slow enablement 
logic?
+            <hint>
+                If you do a lot of tricks when adding actions to regular or 
context menus, you can significantly
+                slow down display of the menu, even when the user is not using 
your action. Pay attention to
+                actions you add to the main menu bar, and to context menus of 
foreign nodes or components. If
+                the action is conditionally enabled, or changes its display 
dynamically, you need to check the
+                impact on performance. In some cases it may be more 
appropriate to make a simple action that is
+                always enabled but does more detailed checks in a dialog if it 
is actually run.
+            </hint>
+        </question>
+-->
+ <answer id="perf-menus">
+  <p>
+   XXX no answer for perf-menus
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="perf-progress" when="final">
+            Does your module execute any long-running tasks?
+
+            <hint>Long running tasks should never block
+            AWT thread as it badly hurts the UI
+            <a 
href="http://performance.netbeans.org/responsiveness/issues.html"; shape="rect">
+            responsiveness</a>.
+            Tasks like connecting over
+            network, computing huge amount of data, compilation
+            be done asynchronously (for example
+            using <code>RequestProcessor</code>), definitively it should
+            not block AWT thread.
+            </hint>
+        </question>
+-->
+ <answer id="perf-progress">
+  <p>
+   XXX no answer for perf-progress
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="perf-scale" when="init">
+            Which external criteria influence the performance of your
+            program (size of file in editor, number of files in menu,
+            in source directory, etc.) and how well your code scales?
+            <hint>
+            Please include some estimates, there are other more detailed
+            questions to answer in later phases of implementation.
+            </hint>
+        </question>
+-->
+ <answer id="perf-scale">
+  <p>
+   XXX no answer for perf-scale
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="perf-spi" when="init">
+            How the performance of the plugged in code will be enforced?
+            <hint>
+            If you allow foreign code to be plugged into your own module, how
+            do you enforce that it will behave correctly and quickly and will 
not
+            negatively influence the performance of your own module?
+            </hint>
+        </question>
+-->
+ <answer id="perf-spi">
+  <p>
+   XXX no answer for perf-spi
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="perf-startup" when="final">
+            Does your module run any code on startup?
+        </question>
+-->
+ <answer id="perf-startup">
+  <p>
+   XXX no answer for perf-startup
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="perf-wakeup" when="final">
+            Does any piece of your code wake up periodically and do something
+            even when the system is otherwise idle (no user interaction)?
+        </question>
+-->
+ <answer id="perf-wakeup">
+  <p>
+   XXX no answer for perf-wakeup
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="resources-layer" when="final">
+            Does your module provide own layer? Does it create any files or
+            folders in it? What it is trying to communicate by that and with 
which
+            components?
+
+            <hint>
+            NetBeans allows automatic and declarative installation of resources
+            by module layers. Module register files into appropriate places
+            and other components use that information to perform their task
+            (build menu, toolbar, window layout, list of templates, set of
+            options, etc.).
+            </hint>
+        </question>
+-->
+ <answer id="resources-layer">
+  <p>
+   XXX no answer for resources-layer
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="resources-mask" when="final">
+            Does your module mask/hide/override any resources provided by 
other modules in
+            their layers?
+
+            <hint>
+            If you mask a file provided by another module, you probably depend
+            on that and do not want the other module to (for example) change
+            the file's name. That module shall thus make that file available 
as an API
+            of some stability category.
+            </hint>
+        </question>
+-->
+ <answer id="resources-mask">
+  <p>
+   XXX no answer for resources-mask
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="resources-preferences" when="final">
+            Does your module uses preferences via Preferences API? Does your 
module use NbPreferences or
+            or regular JDK Preferences ? Does it read, write or both ?
+            Does it share preferences with other modules ? If so, then why ?
+            <hint>
+                You may use
+                    &lt;api type="export" group="preferences"
+                    name="preference node name" category="private"&gt;
+                    description of individual keys, where it is used, what it
+                    influences, whether the module reads/write it, etc.
+                    &lt;/api&gt;
+                Due to XML ID restrictions, rather than 
/org/netbeans/modules/foo give the "name" as org.netbeans.modules.foo.
+                Note that if you use NbPreferences this name will then be the 
same as the code name base of the module.
+            </hint>
+        </question>
+-->
+ <answer id="resources-preferences">
+  <p>
+   XXX no answer for resources-preferences
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="security-grant" when="final">
+            Does your code grant additional rights to some other code?
+            <hint>Avoid using a class loader that adds extra
+            permissions to loaded code unless really necessary.
+            Also note that your API implementation
+            can also expose unneeded permissions to enemy code by
+            calling AccessController.doPrivileged().</hint>
+        </question>
+-->
+ <answer id="security-grant">
+  <p>
+   XXX no answer for security-grant
+  </p>
+ </answer>
+
+
+
+<!--
+        <question id="security-policy" when="final">
+            Does your functionality require modifications to the standard 
policy file?
+            <hint>Your code might pass control to third-party code not
+            coming from trusted domains. This could be code downloaded over the
+            network or code coming from libraries that are not bundled
+            with NetBeans. Which permissions need to be granted to which 
domains?</hint>
+        </question>
+-->
+ <answer id="security-policy">
+  <p>
+   XXX no answer for security-policy
+  </p>
+ </answer>
+
+</api-answers>
diff --git a/groovy/gradle.java/manifest.mf b/groovy/gradle.java/manifest.mf
index e7fb2ab..059c627 100644
--- a/groovy/gradle.java/manifest.mf
+++ b/groovy/gradle.java/manifest.mf
@@ -3,4 +3,4 @@ AutoUpdate-Show-In-Client: false
 OpenIDE-Module: org.netbeans.modules.gradle.java
 OpenIDE-Module-Layer: org/netbeans/modules/gradle/java/layer.xml
 OpenIDE-Module-Localizing-Bundle: 
org/netbeans/modules/gradle/java/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.1
+OpenIDE-Module-Specification-Version: 1.2
diff --git a/groovy/gradle.java/nbproject/project.xml 
b/groovy/gradle.java/nbproject/project.xml
index d2f27ff..0e7a911 100644
--- a/groovy/gradle.java/nbproject/project.xml
+++ b/groovy/gradle.java/nbproject/project.xml
@@ -308,6 +308,7 @@
             <public-packages>
                 <package>org.netbeans.modules.gradle.java.api</package>
                 <package>org.netbeans.modules.gradle.java.api.output</package>
+                <package>org.netbeans.modules.gradle.java.spi.debug</package>
             </public-packages>
             <class-path-extension>
                 
<runtime-relative-path>gradle/org.jacoco.core.jar</runtime-relative-path>
diff --git 
a/groovy/gradle.java/src/org/netbeans/modules/gradle/java/GradleJavaDebuggerImpl.java
 
b/groovy/gradle.java/src/org/netbeans/modules/gradle/java/GradleJavaDebuggerImpl.java
new file mode 100644
index 0000000..5aeda08
--- /dev/null
+++ 
b/groovy/gradle.java/src/org/netbeans/modules/gradle/java/GradleJavaDebuggerImpl.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.gradle.java;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.netbeans.api.debugger.jpda.JPDADebugger;
+import org.netbeans.api.java.classpath.ClassPath;
+import org.netbeans.api.java.platform.JavaPlatform;
+import org.netbeans.api.project.Project;
+import org.netbeans.modules.gradle.api.NbGradleProject;
+import org.netbeans.modules.gradle.api.execute.RunUtils;
+import org.netbeans.modules.gradle.java.api.ProjectSourcesClassPathProvider;
+import org.netbeans.spi.java.classpath.support.ClassPathSupport;
+import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2;
+import org.netbeans.spi.project.ProjectServiceProvider;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.util.Lookup;
+import org.openide.util.RequestProcessor;
+import org.netbeans.modules.gradle.java.spi.debug.GradleJavaDebugger;
+
+/**
+ * Provides a convenient way to attach debugger to a Gradle Project.
+ * The implementation is mostly based on MavenDebuggerImpl.
+ * 
+ * @author lkishalmi
+ */
+@ProjectServiceProvider(service = GradleJavaDebugger.class, projectType = 
NbGradleProject.GRADLE_PLUGIN_TYPE + "/java-base")
+public final class GradleJavaDebuggerImpl implements GradleJavaDebugger {
+
+    private final RequestProcessor RP = new 
RequestProcessor(GradleJavaDebuggerImpl.class);
+    final Project project;
+
+    public GradleJavaDebuggerImpl(Project project) {
+        this.project = project;
+    }
+
+    @Override
+    public void attachDebugger(String name, String transport, String host, 
String address) throws Exception {
+        final Object[] lock = new Object [1];
+        ClassPath sourcePath = getSources();
+        ClassPath jdkSourcePath = getJdkSources();
+
+        final Map properties = new HashMap();
+        properties.put("sourcepath", sourcePath); //NOI18N
+        properties.put("name", name); //NOI18N
+        properties.put("jdksources", jdkSourcePath); //NOI18N
+        properties.put("baseDir", 
FileUtil.toFile(project.getProjectDirectory())); // NOI18N
+        if (RunUtils.isCompileOnSaveEnabled(project)) {
+            properties.put ("listeningCP", "sourcepath"); // NOI18N
+        }
+
+        synchronized(lock) {
+            RP.post(new Runnable() {
+                @Override
+                public void run() {
+                    synchronized(lock) {
+                        try {
+                            // VirtualMachineManagerImpl can be initialized
+                            // here, so needs to be inside RP thread.
+                            if (transport.equals("dt_socket")) {//NOI18N
+                                try {
+                                    JPDADebugger.attach(
+                                            host,
+                                            Integer.parseInt(address),
+                                            new Object[] {properties}
+                                    );
+                                } catch (NumberFormatException e) {
+                                    throw new Exception(
+                                            "address attribute must specify 
port " + //NOI18N
+                                            "number for dt_socket 
connection"); //NOI18N
+                                }
+                            }
+                            else {
+                                    JPDADebugger.attach(
+                                            address,
+                                            new Object[] {properties}
+                                    );
+                            }
+                        } catch (Throwable e) {
+                            lock[0] = e;
+                        } finally {
+                            lock.notify();
+                        }
+                    }
+                }
+            });
+            try {
+                lock.wait();
+            } catch (InterruptedException e) {
+                throw e;
+            }
+            if (lock[0] != null)  {
+                throw new Exception("", (Throwable) lock[0]);
+            }
+
+        }
+    }
+
+    private ClassPath getJdkSources() {
+        JavaPlatform jdk = RunUtils.getActivePlatform(project).second();
+        if (jdk != null) {
+            return jdk.getSourceFolders();
+        }
+        return null;
+    }
+
+    private ClassPath getSources() {
+        ProjectSourcesClassPathProvider pgcpp = 
project.getLookup().lookup(ProjectSourcesClassPathProvider.class);
+        List<SourceForBinaryQueryImplementation2> sourceQueryImpls = new 
ArrayList<>(2);
+        
sourceQueryImpls.addAll(project.getLookup().lookupAll(SourceForBinaryQueryImplementation2.class));
+        
sourceQueryImpls.addAll(Lookup.getDefault().lookupAll(SourceForBinaryQueryImplementation2.class));
+
+        Set<FileObject> srcs = new LinkedHashSet<>();
+        for (ClassPath projectSourcePath : 
pgcpp.getProjectClassPath(ClassPath.SOURCE)) {
+            srcs.addAll(Arrays.asList(projectSourcePath.getRoots()));
+        }
+
+        for (ClassPath cp : pgcpp.getProjectClassPath(ClassPath.EXECUTE)) {
+            for (ClassPath.Entry entry : cp.entries()) {
+                URL url = entry.getURL();
+                SourceForBinaryQueryImplementation2.Result ret;
+                for (SourceForBinaryQueryImplementation2 sourceQuery : 
sourceQueryImpls) {
+                    ret = sourceQuery.findSourceRoots2(url);
+                    if (ret != null) {
+                        List<FileObject> roots = Arrays.asList(ret.getRoots());
+                        if (!roots.isEmpty()) {
+                            srcs.addAll(roots);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        FileObject[] roots = srcs.toArray(new FileObject[srcs.size()]);
+        return ClassPathSupport.createClassPath(roots);
+    }
+}
diff --git 
a/groovy/gradle.java/src/org/netbeans/modules/gradle/java/output/JDPAProcessorFactory.java
 
b/groovy/gradle.java/src/org/netbeans/modules/gradle/java/output/JDPAProcessorFactory.java
index 71f332f..3b22dbe 100644
--- 
a/groovy/gradle.java/src/org/netbeans/modules/gradle/java/output/JDPAProcessorFactory.java
+++ 
b/groovy/gradle.java/src/org/netbeans/modules/gradle/java/output/JDPAProcessorFactory.java
@@ -24,32 +24,13 @@ import org.netbeans.modules.gradle.api.execute.RunConfig;
 import org.netbeans.modules.gradle.api.output.OutputDisplayer;
 import org.netbeans.modules.gradle.api.output.OutputProcessor;
 import org.netbeans.modules.gradle.api.output.OutputProcessorFactory;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-import org.netbeans.api.debugger.jpda.DebuggerStartException;
-import org.netbeans.api.debugger.jpda.JPDADebugger;
-import org.netbeans.api.java.classpath.ClassPath;
-import org.netbeans.api.java.platform.JavaPlatform;
-import org.netbeans.api.java.platform.JavaPlatformManager;
-import org.netbeans.spi.java.classpath.support.ClassPathSupport;
-import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2;
 import org.netbeans.spi.project.ProjectServiceProvider;
-import org.openide.filesystems.FileObject;
-import org.openide.filesystems.FileUtil;
-import org.openide.util.Exceptions;
-import org.openide.util.Lookup;
-import org.openide.util.RequestProcessor;
 import org.openide.windows.IOColors;
-import org.netbeans.modules.gradle.java.api.ProjectSourcesClassPathProvider;
+import org.netbeans.modules.gradle.java.spi.debug.GradleJavaDebugger;
 
 /**
  *
@@ -58,8 +39,6 @@ import 
org.netbeans.modules.gradle.java.api.ProjectSourcesClassPathProvider;
 @ProjectServiceProvider(service = OutputProcessorFactory.class, projectType = 
NbGradleProject.GRADLE_PLUGIN_TYPE + "/java-base")
 public class JDPAProcessorFactory implements OutputProcessorFactory {
 
-    private static final RequestProcessor RP = new 
RequestProcessor("GradleDebug", 1);
-
     @Override
     public Set<? extends OutputProcessor> createOutputProcessors(RunConfig 
cfg) {
         return Collections.singleton(new JDPAOutputProcessor(cfg));
@@ -80,31 +59,13 @@ public class JDPAProcessorFactory implements 
OutputProcessorFactory {
             Matcher m = JDPA_LISTEN.matcher(line);
             if (m.matches()) {
                 String portStr = m.group(1);
-                int port = 5005;
-                try {
-                    port = Integer.parseInt(portStr);
-                } catch (NumberFormatException ex) {
-                }
-                final int finalPort = port;
-
-                if (!activated) {
-                    activated = true;
-                    RP.post(new Runnable() {
-
-                        @Override
-                        public void run() {
-                            Map<String, Object> services = new HashMap<>();
-                            services.put("name", cfg.getTaskDisplayName());
-                            services.put("baseDir", 
FileUtil.toFile(cfg.getProject().getProjectDirectory()));
-                            services.put("jdksources", getJdkSources());
-                            services.put("sourcepath", getSources());
-                            try {
-                                JPDADebugger.attach("localhost", finalPort, 
new Object[]{services});
-                            } catch (DebuggerStartException ex) {
-                                Exceptions.printStackTrace(ex);
-                            }
-                        }
-                    });
+                GradleJavaDebugger dbg = 
cfg.getProject().getLookup().lookup(GradleJavaDebugger.class);
+                if (dbg != null) {
+                    try {
+                        dbg.attachDebugger(cfg.getTaskDisplayName() , 
"dt_socket", "localhost", portStr);
+                    } catch (Exception ex) {
+                        out.print(ex.getCause().getMessage(), null, 
IOColors.OutputType.ERROR);
+                    } 
                 }
                 out.print(line, null, IOColors.OutputType.LOG_DEBUG);
                 return true;
@@ -112,44 +73,5 @@ public class JDPAProcessorFactory implements 
OutputProcessorFactory {
             return false;
         }
 
-        private ClassPath getJdkSources() {
-            JavaPlatform jdk = 
JavaPlatformManager.getDefault().getDefaultPlatform();
-            if (jdk != null) {
-                return jdk.getSourceFolders();
-            }
-            return null;
-        }
-
-        private ClassPath getSources() {
-            ProjectSourcesClassPathProvider pgcpp = 
cfg.getProject().getLookup().lookup(ProjectSourcesClassPathProvider.class);
-            List<SourceForBinaryQueryImplementation2> sourceQueryImpls = new 
ArrayList<>(2);
-            
sourceQueryImpls.addAll(cfg.getProject().getLookup().lookupAll(SourceForBinaryQueryImplementation2.class));
-            
sourceQueryImpls.addAll(Lookup.getDefault().lookupAll(SourceForBinaryQueryImplementation2.class));
-
-            Set<FileObject> srcs = new LinkedHashSet<>();
-            for (ClassPath projectSourcePath : 
pgcpp.getProjectClassPath(ClassPath.SOURCE)) {
-                srcs.addAll(Arrays.asList(projectSourcePath.getRoots()));
-            }
-
-            for (ClassPath cp : pgcpp.getProjectClassPath(ClassPath.EXECUTE)) {
-                for (ClassPath.Entry entry : cp.entries()) {
-                    URL url = entry.getURL();
-                    SourceForBinaryQueryImplementation2.Result ret;
-                    for (SourceForBinaryQueryImplementation2 sourceQuery : 
sourceQueryImpls) {
-                        ret = sourceQuery.findSourceRoots2(url);
-                        if (ret != null) {
-                            List<FileObject> roots = 
Arrays.asList(ret.getRoots());
-                            if (!roots.isEmpty()) {
-                                srcs.addAll(roots);
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-            FileObject[] roots = srcs.toArray(new FileObject[srcs.size()]);
-            return ClassPathSupport.createClassPath(roots);
-        }
-
     }
 }
diff --git 
a/groovy/gradle.java/src/org/netbeans/modules/gradle/java/spi/debug/GradleJavaDebugger.java
 
b/groovy/gradle.java/src/org/netbeans/modules/gradle/java/spi/debug/GradleJavaDebugger.java
new file mode 100644
index 0000000..b68ede3
--- /dev/null
+++ 
b/groovy/gradle.java/src/org/netbeans/modules/gradle/java/spi/debug/GradleJavaDebugger.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.gradle.java.spi.debug;
+
+/**
+ * Instance would be found in the project's lookup allow to attach debugger
+ * to the project. This is essentially the same as MavenDebugger for Maven
+ * projects.
+ * 
+ * @since 1.2
+ */
+public interface GradleJavaDebugger {
+
+    /**
+     * Attaches a Java Debugger session to the project.
+     * 
+     * @param name the name of the session.
+     * @param transport the transport to attach to the JVM
+     * @param host the host where the debugee process is running
+     * @param address the address (usually port number) where the debugee 
process is listening.
+     * @throws Exception if the debug session cannot be started.
+     */
+    void attachDebugger(String name,
+            final String transport,
+            final String host,
+            final String address) throws Exception;
+
+}
diff --git a/groovy/gradle.javaee/nbproject/project.xml 
b/groovy/gradle.javaee/nbproject/project.xml
index c34e418..1d94854 100644
--- a/groovy/gradle.javaee/nbproject/project.xml
+++ b/groovy/gradle.javaee/nbproject/project.xml
@@ -38,7 +38,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>1.0</specification-version>
+                        <specification-version>1.2</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git 
a/groovy/gradle.javaee/src/org/netbeans/modules/gradle/javaee/action-mapping.xml
 
b/groovy/gradle.javaee/src/org/netbeans/modules/gradle/javaee/action-mapping.xml
index 6a0d7a3..2b9cdd3 100644
--- 
a/groovy/gradle.javaee/src/org/netbeans/modules/gradle/javaee/action-mapping.xml
+++ 
b/groovy/gradle.javaee/src/org/netbeans/modules/gradle/javaee/action-mapping.xml
@@ -25,6 +25,9 @@
         <action name="run">
             <args>war</args>
         </action>
+        <action name="debug">
+            <args>war</args>
+        </action>
     </apply-for>
 </actions>
 
diff --git 
a/groovy/gradle.javaee/src/org/netbeans/modules/gradle/javaee/execute/DeployHook.java
 
b/groovy/gradle.javaee/src/org/netbeans/modules/gradle/javaee/execute/DeployHook.java
index 44db5b3..905cea2 100644
--- 
a/groovy/gradle.javaee/src/org/netbeans/modules/gradle/javaee/execute/DeployHook.java
+++ 
b/groovy/gradle.javaee/src/org/netbeans/modules/gradle/javaee/execute/DeployHook.java
@@ -16,7 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.netbeans.modules.gradle.javaee.execute;
 
 import org.netbeans.modules.gradle.api.NbGradleProject;
@@ -25,15 +24,20 @@ import 
org.netbeans.modules.gradle.spi.actions.AfterBuildActionHook;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.URL;
+import java.util.concurrent.Callable;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.util.prefs.Preferences;
 import org.netbeans.api.project.Project;
 import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment;
 import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
+import org.netbeans.modules.j2ee.deployment.plugins.api.ServerDebugInfo;
 import org.netbeans.modules.web.browser.spi.URLDisplayerImplementation;
 import org.netbeans.spi.project.ProjectServiceProvider;
 import org.openide.awt.HtmlBrowser;
 import org.openide.util.Exceptions;
 import org.openide.util.Lookup;
+import org.netbeans.modules.gradle.java.spi.debug.GradleJavaDebugger;
 
 /**
  *
@@ -42,6 +46,7 @@ import org.openide.util.Lookup;
 @ProjectServiceProvider(service = AfterBuildActionHook.class, projectType = 
NbGradleProject.GRADLE_PLUGIN_TYPE + "/war")
 public class DeployHook implements AfterBuildActionHook {
 
+    private static final Logger LOGGER = 
Logger.getLogger(DeployHook.class.getName());
     final Project project;
 
     public DeployHook(Project project) {
@@ -53,13 +58,43 @@ public class DeployHook implements AfterBuildActionHook {
         if ("run".equals(action) && (result == 0)) {
             deploy(out, Deployment.Mode.RUN);
         }
+        if ("debug".equals(action) && (result == 0)) {
+            deploy(out, Deployment.Mode.DEBUG);
+        }
     }
 
     private void deploy(PrintWriter out, Deployment.Mode mode) {
         J2eeModuleProvider jmp = 
project.getLookup().lookup(J2eeModuleProvider.class);
+        Callable<Void> debuggerHook = null;
+        if (mode == Deployment.Mode.DEBUG) {
+            debuggerHook = () -> {
+                ServerDebugInfo sdi = jmp.getServerDebugInfo();
+
+                if (sdi != null) { 
+                    String h = sdi.getHost();
+                    String transport = sdi.getTransport();
+                    String address;
+
+                    if (transport.equals(ServerDebugInfo.TRANSPORT_SHMEM)) {
+                        address = sdi.getShmemName();
+                    } else {
+                        address = Integer.toString(sdi.getPort());
+                    }
+                    GradleJavaDebugger deb = 
project.getLookup().lookup(GradleJavaDebugger.class);
+                    try {
+                        deb.attachDebugger("Debug Deployed app", transport, h, 
address); // NOI18N
+                    } catch (Exception ex) {
+                        LOGGER.log(Level.FINE, "Exception occured while trying 
to attach debugger", ex); //NOI18N
+                    }
+                }
+                return null;
+            };
+        }
         try {
             String showPage = showBrowserOnRun();
-            String browserUrl = Deployment.getDefault().deploy(jmp, mode, 
null, showPage == null ? "" : showPage, true);
+            String browserUrl = Deployment.getDefault().deploy(jmp, mode, 
null, showPage == null ? "" : showPage, true, (String message) -> {
+                out.println(message);
+            }, debuggerHook);
             if (browserUrl != null) {
                 URL url = new URL(browserUrl);
                 if (showPage != null) {
@@ -76,7 +111,7 @@ public class DeployHook implements AfterBuildActionHook {
 
                 }
             }
-        } catch (Deployment.DeploymentException|IOException ex) {
+        } catch (Deployment.DeploymentException | IOException ex) {
             Exceptions.printStackTrace(ex);
         }
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org
For additional commands, e-mail: commits-h...@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to