Debug remote Mule server applications in Eclipse

Normally, I debug mule applications using the Debug as Mule Application option in Anypoint Studio. However, I recently started on an existing mule project that does not run within Anypoint Studio.

I have set up my development environment using eclipse as my IDE, deploying into a mule standalone server, and debugging via Java Debug Wire Protocol (JDWP). JDWP is the protocol used for communication between a debugger and the Java VM which it debugs. In other words, it allows you to set breakpoints, step, evaluate expressions in Java applications running within the target server container, outside eclipse.

First, the mule server must be set up to run in debug mode. Open wrapper.conf and uncomment (or add) the following entries

wrapper.java.additional.1=-Xdebug
wrapper.java.additional.2=-Xnoagent
wrapper.java.additional.3=-Djava.compiler=NONE
wrapper.java.additional.4=-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005

When the mule server is next started, there should be an entry in wrapper.log showing the server is running in debug mode:

Listening for transport dt_socket at address: 5005

To debug in eclipse, go to Run -> Debug Configurations. Create a new debug configuration for Remote Java Application. Set the port as 5005. Hit the Debug button and eclipse will attempt to connect to the mule server. Sometimes, eclipse does not switch to the Debug perspective automatically. To do so manually, go to Window -> Perspective -> Open Perspective -> Debug.

Initially, I made the mistake of deploying my mule applications in zipped files. When I tried to connect to the mule server within eclipse, I get the following errors

  • Hot code replace failed – Scheme change not implemented
  • Hot code replace failed – delete method not implemented

To say they are cryptic is an understatement! This error basically says the IDE cannot hot deploy code in the target VM, which is needed when you debug a remote Java application. You must use the same compiler for both the IDE and the application files running on the remote Java server. And this includes not letting the remote server to ‘explode’ an application during deployment. The simplest way to set this up is to use the maven install step to copy the application files to the mule server, and then run maven within eclipse.

To undeploy the previous installation, delete the anchor file in the mule server apps directory. Never delete a deployed application directory manually. Always let mule do the deletion. This intervenes with mule’s hot deployment layer and can lead to jar locking problems.

PS. I’m running mule standalone server 3.4 and eclipse mars 4.5.

Installing Anypoint Studio Plug-in 5.3.0 in Eclipse Mars

Installing anypoint studio should be a straight forward process, according to the official documentation on the mulesoft website. You add mulesoft to the list of available software site, select anypoint studio, click finish. Eclipse install software wizard should, theoretically, pull in required dependencies.

However, it didn’t work. I got the following exception

No repository found containing: osgi.bundle,org.eclipse.m2e.archetype.common,1.6.2.20150902-0001
….

I had a Java EE installation of Eclipse Mars (4.5). It already included maven support via m2e-wtp. Anypoint studio wasn’t happy with this version of m2e, and was also unable to pull in the required version of m2e itself. I had to manually add m2e’s update site http://download.eclipse.org/technology/m2e/releases and install m2e. After that, anypoint studio was installed without a problem.

Mule Studio and Maven Profiles

The maven project I’m working on has profiles for different environments, such as testing, development and deployment.

<profiles>
	<profile>
		<id>test</id>
		<activation>
			<activeByDefault>true</activeByDefault>
		</activation>
		<properties>
			<db.host>testdb.mycompany.com</db.host>
			<db.name>projectx</db.name>
		</properties>
	</profile>

	<profile>
		<id>development</id>
		<properties>
			<db.host>127.0.0.1</db.host>
		</properties>
	</profile>
</profiles>

To activate multiple profiles at run time, you use the command line option -P
mvn test -P test,development

Or inside eclipse with m2e, you can configure a list of active profiles under Run Configurations.

However, with Mule Studio, if you run the project as a Mule Application with Maven, there are no options to select maven profiles.

The way to get around this is to edit the maven profiles to be activated by a property or a file. In my case, I updated my pom.xml to

<profiles>
	<profile>
		<id>Test</id>
		<activation>
			<activeByDefault>true</activeByDefault>
			<property>
				<name>env</name>
				<value>test</value>
			</property>
		</activation>
		<properties>
			<db.host>testdb.mycompany.com</db.host>
			<db.name>projectx</db.name>
		</properties>
	</profile>

	<profile>
		<id>Development</id>
		<activation>
			<file>
				<exists>.git</exists>
			</file>
		</activation>
		<properties>
			<db.host>127.0.0.1</db.host>
		</properties>
	</profile>
</profiles>

The test profile is activated by setting the system property env to test. This is done in Mule Studio under Windows -> Preferences -> Mule Studio -> Maven Settings. In the “MAVEN_OPTS environment variable” text box, add -Denv=test. The development profile is activated by the existence of a .git file in the project root. Now when I run this as a mule+maven project in eclipse, the properties from both of these profiles are available.

You might ask wouldn’t it be easier to just add -P test,development to the MAVEN_OPTS text box? Yes it would definitely be, but mule studio complained about -P being an unrecognized option.

PS. I’m using mule studio 3.5.