{"id":951,"date":"2014-07-28T10:03:35","date_gmt":"2014-07-28T15:03:35","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/?p=951"},"modified":"2016-08-03T14:29:53","modified_gmt":"2016-08-03T19:29:53","slug":"write-once-deploy-anywhere","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2014\/07\/28\/write-once-deploy-anywhere\/","title":{"rendered":"Write Once, Deploy Anywhere"},"content":{"rendered":"<div class=\"content\"><!--introduction-->Guest blogger <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/4660\">Peter Webb<\/a> returns with another in an <a href=\"https:\/\/blogs.mathworks.com\/loren\/category\/deployment\/\">occasional series<\/a> of postings about application deployment.<\/p>\n<p><!--\/introduction--><\/p>\n<h3>Contents<\/h3>\n<div>\n<ul>\n<li><a href=\"#20f4f6d5-3aa6-4e6f-b514-b03270186856\">Deployment Targets<\/a><\/li>\n<li><a href=\"#75fc3747-e8a6-47f2-a9f3-97b597b29cb5\">Deploying to MATLAB<\/a><\/li>\n<li><a href=\"#9282dcc3-c539-4784-a38a-607767840066\">Deploying to the Desktop<\/a><\/li>\n<li><a href=\"#1ed89e63-21fb-4f87-ba0b-26d89c123a8e\">Deploying to a Java Application<\/a><\/li>\n<li><a href=\"#1139de00-62b7-4def-9008-da07b05e3cf7\">Reuse, Don't Rewrite<\/a><\/li>\n<\/ul>\n<\/div>\n<h4>Deployment Targets<a name=\"20f4f6d5-3aa6-4e6f-b514-b03270186856\"><\/a><\/h4>\n<p>I've written a <a href=\"https:\/\/www.mathworks.com\/products\/matlab\">MATLAB<\/a> application that reports on the presence of contaminants in surface water, using a publically available <a href=\"http:\/\/www.waterqualitydata.us\/\">database<\/a> 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.<\/p>\n<p>I can share the application with other MATLAB users as a <a href=\"https:\/\/www.mathworks.com\/discovery\/matlab-apps.html\">MATLAB App<\/a>. With <a href=\"https:\/\/www.mathworks.com\/products\/compiler\/\">MATLAB Compiler<\/a> I can create a standalone program that will run on a Windows, Linux or Mac desktop. And <a href=\"https:\/\/www.mathworks.com\/products\/javabuilder\/\">Builder JA<\/a> lets me turn my application into a Java class for use by other developers.<\/p>\n<p>To follow the rest of this article, please download the <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/46844-deployanywhere-zip\">example code<\/a> from <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/\">MATLAB Central<\/a>.<\/p>\n<h4>Deploying to MATLAB<a name=\"75fc3747-e8a6-47f2-a9f3-97b597b29cb5\"><\/a><\/h4>\n<p>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 <b>Apps<\/b> tab in the MATLAB toolstrip. Packaging your code as a MATLAB App creates an automated installer (a <tt>.mlappinstall<\/tt> 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 <b>Package App<\/b> button on the <b>Apps<\/b> tab to begin packaging your program as an app.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2014\/PackageApp.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/><\/p>\n<p>The packaging interface consists of three columns, each representing a step in the packaging process:<\/p>\n<div>\n<ol>\n<li>Pick main file<\/li>\n<li>Describe your app<\/li>\n<li>Package into installation file<\/li>\n<\/ol>\n<\/div>\n<p>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 <tt>Add main file<\/tt> link:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2014\/MainFile.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/><\/p>\n<p>From the downloaded example code, select <tt>swq.m<\/tt>. The <b>Files included through analysis<\/b> section fills in with the required function files. Since the automated analysis cannot discover data files, you must add them manually. Select the <tt>Add files\/folders<\/tt> in the <b>Shared resources and helper files<\/b> section and add <tt>Contaminants.xml<\/tt>, <tt>ContaminantLimits.xml<\/tt> and <tt>swqLogo.png<\/tt>.<\/p>\n<p>All Apps must also have a name. Type <tt>SurfaceWaterQuality<\/tt> into the <tt>App Name<\/tt> field at the top of the <b>Describe your app<\/b> 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: <tt>sqwIcon.png<\/tt> for the icon and <tt>swqApp.png<\/tt> for the screenshot. Click on the screenshot and icon to browse for these images.<\/p>\n<p>Once you're satisfied with the description, press the <b>Package<\/b> button to create the installer: <tt>SurfaceWaterQuality.mlappinstaller<\/tt>. On any machine with MATLAB installed, double-clicking <tt>SurfaceWaterQuality.mlappinstaller<\/tt> will install the <tt>SurfaceWaterQuality<\/tt> app into the MATLAB App Gallery. Click once on the app to start it:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2014\/swqApp.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/><\/p>\n<p>With these inputs, the app produces a report of contaminants recorded within five miles of the MathWorks buildings in Natick, Massachusetts.<\/p>\n<h4>Deploying to the Desktop<a name=\"9282dcc3-c539-4784-a38a-607767840066\"><\/a><\/h4>\n<p>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 <b>Apps<\/b> tab of the MATLAB toolstrip. Click the <b>Application Compiler<\/b> button:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2014\/AppCompiler.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/><\/p>\n<p>Like an App, a MATLAB Compiler-generated standalone executable requires a main file. Click on the <tt>+<\/tt> next to the <tt>Add main file<\/tt> field and select <tt>waterQualityReport.m<\/tt> from the downloaded example files:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2014\/CompilerMainFile.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/><\/p>\n<p><tt>applicationCompiler<\/tt> derives the application name from the name of the main file and immediately begins determining the files required to run the application. The <b>Files required for your application to run<\/b> section fills with MATLAB function dependencies. You'll need to add data file dependencies manually. Click on the <tt>+<\/tt> button in that section and add <tt>Contaminants.xml<\/tt> and <tt>ContaminantLimits.xml<\/tt>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2014\/PlusButton.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/><\/p>\n<p>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 <tt>waterQuality.jpg<\/tt> from the downloaded example files. <tt>applicationCompiler<\/tt> 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 <tt>WQRInstaller_web<\/tt>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2014\/WQRInstaller.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/><\/p>\n<p>Press the <b>Package<\/b> button to build the installer for your standalone application.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2014\/PackageExe.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/><\/p>\n<p>Packaging creates a platform-specific installer: <tt>waterQualityReport\\for_redistribution\\WQRInstaller_web.exe<\/tt> on Windows and <tt>waterQualityReport\/for_redistribution\/WQRInstaller_web<\/tt> 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:<\/p>\n<p><tt>WQRInstaller_web<\/tt><\/p>\n<p>Look for the executable in the <tt>application<\/tt> folder, located in the installation folder. And then run the application like this:<\/p>\n<p><tt>waterQualityReport 42.2973025 -71.3525913 5 1\/1\/2004<\/tt><\/p>\n<p>On Linux and Mac platforms, you may find it easier to run the application using the generated <tt>run_waterQualityReport.sh<\/tt> shell script. This command assumes you've installed the MCR in the <tt>\/tmp\/WQTest\/MATLAB_Compiler_Runtime\/v83<\/tt> folder:<\/p>\n<pre>.\/run_waterQualityReport.sh \\\r\n    \/tmp\/WQTest\/MATLAB_Compiler_Runtime\/v83\/ \\\r\n    42.2973025 -71.3525913 5 1\/1\/2004<\/pre>\n<p>See the <a href=\"https:\/\/www.mathworks.com\/help\/compiler\/mcr-path-settings-for-run-time-deployment.html\">MATLAB Compiler documentation<\/a> for more information about how to run a MATLAB Compiler-generated application.<\/p>\n<h4>Deploying to a Java Application<a name=\"1ed89e63-21fb-4f87-ba0b-26d89c123a8e\"><\/a><\/h4>\n<p>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.<\/p>\n<p>When you have set up your environment, type <tt>libraryCompiler<\/tt> at the MATLAB prompt and choose <b>Java Package<\/b> as the application type to begin:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2014\/ApplicationType.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/><\/p>\n<p>Instead of running a main file, a Java component exports one or more functions into a public API. Use the <tt>+<\/tt> button to add <tt>detectContamination.m<\/tt> to the <b>Exported Functions<\/b> list. Then, in <b>Files required for your application to run<\/b> section, add the data files <tt>Contaminants.xml<\/tt>, <tt>ContaminantLimits.xml<\/tt> and <tt>swqLogo.png<\/tt>.<\/p>\n<p>A Java API requires a class with at least one method. Placing the class in a namespace helps prevent class name conflicts. <tt>libraryCompiler<\/tt> uses generic defaults: no namespace, a class named <tt>Class1<\/tt> and method names corresponding to the MATLAB functions you chose to export. Change the class name to <tt>SurfaceWaterQuality<\/tt> and the namespace to <tt>WaterQuality<\/tt>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2014\/ClassStruct.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/><\/p>\n<p>Change the name of the generated installer (as illustrated previously, in <b>Deploying to the Desktop<\/b>) to <tt>DCInstaller_web<\/tt>. Press the <b>Package<\/b> button to create <tt>WaterQuality.jar<\/tt>.<\/p>\n<p>Unlike the desktop application, the Java component in <tt>WaterQuality.jar<\/tt> won't run by itself. It needs to be invoked from a host Java application. The downloaded code contains an example main program, <tt>WaterQuality.java<\/tt>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2014\/swqJava.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/><\/p>\n<p>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:<\/p>\n<div>\n<ol>\n<li>Import Builder JA generated and utility classes.<\/li>\n<li>Create a <tt>WaterQuality.SurfaceWaterQuality<\/tt> object.<\/li>\n<li>Invoke the <tt>detectContaminants<\/tt> method.<\/li>\n<\/ol>\n<\/div>\n<p>The <tt>WaterQuality<\/tt> namespace contains the generated <tt>SurfaceWaterQuality<\/tt> class and the <tt>com.mathworks.toolbox.javabuilder<\/tt> namespace contains Builder JA runtime management and error handling classes such as <tt>MWException<\/tt>. The Java program imports these namespaces:<\/p>\n<pre>import WaterQuality.*;\r\nimport com.mathworks.toolbox.javabuilder.*;<\/pre>\n<p>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 <tt>MWException<\/tt>, so your Java code must either <tt>catch<\/tt> <tt>MWException<\/tt> or declare it in a <tt>throws<\/tt> clause. The unsophisticated code in the example catches (and ignores) errors that might occur during object creation:<\/p>\n<pre>try {\r\n  swq = new SurfaceWaterQuality();\r\n}\r\ncatch (MWException me) {}<\/pre>\n<p>Pushing the <b>Report<\/b> button invokes the web service via the <tt>detectContamination<\/tt> method. The first input is the number of expected outputs. Methods in the exported API return an array of Java <tt>Object<\/tt> instances. The host program converts each result to the appropriate native type, a <tt>String<\/tt> in this case, before using them. Builder JA includes a robust set of type-conversion routines to make this task easy. <tt>detectContamination<\/tt> preformats the text for tabular display with a monospaced font such as <tt>Courier<\/tt>. In the Java code below, <tt>reportData<\/tt> is a Java <tt>TextArea<\/tt> object capable of scrolling to display the list of reported contaminants.<\/p>\n<pre>Object[] lhs;\r\nlhs = swq.detectContamination(1,\r\n    latitude, longitude, radius, startDate);\r\nif (lhs != null)\r\n{\r\n    String result = lhs[0].toString();\r\n    reportData.setText(result);\r\n}<\/pre>\n<p>The download contains scripts to help you build and run the sample application. See the <tt>Readme.txt<\/tt> for platform-specific instructions. Note that the application does not do much validation of its inputs, and is somewhat fragile as a result.<\/p>\n<h4>Reuse, Don't Rewrite<a name=\"1139de00-62b7-4def-9008-da07b05e3cf7\"><\/a><\/h4>\n<p>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.<\/p>\n<p>MATLAB Apps, <tt>applicationCompiler<\/tt> and <tt>libraryCompiler<\/tt> 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.<\/p>\n<p>Do you deploy code to more than one environment? What challenges do you face? Let us know <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=951#respond\">here<\/a>.<\/p>\n<p><script>\/\/ <![CDATA[\nfunction grabCode_3775eef1581b40d5ac1a000574ab46ba() {\n        \/\/ Remember the title so we can use it in the new page\n        title = document.title;\n\n        \/\/ Break up these strings so that their presence\n        \/\/ in the Javascript doesn't mess up the search for\n        \/\/ the MATLAB code.\n        t1='3775eef1581b40d5ac1a000574ab46ba ' + '##### ' + 'SOURCE BEGIN' + ' #####';\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 3775eef1581b40d5ac1a000574ab46ba';\n    \n        b=document.getElementsByTagName('body')[0];\n        i1=b.innerHTML.indexOf(t1)+t1.length;\n        i2=b.innerHTML.indexOf(t2);\n \n        code_string = b.innerHTML.substring(i1, i2);\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\n\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \n        \/\/ in the XML parser.\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\n        \/\/ doesn't go ahead and substitute the less-than character. \n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\n\n        copyright = 'Copyright 2014 The MathWorks, Inc.';\n\n        w = window.open();\n        d = w.document;\n        d.write('\n\n\n\n<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\n\n\n\n\n\\n');\n\n        d.title = title + ' (MATLAB code)';\n        d.close();\n    }\n\/\/ ]]><\/script><\/p>\n<p style=\"text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;\">\n<a><span style=\"font-size: x-small; font-style: italic;\">Get<br \/>\nthe MATLAB code<noscript>(requires JavaScript)<\/noscript><\/span><\/a><\/p>\n<p>Published with MATLAB\u00ae R2014a<\/p>\n<\/div>\n<p><!--\n3775eef1581b40d5ac1a000574ab46ba ##### SOURCE BEGIN #####\n%% Write Once, Deploy Anywhere\n% Guest blogger\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/4660 % Peter Webb> returns with another in an\n% <https:\/\/blogs.mathworks.com\/loren\/category\/deployment\/ occasional % series> of postings about application deployment.\n\n%% Deployment Targets\n% I've written a <https:\/\/www.mathworks.com\/products\/matlab MATLAB>\n% application that reports on the presence of\n% contaminants in surface water, using a publically available\n% <http:\/\/www.waterqualitydata.us\/ database> of\n% water quality observations maintained by the United States Geological\n% Survey and the Environmental Protection Agency. Many groups of people\n% might be interested in this kind of information. MATLAB made it easy to\n% write the application, and some tools we've added recently make sharing\n% the application easy as well.\n%\n% I can share the application with other MATLAB users as a\n% <https:\/\/www.mathworks.com\/discovery\/matlab-apps.html MATLAB App>.\n% With <https:\/\/www.mathworks.com\/products\/compiler\/ MATLAB Compiler>\n% I can create a standalone program that will run on a Windows, Linux or\n% Mac desktop. And\n% <https:\/\/www.mathworks.com\/products\/javabuilder\/ Builder JA> lets\n% me turn my application into a Java class for use by other developers.\n%\n% To follow the rest of this article, please download the\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/46844-deployanywhere-zip example code> from\n% <https:\/\/www.mathworks.com\/matlabcentral\/ MATLAB Central>.\n\n%% Deploying to MATLAB\n% You could share your code with other MATLAB users by emailing them your\n% function and data files. But then you'd have to explain how to install,\n% update and uninstall your application REPLACE_WITH_DASH_DASH and the process would be very\n% vulnerable to human error. Or you could create a MATLAB App. Introduced\n% in R2012b, MATLAB Apps are self-contained programs that automate a\n% technical computing task, typically via a graphical user interface.\n% MATLAB displays the installed apps in the App Gallery, which you access\n% from the *Apps* tab in the MATLAB toolstrip. Packaging your code as\n% a MATLAB App creates an automated installer (a |.mlappinstall|\n% file) that integrates your application into the App Gallery.\n% The MATLAB App installer includes only your code; if the App uses any\n% toolboxes, the recepient of the App must have licened copies of these\n% toolboxes in order to use the App. Click on the *Package App* button on\n% the *Apps* tab to begin packaging your program as an app.\n%\n% <<PackageApp.png>>\n%\n% The packaging interface consists of three columns, each representing a\n% step in the packaging process:\n%\n% # Pick main file\n% # Describe your app\n% # Package into installation file\n%\n% All Apps must have a main file REPLACE_WITH_DASH_DASH this is the MATLAB file that starts the\n% graphical user interface or performs the task. Click on the |Add main\n% file| link:\n%\n% <<MainFile.png>>\n%\n% From the downloaded example code, select |swq.m|. The *Files included\n% through analysis* section fills in with the required function files.\n% Since the automated analysis cannot discover data files, you must add them\n% manually. Select the |Add files\/folders| in the *Shared resources and\n% helper files* section and add |Contaminants.xml|,\n% |ContaminantLimits.xml| and |swqLogo.png|.\n%\n% All Apps must also have a name. Type |SurfaceWaterQuality| into the |App\n% Name| field at the top of the *Describe your app* area. You can add your\n% contact info and a description too, if you like, but that's optional. If\n% you want to add an icon and a screenshot, I've provided appropriate\n% images: |sqwIcon.png| for the icon and |swqApp.png| for the screenshot.\n% Click on the screenshot and icon to browse for these images.\n%\n% Once you're satisfied with the description, press the *Package* button to\n% create the installer: |SurfaceWaterQuality.mlappinstaller|. On any machine\n% with MATLAB installed, double-clicking |SurfaceWaterQuality.mlappinstaller|\n% will install the |SurfaceWaterQuality| app into the MATLAB App Gallery.\n% Click once on the app to start it:\n%\n% <<swqApp.png>>\n%\n% With these inputs, the app produces a report of contaminants recorded\n% within five miles of the MathWorks buildings in Natick, Massachusetts.\n\n%% Deploying to the Desktop\n% MATLAB Apps allow you to share programs with other MATLAB users. But what\n% if your target audience doesn't have MATLAB? MATLAB Compiler packages\n% MATLAB programs to run against the MATLAB Compiler Runtime, which does\n% not require MATLAB. The process of creating a standalone executable with\n% MATLAB Compiler begins on the *Apps* tab of the MATLAB toolstrip. Click\n% the *Application Compiler* button:\n%\n% <<AppCompiler.png>>\n%\n% Like an App, a MATLAB Compiler-generated standalone executable requires a\n% main file. Click on the |+| next to the |Add main file| field and select\n% |waterQualityReport.m| from the downloaded example files:\n%\n% <<CompilerMainFile.png>>\n%\n% |applicationCompiler| derives the application name from the name\n% of the main file and immediately begins determining the files required to\n% run the application. The *Files required for your application to run*\n% section fills with MATLAB function dependencies. You'll need to add data\n% file dependencies manually. Click on the |+| button in that section and\n% add |Contaminants.xml| and |ContaminantLimits.xml|:\n%\n% <<PlusButton.png>>\n%\n% Like a MATLAB App, a standalone application may contain contact and\n% description information to be displayed in the installer. You may also\n% add a splash screen, for example |waterQuality.jpg| from the downloaded\n% example files. |applicationCompiler| automatically includes the splash\n% screen image in the installer, so there's no need to add it manually.\n% Once you're done entering this optional information,\n% change the name of the installer to |WQRInstaller_web|.\n%\n% <<WQRInstaller.png>>\n%\n% Press the *Package* button to build the installer for your standalone\n% application.\n%\n% <<PackageExe.png>>\n%\n% Packaging creates a platform-specific installer:\n% |waterQualityReport\\for_redistribution\\WQRInstaller_web.exe| on Windows\n% and |waterQualityReport\/for_redistribution\/WQRInstaller_web| on Linux and\n% Mac. Copy this file to a machine of the appropriate type, run the\n% installer, and you'll be able to install and run the water quality\n% application without installing MATLAB. Run the installer like this:\n%\n% |WQRInstaller_web|\n%\n% Look for the executable in the |application| folder, located in the\n% installation folder. And then run the application like this:\n%\n% |waterQualityReport 42.2973025 -71.3525913 5 1\/1\/2004|\n%\n% On Linux and Mac platforms, you may find it easier to run the application\n% using the generated |run_waterQualityReport.sh| shell script. This\n% command assumes you've installed the MCR in the\n% |\/tmp\/WQTest\/MATLAB_Compiler_Runtime\/v83| folder:\n%\n%  .\/run_waterQualityReport.sh \\\n%      \/tmp\/WQTest\/MATLAB_Compiler_Runtime\/v83\/ \\\n%      42.2973025 -71.3525913 5 1\/1\/2004\n%\n% See the\n% <https:\/\/www.mathworks.com\/help\/compiler\/mcr-path-settings-for-run-time-deployment.html % MATLAB Compiler documentation> for more information about how to run a\n% MATLAB Compiler-generated application.\n\n%% Deploying to a Java Application\n% Builder JA creates a Java component that you integrate into a larger host\n% application. Before using Builder JA, you must\n% <https:\/\/www.mathworks.com\/help\/javabuilder\/ug\/configuring-your-environment.html % configure your environment> to ensure Builder JA uses a supported\n% version of the Java compiler.\n%\n% When you have set up your environment, type |libraryCompiler| at the\n% MATLAB prompt and choose *Java Package* as the application type to begin:\n%\n% <<ApplicationType.png>>\n%\n% Instead of running a main file, a Java component exports one or more\n% functions into a public API. Use the |+| button to add\n% |detectContamination.m| to the *Exported Functions* list. Then, in\n% *Files required for your application to run* section, add the data files\n% |Contaminants.xml|, |ContaminantLimits.xml| and |swqLogo.png|.\n%\n% A Java API requires a class with at least one method. Placing the class\n% in a namespace helps prevent class name conflicts. |libraryCompiler|\n% uses generic defaults: no namespace, a class named |Class1| and method\n% names corresponding to the MATLAB functions you chose to export. Change\n% the class name to |SurfaceWaterQuality| and the namespace to\n% |WaterQuality|.\n%\n% <<ClassStruct.png>>\n%\n% Change the name of the generated installer (as illustrated previously, in\n% *Deploying to the Desktop*) to |DCInstaller_web|.\n% Press the *Package* button to create |WaterQuality.jar|.\n%\n% Unlike the desktop application, the Java component in |WaterQuality.jar|\n% won't run by itself. It needs to be invoked from a host Java application.\n% The downloaded code contains an example main program,\n% |WaterQuality.java|.\n%\n% <<swqJava.png>>\n%\n% Much like the MATLAB App and the desktop application, this Java host\n% program collects a search area and start date from the user and invokes\n% the web service. In addition to creating a user interface via AWT, the\n% main program must perform three tasks to interact with the Builder\n% JA-generated Java component:\n%\n% # Import Builder JA generated and utility classes.\n% # Create a |WaterQuality.SurfaceWaterQuality| object.\n% # Invoke the |detectContaminants| method.\n%\n% The |WaterQuality| namespace contains the generated |SurfaceWaterQuality|\n% class and the |com.mathworks.toolbox.javabuilder| namespace contains\n% Builder JA runtime management and error handling classes such as\n% |MWException|. The Java program imports these namespaces:\n%\n%  import WaterQuality.*;\n%  import com.mathworks.toolbox.javabuilder.*;\n%\n% Builder JA creates object, rather than static, methods, so you must\n% create an instance of the generated class to invoke the methods in your\n% exported API. The constructor might throw an |MWException|, so your Java code\n% must either |catch| |MWException| or declare it in a |throws| clause.\n% The unsophisticated code in the example catches (and ignores) errors that\n% might occur during object creation:\n%\n%  try {\n%    swq = new SurfaceWaterQuality();\n%  }\n%  catch (MWException me) {}\n%\n% Pushing the *Report* button invokes the web service via the\n% |detectContamination| method. The first input is the number of expected\n% outputs. Methods in the exported API return an array of Java |Object|\n% instances. The host program converts each result to the appropriate\n% native type, a |String| in this case, before using them. Builder JA\n% includes a robust set of type-conversion routines to make this task easy.\n% |detectContamination| preformats the text for tabular display with a\n% monospaced font such as |Courier|. In the Java code below, |reportData| is a\n% Java |TextArea| object capable of scrolling to display the list of\n% reported contaminants.\n%\n%  Object[] lhs;\n%  lhs = swq.detectContamination(1,\n%      latitude, longitude, radius, startDate);\n%  if (lhs != null)\n%  {\n%      String result = lhs[0].toString();\n%      reportData.setText(result);\n%  }\n%\n% The download contains scripts to help you build and run the sample\n% application. See the |Readme.txt| for platform-specific instructions.\n% Note that the application does not do much validation of its inputs,\n% and is somewhat fragile as a result.\n%\n%% Reuse, Don't Rewrite\n%\n% Managing the interaction with the web service is the most complex part\n% of these three water quality report applications. And in each of them,\n% that part is exactly the same. Only the target-specific wrapper differs,\n% adapting the core functionality to the interface norms of the target\n% environment: MATLAB, the standalone desktop and a Java host program.\n%\n% MATLAB Apps, |applicationCompiler| and |libraryCompiler| use the same\n% visual conventions and very similar three-step workflows: select\n% functions to deploy, add data files and descriptive data, create an\n% installer. This shared language and process makes it simpler to deploy\n% the same code to multiple target environments.\n%\n% Do you deploy code to more than one environment? What challenges do you\n% face? Let us know <https:\/\/blogs.mathworks.com\/loren\/?p=951#respond here>.\n\n##### SOURCE END ##### 3775eef1581b40d5ac1a000574ab46ba\n--><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2014\/swqJava.png\" onError=\"this.style.display ='none';\" \/><\/div>\n<p><!--introduction-->Guest blogger <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/4660\">Peter Webb<\/a> returns with another in an <a href=\"https:\/\/blogs.mathworks.com\/loren\/category\/deployment\/\">occasional series<\/a> of postings about application deployment.<\/p>\n<p><!--\/introduction-->... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2014\/07\/28\/write-once-deploy-anywhere\/\">read more >><\/a><\/p>\n","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[24],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/951"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=951"}],"version-history":[{"count":15,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/951\/revisions"}],"predecessor-version":[{"id":1910,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/951\/revisions\/1910"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=951"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=951"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=951"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}