10

I have a project in Eclipse which, after assembly has a package structure of the following

launcher.tar.gz
 |-- launcher.jar
 |-- lib/
 |-- resources/
 |-- plugins/

Which is achieved using the maven-assembly-plugin.

For the application to properly start, some of resources are required, but not available outside of the final assembly, additionally, I would like to have the ability to install plugins as I currently do.

My current workflow is

$ mvn [clean] package
$ cd target/launcher/
$ java -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -jar launcher.jar

Once the application has launched in a suspended state, I can attach the debugger and resume my normal workflow.

How can I streamline this process from Eclipse?

I can launch this from my Launcher.java class, but when debugging in Eclipse, I do not have the ability to install plugins via this method.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Matt Clark
  • 27,671
  • 19
  • 68
  • 123
  • are you looking at doing something similar (or exactly) as remote debugging your application? http://javarevisited.blogspot.ca/2011/02/how-to-setup-remote-debugging-in.html – blurfus Feb 25 '17 at 20:58
  • Remote debugging is how I currently do it. I would like to simply be able to click the run button from within eclipse, not external commands, then remote debugging. – Matt Clark Feb 25 '17 at 21:03
  • So, does the article in the link help at all? – blurfus Feb 25 '17 at 21:06
  • Sorry, no, this appears to be exactly how I am _currently_ doing things. I would like to avoid having to do a manual `mvn package && tar extrace && java -jar w/debug opts`. I would like eclipse to do all of this for me. – Matt Clark Feb 25 '17 at 21:18

3 Answers3

2

The following is one way to perhaps do what you want, with examples for Windows. Part of the idea is from here.

I believe there are two ways to perform the external commands with a button in eclipse. One is a custom external tool configuration, the other can possibly be accomplished with a run configuration for maven in eclipse. I'll show the external tool config first:

The idea is to create a batch file in the root of your project directory and run it from eclipse by creating a new External Tools program configuration.

So for example, you have launcher.bat in your project directory with the following script:

call mvn clean package
call cd target/
call "C:\Program Files\Java\{jdkfolder}\bin\cjava.bat" -{your debug options} -jar launcher.jar


Where cjava.bat is another batch file you need to create with the following script:

start /wait cmd.exe /c java %*


Then your external program launch config could look like this, although i'm sure you would rather set the working directory explicitly so you don't have to highlight the project when you click run.

external tools config



Set the launch parameters in the common tab to your choosing

enter image description here

Add this external config to your favorites so its easy to access (the external tools button should be on the taskbar already).


The alternative to this, if you really want to be able to do this by using a Run Command instead, is to set up a maven exec configuration (exec-maven-plugin) and call the script file that way with something like this, though i haven't tried it.

<plugin>
                <artifactId>exec-maven-plugin</artifactId>
                <groupId>org.codehaus.mojo</groupId>
                <executions>
                    <execution>
                        <id>Launcher Remote Debug</id>
                        <phase>package</phase>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <executable>${basedir}/launcher.bat</executable>
                </configuration>
            </plugin>

Then you'll just remove the call for mvn clean package in the script file so you don't end up in an infinite loop.

Community
  • 1
  • 1
  • My final solution looks a little bit different to be able to support multi platform / version upgrades, however I did build off of this implementation, thanks. I will give you the bounty, and post my final solution. – Matt Clark Mar 05 '17 at 05:29
1

So I never tried this but here is How I would give it a shot:

In your project, parallel to pom.xml, add a build.xml (Ant script) with following content:

<project>
<target name="mytarget" description="runs my class" >
<java jar="target/launcher/launcher.jar"
       fork="true"
       failonerror="true"
       maxmemory="128m"
       >
</java>
</target>
</project>

Now In Eclipse go to Run->External Tools->External Tools Configurations

Create a new configuration under "Ant Build"

Under Buildfile select the complete path of your build.xml

Under the Targets the Target "mytarget" should be auto selected. Just make sure it is checked.

Under the JRE tab pass your VM arguments

-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000

Now click on Run. If successful, attach your debugger. You can further automate it by configuring the Build tab. I would actually configure the Build tab to run "mvn clean package". But come on you have an ant script now. Do whatever you want :-)

htulsiani
  • 344
  • 1
  • 8
  • If the JVM arguments are not passed to your jar that may be bacuse of that "fork=true" in the ant script. In that case I would add following before : – htulsiani Mar 02 '17 at 09:52
0

Following the advice of Braheem, I was able to accomplish this using the exec-maven-plugin plugin, however I changed up a bit to make it more platform independent.

Using the profile definitions from this answer, I can use ${script.extension} to swap between .sh and .bat

I have the following plugin definition that I can execute using the verify target, which will eventually become a custom target entirely.

<plugin>
    <artifactId>exec-maven-plugin</artifactId>
    <groupId>org.codehaus.mojo</groupId>
    <version>1.5.0</version>

    <executions>
        <execution>

            <id>Application Launcher</id>
            <phase>verify</phase>
            <goals>
                <goal>exec</goal>
            </goals>
        </execution>
    </executions>

    <configuration>
        <executable>"${project.build.directory}\${project.artifactId}-${project.version}\bin\launcher${script.extension}"</executable>

        <arguments>
            <argument>${flags}</argument>
        </arguments>
    </configuration>
</plugin>

With the above plugin definition, I have available

# Launch
mvn package verify
# Calls [ launcher.bat ]

# Launch with debug flag
mvn package verify -Dflags=--debug
# Calls [ launcher.bat --debug ]

Then from my scripts, I can handle the --debug flag, and if necessary, modify the launch command.

...

IF "%1"=="--debug" (

        REM add VM arguments to suspend the JVM and wait for debugger to attach
        SET vmOpts=%vmOpts% -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000

        REM some additional arguments to send to my application
        SET extOpts=%extOpts% --debug --console
)

...

REM start the launcher.jar app with assemble arguments
START java %vmOpts% -jar launcher.jar %extOpts%

From with Eclipse, I now have 3 launch targets.

Standard Launch

A standard launch can be run by just running

mvn package verify

To debug, I require now two launch targets

Launch Debug

mvn package verify -Ddebug=--debug

This will cause the application to launch, and hang, waiting for the debugger to attach, from this point, I can run the second target from eclipse, which is simply configured to

Launch Debug Attach

This launch target simply connects to a remote application, as described in Eclipse's documentation.

Running this target connects to the running jvm, and the userspace code is resumed, allowing me to debug as normal - while the application is running out of the compiled dist directory.


Following this answer, I can simply export the three launch configurations, and commit them with the launcher itself, allowing new users of the repository to simply import the targets and be ready to go in seconds.

Community
  • 1
  • 1
Matt Clark
  • 27,671
  • 19
  • 68
  • 123