Does anybody know how to embed a Java runtime into a Mac Cocoa (sandboxed) app so that the app can run a .jar file without the user having to install Java separately?
We have a Cocoa application that we sell through the Mac App Store as well as on our own site which can use Java for a specific task. It's a writing app, and because the standard NSText exporters for .doc, .docx and .odt are very limited (not supporting headers, footers, images etc), we write out to RTF and then use Java-based converters (from Aspose.com) to convert the RTF to .doc, .docx or .odt, depending on the chosen export format.
I do this by by using NSTask to call on /usr/bin/java and run a bundled .jar file that runs the conversion routines. This all works beautifully--as long as Java is installed on the user's Mac. If it's not installed, our app asks the user if he or she would like to install Java to benefit from the enhanced converters, or instead fall back on the NSText lossy converters. If the user chooses to install Java, we call java_home --request to invoke OS X's Java installer.
However, now that Apple has ended (or is ending) direct support for Java, this approach is problematic. During our last Mac App Store review, we were told that we would soon need to stop asking the user if he or she wanted to install Java. I have read that Apple's recommended route going forward is to embed a Java Runtime Environment into Cocoa applications that need to run Java. (E.g: http://lists.apple.com/archives/java-dev/2011/Jul/msg00038.html )
Over the past few days, I've therefore been researching how I can go about embedding a JRE in my app, but I haven't found any instructions on how to do so anywhere - nothing that I understand, at least. Someone asked a similar question here a couple of years ago:
Bundling a private JRE on Mac OS X
However, the answers there, and on other sites I've found, are all about bundling a Java application as a Mac application, not about including a JRE with an existing Cocoa application. (Although I accept that my lack of experience with Java may mean that I just don't understand how to convert the instructions for my purposes - take me out of Xcode and I'm out of my comfort zone.) Likewise: https://wikis.oracle.com/display/OpenJDK/How+to+embed+a+.jre+bundle+in+your+Mac+app
It seems that a couple of applications have done this (e.g. Cyberduck), but no one has documented the process yet. From what I've read, I think I need to either grab the Java Virtual Machine from Oracle's JDK or OpenJDK and include that in my Cocoa app and call on java from within that, but if I did so, the Java executables within the copy of the JVM wouldn't be sandboxed, so my app wouldn't get through the MAS review process. So presumably I need to somehow build a copy of the JDK and sandbox it, most likely as part of my larger Xcode project? I'm not even sure where to start; I'm guessing it's still early days and that not many Mac developers have had to do this yet.
Has anyone got any experience of embedding a JRE into a Cocoa application in such a way that the app can just call on it using NSTask? And in such a way that the JRE is fully sandboxed and thus acceptable by the Mac App Store? Or, has anyone successfully created a sandboxed Cocoa app that runs a .jar file without needing a separate Java installation? If so, would you be willing to share how you did it?
(I took out a developer tech support incident with Apple asking for help on this, but was told that they couldn't help at all given that Java is now considered a third-party development environment.)
Many thanks in advance for any suggestions or pointers to web pages I may have missed.
I can't be sure, but I strongly suspect that when that Apple engineer says they suggest "embedding" the Java runtime, he doesn't mean "bundle a separate executable into your app bundle and run it in a separate process" so much as he means "spin up a Java VM within your own process and run what you need to in that VM." It's arguably more cumbersome to do this than it is to run Java in a separate process, but it is possible.
Have a look at the NSJavaVirtualMachine class. It may not help you if the user doesn't have Java installed, but the idea would be the same - you would just build yourself a library containing the Java Runtime, link it into your main binary, then create and manage the JVM using the JNI API. Google for JNI_CreateJavaVM.
I gave a quick example of spooling up a JVM and calling into Java using JNI in another question (Calling a Java class function from Cocoa with JNI), although that was predicated on using the Apple-bundled JavaVM.framework, so it doesn't include steps on building the library you would need to link. I don't have any experience with that, unfortunately.
To answer your sub-question about sandbox and aux binaries, that's not a problem. You just have to mark the binary as inheriting the sandbox.
Have an .entitlements file like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>
And make sure you have a build phase in Xcode that codesigns the aux binary:
codesign --entitlements myjava.entitlements -s "${CODE_SIGN_IDENTITY}" java
Related
All of the solutions I found on stackoverflow suggest wrappers to register java application as windows service. My requirement is totally different. Please don't suggest wrappers for the purpose. The question is very simple I have java executable and I want to register it as windows service.
Phyiscal Path
Service Properties
Unfortunately we don't have backup of previous setup that installed it as windows service at the first place. Do I need some setup program or anything like that.
Not necessarily.
It is difficult to advise you on precisely what you need to do without more information on what you actually still have; e.g. an application installer, application JAR files, wrapper scripts, etc. Alternatively, if you told us what the application was, then maybe we could give you some hints on where to get installers, etc.
However, I can tell you definitely that registering java.exe or javaw.exe directly as a Windows Service will not work. These are not the executables for your Java application. Rather they executables for as Java Virtual Machine that will run your (real) Java application.
It is so easy task in case of Visual Studio. I want same support in Eclipse or anything else.
Well Java doesn't work like that. Java compiles to platform independent bytecode files, not to platform-specific native code. Sure, there are third party tools to generate exe's. However, using them is neither necessary, or desirable:
Why is creating an .exe from a java program not recommended?
(And asking for recommendations on what tools to use to do this is off-topic.)
Finally, if you take an arbitrary Java program and turn it into an ".exe" file, it won't necessarily be immediately registerable as a Windows service. This Q&A talks about turning an ".exe" into a Windows Service.
Create Windows service from executable
However, I can't tell you if the advice given there is appropriate for an ".exe" file created from an arbitrary Java app by some unspecified 3rd-part tool.
My recommendation:
If you are starting from scratch, use a Java Service Launcher / Wrapper.
If not, talk with whoever supplied and/or installed this application in the first place.
If you can't find any information about the application and where it came from, or if the vendor has gone out of business ... you need to urgently look for an alternative.
As far as I know, I can run .mex files on Linux that were generated on Windows by installing Matlab Runtime on Linux (correct me if I am wrong). But what if I want to use a MATLAB generated java package, that was generated on Windows, on a Linux (like Ubuntu)?
Objective:
I have to test a feature that uses audio processing. If test is successful, we will buy the products we need. At the moment I have my requested license on Windows, since the requested license have machine specific limitation, I am able to generate some test java code on my Windows machine, now the application is to be deployed on android, so I learnt from google that it needs matlab runtime to run or compiler to use converted/generated code. Android system has no MCR or simple Matlab Runtime installation support, so I moved to this solution.
Use a linux to host servlet that takes some input from android, do processing return answer in terms of json or text. Now my java package is generated using Windows machine, and I am lost.
From my knowledge this code-convert-servlet-deploy-once approach is cost effective than MATLAB Production Server, since we have to buy license once for the specific products. Remember licensing phase is after we test if this approach is giving us desired results.
Specs:
Windows 10
MATLAB 2016a (Trial)
MATLAB products (Compiler/sdk, Signal Processing/Audio Processing Toolbox)
Package made using JDK 1.7.x (Exactly matching MATLAB jdk/jre version on Windows)
Ubuntu 16 Desktop (with Oracle jdk 8_101 installed, also MATLAB Runtime installed, I can also work with jdk 7.x (same as MATLAB used on Windows when generating package))
Questions:
How can I use this java package in Linux when I create a java program?
What software + licenses are needed to make it possible?
Should I install MATLAB ON Linux machine, generate Java Package ON Linux machine and use that package in java program ON same linux machine? ( I think I will need to request license for it again )
Are there any other methods? Am I missing something?
Java packages generated by MATLAB Compiler SDK are in general cross-platform - however, they may call mex files, or other libraries, that are platform-specific, and if they do the Java package as a whole will end up being platform-specific.
You aren't entirely clear about whether you're calling mex files or not; and you may be calling platform-specific libraries without realising it (for example, Signal Processing Toolbox might call out to some library for some of its operations).
In addition, your comment about being "able to run mex files on Linux that were generated on Windows by installing the MATLAB Runtime on Linux" is confused - mex files are not cross-platform, and the don't use MATLAB Runtime at all.
So with respect to platforms - you may be able to use a Java package generated on Windows on Linux, so long as it doesn't call any Windows-specific mex files or libraries. But if you generate it on Linux, you can rule that issue out, so it will be easier for you if you use the same platform for compilation and execution. It should be fairly easy for you to reassign your MATLAB license to a Linux machine to do that.
Am I missing something?
Yes: the way you're proposing to do things is very unlikely to scale well. If you have a Java servlet on your Linux server along with a Java package generated by MATLAB Compiler SDK, then whenever you make a call to the servlet it will make a call to the Java package, which will start up the MATLAB Compiler Runtime (MCR), run your MATLAB code, return the answer to the servlet, and then shut down the MCR.
The MCR takes quite a long time to start up (nearly as long as MATLAB). So each call will take rather a long time, just due to MCR startup times.
So you can get around that by creating some sort of utility tool that will start up a an MCR and keep it there, and pass through requests and return answers to the servlet.
But then you've only got one MCR - what happens if you get multiple requests at once? They'll be queued up (or dropped) and it won't scale. So you'll need to improve your utility tool, so that it manages a pool of MCRs and passes requests through to a free one, load-balancing them as it goes.
But then what happens if an MCR crashes, or runs ouot of memory? The utility tool will need to monitor that possibility, and restart any crashed ones.
And you'll need some extra stuff that will enable you to administer all that stuff conveniently.
Once you've done all that (which will be hard), you'll realise that you have now pretty much written MATLAB Production Server. I know it's expensive, but you might like to take another look at it before committing to the solution you're considering.
I have a program which is being distributed to companies where java is either not allowed on their computers or not allowed to be updated for various security reasons. It is a java jar as it stands, a simple survey-type desktop program using swing.
My question is, how can I distribute this program to the various end users when they aren't allowed to install anything on their systems, including java? They will be running the program from a flash drive, so it has to just run from there with no installation or copying to the disk or anything like that, and no guarantee that java will be installed.
All of the target users are on windows, at least, so an exe is an option.
EDIT: Based on what Rob has said, does anyone know if distributing a private JRE is possible? Bundling a JRE which is preinstalled on the flash drive, and then pointing the jar to that?
I don't believe that there is anyway to do this using Java. The role of the JVM is to interpret the java byte code into instructions which will function on the device which the JVM is installed on. If no JVM is installed, your intermediate code (JAR file) can't be run.
You may look into distributing your app via ClickOnce if .Net development is an option. It will allow Windows users to install and run applications with limited permissions even without administrative access on their computers.
I have studied Java Web Start and found it complex and clumsy for my purposes. In addition, my app needs to access the PC resources, which causes more hoops to be jumped through with Java Web Start. To add to the difficulties I need to access a 32-bit native library (libvlc) so I need to insure that my app runs under 32-bit Java. Is there an easy way to deploy my app without resorting to Java Web Start? Needless to say, I want everything to be contained in a single .exe file.
I would start by searching the Internet for keywords such as "java 2 exe" and "jar to exe", etc. Doing so yields many freely available software packages that convert Java programs into Windows executables, for example:
JexePack - http://www.duckware.com/jexepack/index.html
JarToExe - http://www.regexlab.com/en/jar2exe/
JSmooth - http://jsmooth.sourceforge.net/
And the list goes on. Perhaps one of them meets your needs?
I am answering my own question to help people understand how to do this, which has taken me some number of days to figure out.
My initial problem was that my app would run on some versions of Windows but on others it was having problems finding the libvlc native library. I finally figured out that my app must run with 32-bit Java in order to use the 32-bit native library. Thus, the problem then became how to insure that the user started my app with 32-bit Java.
I read about Jar2Exe (http://www.regexlab.com/en/jar2exe/) in another post and decided to check it out. It is a great little program that is very configurable so I figured that it must be able to handle my 32-bit Java problem. In fact, it does so without even needing to do any configuration. The resulting .exe file contains my app along with all the required jar files and starts up with the 32-bit Java. I am very pleased with this program and plan to buy a license, which is very cheap.
Hope this saves time for other people who are trying to solve a similar problem.
Is it possible to integrate a Matlab program into a Chrome extension using the Matlab Builder JA?
Essentially, I have a computational tool in Matlab that I want to make more user-friendly and widely-available for other researchers with few or no programming skills. The best way to do this seems to be deploying it on the web--and, since I don't have access to a web server, in a Chrome extension. In order to deploy Matlab on the web via Java, it seems I need to upload the JRE or JDK and do a lot of other configurations on a server, like in http://www.mathworks.com/help/javabuilder/web-deployment.html (need a Matlab account to view).
Any workarounds for the extension that don't require a web server? Or other ideas to distribute my package to non-programmers so that they can use it?
Thanks!
I was in a similar situation, and I solved it in a slightly more elegant way than trying to play with web plugins:
In order to make the functions of my package accessible to non-programmers, I built a very simple GUI using guide in matlab, which allowed users to open data files, choose processing parameters, run the analysis, and export the results. Guide is very simple to use, and there are some good tutorials online. Then in terms of distributing it, I packaged all the necessary matlab files into a single folder, and then wrote a bash script (linux/mac) that would copy the files into a sensible directory, make a shortcut in /usr/bin/ (so that the GUI could be opened directly from the command line by running scatter_analysis without invoking any other display from matlab), and finally make a double-clickable shortcut on the desktop. The only prerequisite is that the user has matlab installed already.
I presume you're using windows, which I know nothing about, but I think it's likely that you can come up with a similar solution on the windows platform with far less effort than wrestling with web plugins? Unfortunately I cannot share my code - I'm in the process of selling it and any disclosure would violate the terms of the sale.