Loren on the Art of MATLAB

Turn ideas into MATLAB

Write Once, Deploy Anywhere 4

Posted by Loren Shure,

Guest blogger Peter Webb returns with another in an occasional series of postings about application deployment.

Contents

Deployment Targets

I've written a MATLAB application that reports on the presence of contaminants in surface water, using a publically available database of water quality observations maintained by the United States Geological Survey and the Environmental Protection Agency. Many groups of people might be interested in this kind of information. MATLAB made it easy to write the application, and some tools we've added recently make sharing the application easy as well.

I can share the application with other MATLAB users as a MATLAB App. With MATLAB Compiler I can create a standalone program that will run on a Windows, Linux or Mac desktop. And Builder JA lets me turn my application into a Java class for use by other developers.

To follow the rest of this article, please download the example code from MATLAB Central.

Deploying to MATLAB

You could share your code with other MATLAB users by emailing them your function and data files. But then you'd have to explain how to install, update and uninstall your application -- and the process would be very vulnerable to human error. Or you could create a MATLAB App. Introduced in R2012b, MATLAB Apps are self-contained programs that automate a technical computing task, typically via a graphical user interface. MATLAB displays the installed apps in the App Gallery, which you access from the Apps tab in the MATLAB toolstrip. Packaging your code as a MATLAB App creates an automated installer (a .mlappinstall file) that integrates your application into the App Gallery. The MATLAB App installer includes only your code; if the App uses any toolboxes, the recepient of the App must have licened copies of these toolboxes in order to use the App. Click on the Package App button on the Apps tab to begin packaging your program as an app.

The packaging interface consists of three columns, each representing a step in the packaging process:

  1. Pick main file
  2. Describe your app
  3. Package into installation file

All Apps must have a main file -- this is the MATLAB file that starts the graphical user interface or performs the task. Click on the Add main file link:

From the downloaded example code, select swq.m. The Files included through analysis section fills in with the required function files. Since the automated analysis cannot discover data files, you must add them manually. Select the Add files/folders in the Shared resources and helper files section and add Contaminants.xml, ContaminantLimits.xml and swqLogo.png.

All Apps must also have a name. Type SurfaceWaterQuality into the App Name field at the top of the Describe your app area. You can add your contact info and a description too, if you like, but that's optional. If you want to add an icon and a screenshot, I've provided appropriate images: sqwIcon.png for the icon and swqApp.png for the screenshot. Click on the screenshot and icon to browse for these images.

Once you're satisfied with the description, press the Package button to create the installer: SurfaceWaterQuality.mlappinstaller. On any machine with MATLAB installed, double-clicking SurfaceWaterQuality.mlappinstaller will install the SurfaceWaterQuality app into the MATLAB App Gallery. Click once on the app to start it:

With these inputs, the app produces a report of contaminants recorded within five miles of the MathWorks buildings in Natick, Massachusetts.

Deploying to the Desktop

MATLAB Apps allow you to share programs with other MATLAB users. But what if your target audience doesn't have MATLAB? MATLAB Compiler packages MATLAB programs to run against the MATLAB Compiler Runtime, which does not require MATLAB. The process of creating a standalone executable with MATLAB Compiler begins on the Apps tab of the MATLAB toolstrip. Click the Application Compiler button:

Like an App, a MATLAB Compiler-generated standalone executable requires a main file. Click on the + next to the Add main file field and select waterQualityReport.m from the downloaded example files:

applicationCompiler derives the application name from the name of the main file and immediately begins determining the files required to run the application. The Files required for your application to run section fills with MATLAB function dependencies. You'll need to add data file dependencies manually. Click on the + button in that section and add Contaminants.xml and ContaminantLimits.xml:

Like a MATLAB App, a standalone application may contain contact and description information to be displayed in the installer. You may also add a splash screen, for example waterQuality.jpg from the downloaded example files. applicationCompiler automatically includes the splash screen image in the installer, so there's no need to add it manually. Once you're done entering this optional information, change the name of the installer to WQRInstaller_web.

Press the Package button to build the installer for your standalone application.

Packaging creates a platform-specific installer: waterQualityReport\for_redistribution\WQRInstaller_web.exe on Windows and waterQualityReport/for_redistribution/WQRInstaller_web on Linux and Mac. Copy this file to a machine of the appropriate type, run the installer, and you'll be able to install and run the water quality application without installing MATLAB. Run the installer like this:

WQRInstaller_web

Look for the executable in the application folder, located in the installation folder. And then run the application like this:

waterQualityReport 42.2973025 -71.3525913 5 1/1/2004

On Linux and Mac platforms, you may find it easier to run the application using the generated run_waterQualityReport.sh shell script. This command assumes you've installed the MCR in the /tmp/WQTest/MATLAB_Compiler_Runtime/v83 folder:

./run_waterQualityReport.sh \
    /tmp/WQTest/MATLAB_Compiler_Runtime/v83/ \
    42.2973025 -71.3525913 5 1/1/2004

See the MATLAB Compiler documentation for more information about how to run a MATLAB Compiler-generated application.

Deploying to a Java Application

Builder JA creates a Java component that you integrate into a larger host application. Before using Builder JA, you must configure your environment to ensure Builder JA uses a supported version of the Java compiler.

When you have set up your environment, type libraryCompiler at the MATLAB prompt and choose Java Package as the application type to begin:

Instead of running a main file, a Java component exports one or more functions into a public API. Use the + button to add detectContamination.m to the Exported Functions list. Then, in Files required for your application to run section, add the data files Contaminants.xml, ContaminantLimits.xml and swqLogo.png.

