How to let Gradle Wrapper use some random JMX-port?

Hi all,

I’m using Tomcat 8 with Jenkins to build and test some Gradle-based projects. Recently I needed to debug memory related problems within Tomcat and enabled JMX for that in a way so that I’m able to use JMX through some SSH-tunnel:

JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote=true"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.host=[...]"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.port=7091"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.authenticate=false"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.ssl=false"

That setup now leads to my Gradle-projects failing with the following error:

[workspace] $ /bin/sh -xe /tmp/tomcat8-tomcat8-tmp/jenkins983412427873347280.sh
+ export GRADLE_USER_HOME=/home/jenkins/.gradle
+ GRADLE_USER_HOME=/home/jenkins/.gradle
+ cd de.am_soft.docbeam.raw.server
+ ./gradlew check
Error: Exception thrown by the agent : java.rmi.server.ExportException: Port already in use: 7091; nested exception is: 
		java.net.BindException: Address already in use (Bind failed)
sun.management.AgentConfigurationError: java.rmi.server.ExportException: Port already in use: 7091; nested exception is: 
		java.net.BindException: Address already in use (Bind failed)
		at sun.management.jmxremote.ConnectorBootstrap.startRemoteConnectorServer(ConnectorBootstrap.java:480)
		at sun.management.Agent.startAgent(Agent.java:262)
		at sun.management.Agent.startAgent(Agent.java:452)
Caused by: java.rmi.server.ExportException: Port already in use: 7091; nested exception is: 
		java.net.BindException: Address already in use (Bind failed)
		at sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:346)
		at sun.rmi.transport.tcp.TCPTransport.exportObject(TCPTransport.java:254)
		at sun.rmi.transport.tcp.TCPEndpoint.exportObject(TCPEndpoint.java:411)
		at sun.rmi.transport.LiveRef.exportObject(LiveRef.java:147)
		at sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:237)
		at sun.rmi.registry.RegistryImpl.setup(RegistryImpl.java:213)
		at sun.rmi.registry.RegistryImpl.<init>(RegistryImpl.java:173)
		at sun.management.jmxremote.SingleEntryRegistry.<init>(SingleEntryRegistry.java:60)
		at sun.management.jmxremote.ConnectorBootstrap.exportMBeanServer(ConnectorBootstrap.java:812)
		at sun.management.jmxremote.ConnectorBootstrap.startRemoteConnectorServer(ConnectorBootstrap.java:468)
		... 2 more
Caused by: java.net.BindException: Address already in use (Bind failed)
		at java.net.PlainSocketImpl.socketBind(Native Method)
		at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
		at java.net.ServerSocket.bind(ServerSocket.java:375)
		at java.net.ServerSocket.<init>(ServerSocket.java:237)
		at sun.management.jmxremote.ConnectorBootstrap$HostAwareSocketFactory.createServerSocket(ConnectorBootstrap.java:864)
		at sun.rmi.transport.tcp.TCPEndpoint.newServerSocket(TCPEndpoint.java:666)
		at sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:335)
		... 11 more
Build step 'Execute shell' marked build as failure

If I add the same JMX-related config like above, only with a different port to the Jenkins-config of my Gradle-project things work again. The problem is that all Gradle-projects need different ports of course and I would like to avoid needing to configure those things additionally per project in Jenkins. Jenkins provides a plugin called Port Allocator which can be used to forward random ports from the outside.

So what is the best way to handle this? Does the wrapper really need JMX at all or can that be disabled? Is it able to use some random port on its own already? How do others deal with those problems and running multiple projects on the same host at the same time?

Thanks!