Contact Us 1-800-596-4880

Upgrading Java for Custom Connectors (Customers)

This guide applies to MuleSoft customers only. If you are a MuleSoft partner, see Upgrading Java for Custom Connectors (Partners).

Upgrade, test, and release your custom connectors for Java 17 to ensure compatibility within the MuleSoft ecosystem. Ensuring this compatibility is crucial because running an incompatible connector can lead to runtime failures, decreased performance, and security vulnerabilities that could impact your app’s stability.

Before You Begin

Before upgrading and testing your custom connector for Java 17, you must be familiar with the following considerations:

  • Target compilation level

    The maximum supported version for running your applications is Java 17 for Mule runtime 4.6.x and later. During the packaging of your app, all code, including third-party dependencies, must be compiled for Java 8.

    Because you must compile your custom connector with Java 8, use the Java compiler configuration from the Java SDK parent POM. You can’t use language features from Java 11 or Java 17.

    If you change the compilation to Java 17, the surrounding tooling (such as Studio, Maven plugins, DataSense, or connectivity testing, and so on) breaks because they are still running on Java 8.

  • Unsupported directives

    Don’t set -add-opens or -add-export directives. These directives are not allowed in CloudHub or Runtime Fabric, require managing them for each connector across all environments, and introduce a backward compatibility burden, complicating future Java upgrades and potentially enabling security vulnerabilities.

  • Minimum Mule version

    If your custom connector is running on Mule 4.5.x or earlier, you can’t run Java 17 tests that extend the MuleArtifactFunctionalTestCase, but you can still run Java 8 tests.

    To decouple the minimum Mule version when running tests, add the -Dmunit.jvm parameter to use Java 17 as described in Test Your Custom Connector with MUnit.

Upgrade Your Custom Mule SDK Connectors

Upgrade your custom Mule SDK (Java SDK and XML SDK) connectors to Java 17.

Upgrade Third-Party Libraries

Your custom connector likely relies on third-party libraries, so it’s important to ensure they are compatible with Java 17 as well. Even if your custom connector passes tests, it is still important to deliver secure and reliable software. If a critical bug or vulnerability is found, you must upgrade to a fixed version. Using up-to-date libraries that explicitly support Java 17 makes this process easier and more reliable, as the vendor has already tested them on Java 17.

Upgrade the third-party libraries of your custom connector to be compatible with Java 17:

  • Java EE libraries

    Mule 4.6.x exposes Java EE libraries differently than earlier Mule versions. You must add the BOM dependency to your custom connector and, if applicable, exclude the provided conflicting library. You can also add the libraries in the BOM dependency separately.

    <properties>
     <muleJavaEeBomVersion>4.6.0</muleJavaEeBomVersion>
    </properties>
    <dependencyManagement>
     <dependencies>
       <dependency>
         <groupId>org.mule</groupId>
         <artifactId>mule-javaee-runtime-bom</artifactId>
         <version>${muleJavaEeBomVersion}</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
     </dependencies>
    </dependencyManagement>

    For more information, see Java EE Libraries.

  • External libraries

    Upgrade external libraries, which are third-party libraries that are not bundled with your custom connector. Some examples include a JDBC driver, JMS broker client, or Groovy runtime. The following example shows a JDBC driver external library configuration:

    @ExternalLib(name = "MySQL JDBC Driver",
    description = "A JDBC driver that supports connection to the MySQL Database",
    nameRegexpMatcher = "(.*)\\.jar",
    requiredClassName = "com.mysql.jdbc.Driver",
    coordinates = "mysql:mysql-connector-java:5.1.44")
    public class MySqlConnectionProvider implements ConnectionProvider<Connection> {
      //
    }

    You must update your external libraries to a version that is compatible with Java 17.

Review Your Code

After you compile your custom connector with Java 8, ensure you can run your custom connector with Java 17. Reviewing your code is important because some restrictions are flagged as warnings in Java 11 but are flagged as failures and can’t be disabled in Java 17. For example, reflection is more restricted in Java 17, so you must review your code to ensure there are no illegal actions.