A Java API requires a class with at least one method. Placing the class in a namespace helps prevent class name conflicts. libraryCompiler uses generic defaults: no namespace, a class named Class1 and method names corresponding to the MATLAB functions you chose to export. Change the class name to SurfaceWaterQuality and the namespace to WaterQuality.

Change the name of the generated installer (as illustrated previously, in Deploying to the Desktop) to DCInstaller_web. Press the Package button to create WaterQuality.jar.

Unlike the desktop application, the Java component in WaterQuality.jar won't run by itself. It needs to be invoked from a host Java application. The downloaded code contains an example main program, WaterQuality.java.

Much like the MATLAB App and the desktop application, this Java host program collects a search area and start date from the user and invokes the web service. In addition to creating a user interface via AWT, the main program must perform three tasks to interact with the Builder JA-generated Java component:

  1. Import Builder JA generated and utility classes.
  2. Create a WaterQuality.SurfaceWaterQuality object.
  3. Invoke the detectContaminants method.

The WaterQuality namespace contains the generated SurfaceWaterQuality class and the com.mathworks.toolbox.javabuilder namespace contains Builder JA runtime management and error handling classes such as MWException. The Java program imports these namespaces:

import WaterQuality.*;
import com.mathworks.toolbox.javabuilder.*;

Builder JA creates object, rather than static, methods, so you must create an instance of the generated class to invoke the methods in your exported API. The constructor might throw an MWException, so your Java code must either catch MWException or declare it in a throws clause. The unsophisticated code in the example catches (and ignores) errors that might occur during object creation:

try {
  swq = new SurfaceWaterQuality();
}
catch (MWException me) {}

Pushing the Report button invokes the web service via the detectContamination method. The first input is the number of expected outputs. Methods in the exported API return an array of Java Object instances. The host program converts each result to the appropriate native type, a String in this case, before using them. Builder JA includes a robust set of type-conversion routines to make this task easy. detectContamination preformats the text for tabular display with a monospaced font such as Courier. In the Java code below, reportData is a Java TextArea object capable of scrolling to display the list of reported contaminants.

Object[] lhs;
lhs = swq.detectContamination(1,
    latitude, longitude, radius, startDate);
if (lhs != null)
{
    String result = lhs[0].toString();
    reportData.setText(result);
}

The download contains scripts to help you build and run the sample application. See the Readme.txt for platform-specific instructions. Note that the application does not do much validation of its inputs, and is somewhat fragile as a result.

Reuse, Don't Rewrite

Managing the interaction with the web service is the most complex part of these three water quality report applications. And in each of them, that part is exactly the same. Only the target-specific wrapper differs, adapting the core functionality to the interface norms of the target environment: MATLAB, the standalone desktop and a Java host program.

MATLAB Apps, applicationCompiler and libraryCompiler use the same visual conventions and very similar three-step workflows: select functions to deploy, add data files and descriptive data, create an installer. This shared language and process makes it simpler to deploy the same code to multiple target environments.

Do you deploy code to more than one environment? What challenges do you face? Let us know here.

Get the MATLAB code

Published with MATLAB® R2014a

Note

Comments are closed.

4 CommentsOldest to Newest

adam replied on : 1 of 4
We have started to use Desktop deployment quite a lot as our company internal experts in our domain work in a different office to our technical group and R&D team so our R&D team often create small applications in Matlab to ship to our other office where they have very little or no Matlab expertise. We haven't made a Matlab deployable app yet though to share among those of us who work in R&D as we tend to all just run our programs from command line or GUIDE. One thing that we are unsure about with regard to desktop deployment though is if we were to send these external to our company (e.g. to R&D partners). I noticed that installing an executable copies the .m files to the target computer (in a relatively obscure folder, but entirely readable). Allied to the fact we do not have any kind of licensing on executables we create this makes us uneasy about sending out such executables whose code may well contain IP that we do not wish to expose.
Ssoiniss replied on : 2 of 4
If I understand corretly, the GUI deployment using Matlab Builder still needs this huge Matlab Runtime package, correct? Because as in my memory this makes the loading and initialization of GUI extremely slow comparing to a normal windows exe. application. Also there are issues e.g. due to environment variables and saving/opening data. ------------------------ @Adam, I don't know whether Matlab would pack the orignal m file into App or desktop application. But if yes maybe there is a workround to compile the m file into p file and then use it in the compilation. ------------------------ I work on Matlab Gui development a lot and hope really that someday in future, the Matlab GUI can work exactly like in Matlab and as fast as a standard Windows exe. in every aspects.
Amro replied on : 3 of 4
All applications produced by the MATLAB Compiler (and related toolboxes) include an embedded CTF archive. This archive is embedded in the generated component (standalone EXE, shared DLL, Java packes, .NET assemblies, etc..) along with a target-specific boilerplate code to expose it as a binary component of the expected format. The CTF archive contains all the MATLAB source and data of the project files in an encrypted form (AES encryption). The archive is extracted when the application runs for the first time (to a configurable cache location), files are then decrypted and executed in the context of the MCR runtime. So even though there will be a bunch of visible M-files inside the cache directory, they all contain encrypted gibberish (not clear text code). Think of the MCR runtime as a stripped version of the MATLAB computation engine without a user interface. This is why starting a MATLAB-compiled application takes about the same time as starting the MATLAB IDE itself. There are ways to make the compiled application load up a bit faster, but ultimately it's somewhat similar as starting MATLAB IDE, running your scripts, the shutting the IDE down each time the application is exectued... You can read more about this in the docs.
adam replied on : 4 of 4
That is true actually. When I said they were "entirely readable" I realise now I just saw the .m extension and assumed they were the standard readable files without actually opening them. So it is just our eccentric naming of folders and classes that will be potentially exposed to 3rd parties then rather than our IP!