Contenido principal

Deploy MATLAB Class that Inherits from MATLAB Handle Class

R2026b

Data API: MATLAB® Data Array for Java®

This example shows how to package a MATLAB class that inherits from a MATLAB handle class and deploy it to a Java application. It uses the MATLAB Data API for Java for managing data exchange between the MATLAB code and the Java application. The workflow is supported on Windows®, Linux®, and macOS.

Prerequisites

  • Create a new work folder that is visible to the MATLAB search path. This example uses a folder named work.

  • Verify that you have set up a Java development environment. For details, see Set Up Java Development Environment.

  • Verify that you have met all of the MATLAB Compiler SDK™ Java target requirements. For details, see MATLAB Compiler SDK Java Target Requirements.

  • End users must have an installation of MATLAB Runtime to run the application. For details, see Download and Install MATLAB Runtime.

    For testing purposes, you can use an installation of MATLAB instead of MATLAB Runtime.

Data Management

To exchange data between the deployed MATLAB code and the Java application, use the MATLAB Data API for Java. This API is also used by MATLAB Engine. For details, see Java Data Type Conversions.

Create MATLAB Class That Inherits from MATLAB Handle Class

Create a MATLAB file named BankAccount.m with the following code:

classdef BankAccount < handle
    % BankAccount - A class for managing a bank account.
    %
    % This class provides methods to deposit, withdraw, and check the 
    % balance of a bank account.
    %
    % BankAccount Properties:
    %   Balance - The current balance of the account (private access).
    %
    % BankAccount Methods:
    %   BankAccount - Constructor, initializes account with a balance.
    %   deposit - Deposit money into the account.
    %   withdraw - Withdraw money from the account.
    %   checkBalance - Check the current balance of the account

    properties (Access = private)
        Balance (1,1) double {mustBeReal}
    end
    
    methods
        % Constructor to initialize the account with a balance
        function obj = BankAccount(initialBalance)
            arguments (Input)
                initialBalance (1,1) double {mustBeReal}
            end
            if nargin == 0
                initialBalance = 0;
            end
            obj.Balance = initialBalance;
        end
        
        % Method to deposit money
        function deposit(obj, amount)
            arguments (Input)
                obj (1,1) BankAccount
                amount (1,1) double {mustBeReal}
            end
            if amount > 0
                obj.Balance = obj.Balance + amount;
            else
                error('Amount must be positive');
            end
        end
        
        % Method to withdraw money
        function withdraw(obj, amount)
            arguments (Input)
                obj (1,1) BankAccount
                amount (1,1) double {mustBeReal}
            end
            if amount <= obj.Balance && amount > 0
                obj.Balance = obj.Balance - amount;
            else
                error('Insufficient funds or invalid amount');
            end
        end
        
        % Method to check the balance
        function bal = checkBalance(obj)
            arguments (Input)
                obj (1,1) BankAccount
            end
            arguments (Output)
                bal (1,1) double {mustBeReal}
            end
            bal = obj.Balance;
        end
    end
end

Test the MATLAB class at the command prompt.

%% Create a new bank account with an initial balance of 100
account = BankAccount(100);

%% Deposit 50 into the account
account.deposit(50);
disp(['Balance after deposit: ', num2str(account.checkBalance())]);

%% Withdraw 30 from the account
account.withdraw(30);
disp(['Balance after withdrawal: ', num2str(account.checkBalance())]);

%% Create a joint account that references the same existing account
jointAccount = account;

%% Deposit 20 using the shared reference
jointAccount.deposit(20);
disp(['Balance from sharedAccount: ', num2str(jointAccount.checkBalance())]);
disp(['Balance from original account: ', num2str(account.checkBalance())]);

Balance after deposit: 150
Balance after withdrawal: 120
Balance from sharedAccount: 140
Balance from original account: 140

Create Java Package Using compiler.build.javaPackage

Use the compiler.build.javaPackage function to generate a code archive (.ctf file) from the MATLAB function.

buildResults = compiler.build.javaPackage( ...
    "BankAccount.m",...
    Interface="matlab-data",...
    Verbose="on", OutputDir=".\output",....
    PackageName="com.example.Banking")

Although specifying a PackageName in the compiler.build.javaPackage function is not mandatory, it is strongly recommended. Providing a package name results in a cleaner, more predictable Java namespace for the generated code. If omitted, a default root package named example is used, which can lead to a cluttered or confusing package structure in your Java application.

When you package your MATLAB function for Java integration, the process generates several files in your chosen output directory. Of these, the only key file required for Java integration is the code archive (.ctf file), which contains your packaged MATLAB code and resources. For details on the other files, see Files Generated After Packaging MATLAB Functions.