To help you review your code, learn more about the different changes in Java 17:

  • JDK Migration Guide

    See the Oracle JDK Migration Guide for a full list of the changes made in Java 17. Use the guide to assess the impact to your code.

  • Mule runtime engine

    See Mule runtime to learn more about the Java 17 changes made in Mule runtime engine.

    • Reflection on Java classes

      To ensure compatibility with Java 17, review and update any code that uses reflection to access Java classes or set parameter values. Java 17 imposes stricter access controls, so you should avoid introspecting JDK internals. Ensure you have a robust test suite and make sure it is run with Java 17.

    • Serialization

      Update your serialization code to accommodate the restrictions of Java 17. If your code uses libraries like Gson for serializing classes, switch to using Data Transfer Objects (DTOs) where reflective access to JDK classes is involved. Ensure that serialization libraries are updated and adjust your code to minimize reliance on reflection. For more information, refer to Configure Custom Serializers.

    • Library upgrades

      Upgrade your libraries to versions compatible with Java 17. This includes updating ByteBuddy to version 1.14.0, Jacoco to 0.8.10, and SLF4J to version 2.x. Replace CGLib with ByteBuddy and check for updates to other libraries like Groovy and JRuby. Verify that all dependencies are compatible with Java 17 to avoid runtime issues.

    • Changes with running the test suite

      Adapt your testing approach for Java 17. If you use Mockito, be aware that Mockito can’t mock JVM classes. Consider custom implementations for mocking and switch from PowerMock to newer Mockito versions. Update your tests to handle the changes in Java 17 and avoid deprecated methods.

    • Java Platform Module System (JPMS)

      JPMS introduces stricter encapsulation, impacting how Mule modules interact with JDK classes. As Mule upgrades to Java 17 and JPMS, the following changes are necessary:

      • Refactor Split Packages: Resolve issues with internal and API package splits by reorganizing and refactoring packages to conform with JPMS modularization standards.

      • Address ResourceBundle Loading: Implement solutions for issues related to resource bundle loading, such as using ResourceBundleProvider or alternative methods.

Add Missing Code

Because reflection is more restricted in Java 17, API objects now require setters. Previously with Java 8, it was enough for API objects to only have default constructors and getters for all DataWeave accessible properties. Now, API objects must also have setters so DataWeave can write those properties without using reflection.

Constructors and setters are required if your class is instantiated by DataWeave, and getters are required if your class is read. If your class is returned and not instantiated, only getters are required. However, using both getters and setters simplifies the validation and certification process.

Upgrade Your Custom Configuration Properties Providers

To upgrade your custom configuration properties provider to be compatible with Java 17, switch to use Java SDK and use the @JavaVersionSupport annotation as explained in Release Your Custom Connector. You must also perform all the steps described in Upgrading Java for Custom Connectors (Customers), just like with any custom connector. The example custom configuration properties provider mentioned in Example: Mule SDK Module is updated to support Java 17. Refer to that example to update your custom configuration properties provider. For more details about what the changed code looks like (including migrating tests to MUnit), refer to this changeset.

Alternatively, if switching to using Java SDK involves too many changes for you, add a declaration using ExtensionDeclarer inside ExtensionLoadingDelegate in your custom configuration properties provider. For more details about what the changed code looks like, refer to this changeset.

Test Your Custom Connector with MUnit