P:\MATLAB\WORK\OUTPUT
    requiredMCRProducts.txt
    GettingStarted.html
    readme.txt
    buildresult.json
    unresolvedSymbols.txt
    includedSupportPackages.txt
    mccExcludedFiles.log
    Banking.ctf

No subfolders exist

When using the MATLAB Data API for Java, the compiler.build.javaPackage function generates a .ctf file, but does not produce a JAR file containing Java wrapper classes. For details, see MATLAB Data API for Java Workflow.

Integrate MATLAB Code into Java Application

You can finalize the integration process in your preferred Java development environment, including a text editor together with the Java Development Kit (JDK) command line tools, or alternatives such as IntelliJ IDEA and Visual Studio Code on Windows, macOS, and Linux. For details, see Set Up Java Development Environment.

Use Java Command Line API to Build Application

  1. Create a Java wrapper class so the MATLAB BankAccount class can be used directly in a Java application.

    import com.mathworks.runtime.*;
    import com.mathworks.matlab.types.*;
    
    /**
     * Java wrapper for the packaged MATLAB BankAccount class.
     * This class provides a Java interface to interact with the MATLAB BankAccount object.
     */
    public class BankAccount implements AutoCloseable {
        /**
         * Reference to MATLAB runtime environment.
         * This is needed to execute MATLAB functions and methods.
         */
        private final MatlabRuntime runtime;
    
        /**
         * Reference to the MATLAB BankAccount object.
         * HandleObject is a special interface that represents a MATLAB handle class instance.
         * It allows us to call methods on the MATLAB object from Java.
         */
        private final HandleObject accountObject;
    
        /**
         * Constructor to initialize the account with a balance
         *
         * @param runtime MATLAB Runtime environment
         * @param initialBalance The initial balance for the account
         * @throws Exception If there's an error creating the MATLAB object
         */
        public BankAccount(MatlabRuntime runtime, double initialBalance) throws Exception {
        		this.runtime = runtime;
    
    		try {
                // Create a new MATLAB BankAccount object by calling the MATLAB constructor
                // The feval method executes a MATLAB class and returns the result
                this.accountObject = runtime.feval("BankAccount", initialBalance);
    
                if (this.accountObject == null) {
                    throw new Exception("Failed to create MATLAB BankAccount object");
                }
            } catch (Exception e) {
                throw new Exception("Error creating BankAccount: " + e.getMessage(), e);
            }
        }
    
        /**
         * Method to deposit money into the account
         *
         * @param amount The amount to deposit
         * @throws Exception If there's an error with the deposit
         */
        public void deposit(double amount) throws Exception {
            try {
                // Call the deposit method on the MATLAB object
                // The first parameter (0) indicates we don't expect a return value
                runtime.feval(0, "deposit", this.accountObject, amount);
            } catch (Exception e) {
                throw new Exception("Error depositing funds: " + e.getMessage(), e);
            }
        }
    
        /**
         * Method to withdraw money from the account
         *
         * @param amount The amount to withdraw
         * @throws Exception If there's an error with the withdrawal
         */
        public void withdraw(double amount) throws Exception {
            try {
                // Call the withdraw method on the MATLAB object
                runtime.feval(0, "withdraw", this.accountObject, amount);
            } catch (Exception e) {
                throw new Exception("Error withdrawing funds: " + e.getMessage(), e);
            }
        }
    
        /**
         * Method to check the balance of the account
         *
         * @return The current balance
         * @throws Exception If there's an error checking the balance
         */
        public double checkBalance() throws Exception {
            try {
                // Call the checkBalance method on the MATLAB object
                // The first parameter (1) indicates we expect a single return value
                // The <Double> specifies the expected return type
                return runtime.<Double>feval(1, "checkBalance", this.accountObject);
            } catch (Exception e) {
                throw new Exception("Error checking balance: " + e.getMessage(), e);
            }
        }
    
        /**
         * Closes resources associated with this BankAccount.
         * In this implementation, we don't need to do anything specific as MATLAB Runtime
         * will be closed separately, and the MATLAB object will be garbage collected.
         */
        @Override
        public void close() {
            // No specific cleanup needed for individual accounts
            // MATLAB runtime will be closed by the main application
        }
    }
    • The constructor BankAccount(MatlabRuntime runtime, double initialBalance) creates the MATLAB object by calling:

      this.accountObject = runtime.feval("BankAccount", initialBalance);
      
      This establishes a new MATLAB BankAccount instance and binds it to Java.

    • In MATLAB, handle classes use reference semantics, meaning multiple variables can refer to the same object instance, and this behavior is preserved in Java through the HandleObject reference, which allows different Java objects to interact with the same underlying MATLAB handle object.

    • Each Java method in the wrapper corresponds to a MATLAB method, executed using runtime.feval(). For example:

      • deposit(double amount) calls the MATLAB deposit method.

      • withdraw(double amount) calls the MATLAB withdraw method.

      • checkBalance() calls the MATLAB checkBalance method and returns a double value.

  2. Create a driver application that initializes MATLAB Runtime and uses the wrapper class to perform operations.

    import com.mathworks.runtime.*;
    
    /**
     * Example application demonstrating the use of the BankAccount class
     * with the MATLAB Runtime.
     */
    public class BankAccountExample {
        public static void main(String[] args) {
            
        		System.out.println("Starting BankAccountExample ...");
        		
        		// Path to the packaged MATLAB CTF file
            String ctfPath = "Banking.ctf";
            
            // Use try-with-resources to ensure proper cleanup of MATLAB Runtime
            try (MatlabRuntime runtime = MatlabRuntime.startMatlab(ctfPath)) {
                System.out.println("MATLAB Runtime started successfully");
    
                // Execute the banking operations
                performBankingOperations(runtime);
                
                // Terminate MATLAB Runtime client infrastructure.
                MatlabRuntime.terminateMatlabClient();
                
            } catch (Exception e) {
                System.err.println("An error occurred with MATLAB Runtime: " + e.getMessage());
                e.printStackTrace();
            } 
        }
    
        /**
         * Performs a series of banking operations to demonstrate the BankAccount class
         *
         * @param runtime MATLAB runtime environment
         */
        private static void performBankingOperations(MatlabRuntime runtime) {
            try {
                // Create a new bank account with an initial balance of 100
                System.out.println("Creating bank account...");
                try (BankAccount account = new BankAccount(runtime, 100)) {
                    System.out.println("Bank account created successfully");
    
                    // Deposit 50 into the account
                    System.out.println("Depositing 50...");
                    account.deposit(50);
                    displayBalance(account, "Balance after deposit: ");
    
                    // Withdraw 30 from the account
                    System.out.println("Withdrawing 30...");
                    account.withdraw(30);
                    displayBalance(account, "Balance after withdrawal: ");
    
                    // Create a joint account that references the same existing account
                    // Note: This doesn't create a new MATLAB object, just a new Java reference
                    System.out.println("Creating joint account reference...");
                    BankAccount jointAccount = account;
    
                    // Deposit 20 using the shared reference
                    System.out.println("Depositing 20 using joint account...");
                    jointAccount.deposit(20);
                    displayBalance(jointAccount, "Balance from joint account: ");
                    displayBalance(account, "Balance from original account: ");
                }
            } catch (Exception e) {
                System.err.println("Error in bank operations: " + e.getMessage());
                e.printStackTrace();
            }
        }
    
        /**
         * Helper method to display the account balance with a message
         *
         * @param account The bank account
         * @param message The message to display before the balance
         */
        private static void displayBalance(BankAccount account, String message) {
            try {
                double balance = account.checkBalance();
                System.out.println(message + balance);
            } catch (Exception e) {
                System.err.println("Error checking balance: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }
    
    • The driver initializes MATLAB Runtime using the path to the packaged MATLAB .ctf file.

    • Inside the runtime session, the performBankingOperations(runtime) method demonstrates various operations that can be perfomed.

  3. Compile your Java code by setting the classpath to include matlabruntime.jar.

    set MATLABROOT=C:\Program Files\MATLAB\R2026b
    
    javac -classpath ".;%MATLABROOT%\toolbox\javabuilder\jar\matlabruntime.jar" BankAccount.java BankAccountExample.java
  4. Run your Java application by setting the classpath to include matlabruntime.jar and by configuring access to the native runtime libraries. For details, see Set MATLAB Library Paths for Testing Deployed Applications.

    java -classpath ".;%MATLABROOT%\toolbox\javabuilder\jar\matlabruntime.jar" BankAccountExample
    
    Starting BankAccountExample ...
    MATLAB Runtime started successfully
    Creating bank account...
    Bank account created successfully
    Depositing 50...
    Balance after deposit: 150.0
    Withdrawing 30...
    Balance after withdrawal: 120.0
    Creating joint account reference...
    Depositing 20 using joint account...
    Balance from joint account: 140.0
    Balance from original account: 140.0
    

    Running a Java application without setting the environment variables to provide access to the native runtime libraries from MATLAB or MATLAB Runtime results in a java.lang.UnsatisfiedLinkError.

    Note

    When testing applications on a machine with a full MATLAB installation, you can set up native library access using the MATLAB installation.

    In a deployment scenario where MATLAB Runtime is used, you must explicitly specify the location of the native libraries within an installation of MATLAB Runtime. This distinction ensures that deployed applications run independently of a full MATLAB installation.

    For details, see:

See Also

Topics