Run your MUnit tests to test compatibility of your connector against Java 17. Ensure your local JDK version is 17.

  1. Open the pom.xml file of your Mule app.

  2. Replace the mule-maven-plugin version with the ${mule.maven.plugin.version} parameter.

  3. If you haven’t already, add the munit-maven-plugin. Replace the version with the ${munit.version} parameter and replace runtimeVersion with the ${app.runtime} parameter.

    	<plugin>
    		<groupId>com.mulesoft.munit.tools</groupId>
    		<artifactId>munit-maven-plugin</artifactId>
    		<version>${munit.version}</version>
    		<executions>
    			<execution>
    				<id>test</id>
    				<phase>test</phase>
    				<goals>
    					<goal>test</goal>
    					<goal>coverage-report</goal>
    				</goals>
    			</execution>
    		</executions>
    		<configuration>
    			<coverage>
    				<runCoverage>true</runCoverage>
    				<formats>
    					<format>html</format>
    				</formats>
    			</coverage>
    			<runtimeVersion>${app.runtime}</runtimeVersion>
    			<dynamicPorts>
    				<dynamicPort>http.port</dynamicPort>
    			</dynamicPorts>
    		</configuration>
    	</plugin>
    MUnit 3.1 is compatible only with Mule runtime 4.3.0 and later. If your connector is compatible with Mule runtime 4.2.0 and earlier, you must create a legacy profile that overrides the MUnit version.
  4. If you have MUnit dependencies, such as munit-runner and munit-tools, replace the version for each dependency with the ${munit-version} parameter.

  5. Replace the version for each connector dependency with the Java 17 compatible version of the connector.

  6. Open a terminal window in the root of your Mule project and run the following command:

    mvn -f pom.xml -s ~/.m2/settings.xml -Dapp.runtime=4.6.0 -Dmunit.version=3.1.0 -Dmule.maven.plugin.version=4.1.0 -fae test

You can now see if your connector is compatible with Java 17. For more information about running MUnit tests, refer to MUnit.

The Mule runtime version you use determines the version of the mule-modules-parent. For example, if you use Mule runtime 4.6.0, you must use mule-modules-parent 1.6.0. Minor versions maintain a correspondence, such as Mule runtime 4.1.0 with mule-modules parent 1.1.0, Mule runtime 4.2.0 with mule-modules-parent 1.2.0, and so forth.

Java 17 is supported with Mule runtime 4.6.0 and later. However, a connector can be compatible with both Mule 4.3.0 and Java 17 simultaneously. If your connector must be compatible with Mule 4.3.0, its mule-modules-parent version cannot exceed 1.3.0. You don’t necessarily need to use mule-modules-parent 1.6.0 for your connector to be compatible with Java 17. Using mule-modules-parent 1.6.0 is specifically required to leverage other features from the Mule runtime 4.6.0 in the connector.

Release Your Custom Connector

After you update your code and your tests are green, you are ready to release a new Java 17-compatible version of your custom connector.

  1. To communicate Java 17 compatibility, generate metadata for Java compatibility of your custom connector by adding or upgrading the custom connector mule-sdk-api dependency to the latest version:

    <dependency>
       <groupId>org.mule.sdk</groupId>
       <artifactId>mule-sdk-api</artifactId>
       <version>0.10.1</version>
    </dependency>
  2. For Java SDK, add the @JavaVersionSupport annotation in the same class as the @Extension annotation and include the JAVA_17 value, for example:

    You don’t need to add any annotations for XML SDK because XML SDK modules are Java 17 compatible and inherit the property automatically.
    @Extension(name = "Database")
    @Operations(...)
    @JavaVersionSupport({JAVA_8, JAVA_11, JAVA_17})
    public class DatabaseConnector {
    ..
    }

In Mule 4.5.0 and later, custom connectors that don’t specify the @JavaVersionSupport annotation are assumed to be compatible with Java 8 and Java 11.

You can mark your custom connector as compatible with Java 17 only; however, you must ensure that no adoption or backward compatibility issues exist.

When you deploy a Mule app, Mule verifies that all modules in the Mule app are compatible with the Java version. If Mule finds an incompatibility, Mule throws an error and the application does not deploy.

If you receive an error message specific to an XML SDK based connector, such as Extension 'module-error-handler-plugin' does not support Java 17. Supported versions are: [1.8, 11], this means that your Mule app still contains some connectors that are not compatible with Java 17. To resolve this error, upgrade all connectors in your Mule app to be compatible with Java 17.

If your code is compatible with Java 17 but you don’t declare Java 17 compatibility, you can still get a successful test run.

To run a quick check on your custom connector or if all dependencies are not ready, pass the following argument to skip hard checks on the Java support declaration:

-M-Dmule.jvm.version.extension.enforcement=LOOSE

For more information, see Java Version Support.

See Also