What happens to JavaScript code after app is compiled using Titanium Mobile - javascript
I installed Titanium from appcelerator and built the "KitchenSink" example application.
All works well, I'm just wondering where does the javascript code ends up in a built app.
I grep-ed the Xcode project and also the result application as I found it in Library/Application Support/iPhone Simulator/....KitchenSink.app, but I can't find any function names from .js files, not even string texts used within the application.
Nearest information I found is an answer here : How Does Appcelerator Titanium Mobile Work? but I do not understand clearly how the process works.
Is the javascript code being compiled into a binary code (what compiler is used then?), or is it just transformed in some special data-format and interpreted in a running application ?
Update:
This is what I can see in a build/android directory of KitchenSink:
michal:bin mac$ find . -name table_view_layout\*
./assets/Resources/examples/table_view_layout.js
./assets/Resources/examples/table_view_layout_2.js
./assets/Resources/examples/table_view_layout_3.js
./assets/Resources/examples/table_view_layout_4.js
./assets/Resources/examples/table_view_layout_5.js
./classes/org/appcelerator/generated/examples/table_view_layout.class
./classes/org/appcelerator/generated/examples/table_view_layout_2.class
./classes/org/appcelerator/generated/examples/table_view_layout_3.class
./classes/org/appcelerator/generated/examples/table_view_layout_4.class
./classes/org/appcelerator/generated/examples/table_view_layout_5.class
michal:bin mac$ unzip -t app.apk | grep table_view_layout
testing: assets/Resources/examples/table_view_layout.js OK
testing: assets/Resources/examples/table_view_layout_2.js OK
testing: assets/Resources/examples/table_view_layout_3.js OK
testing: assets/Resources/examples/table_view_layout_4.js OK
testing: assets/Resources/examples/table_view_layout_5.js OK
I didn't look into app.apk before, all I could see were these class files corresponding to each of the javascript files. Therefore I assumed that on Android javascript is being compiled for JVM. Why can't these be found in app.apk ?
Titanium is not a wrapper around a web view as stated before (though that accurately explains how Phonegap works). Jeff's answer, linked in the question, is a technically correct explanation of how Titanium works, but here's the best version I've heard so far, from Marshall Culpepper:
It's true that Titanium Mobile used the WebView (in both Android and iOS) in the pre-1.0 days. However, this is no longer true and hasn't been since our 1.0 release is March 2010.
Since 1.0, we've shipped two separate Javascript runtimes with our apps, and we are running the Javascript code directly without a WebView. Your entire app from start to finish is now controlled by JS, and we provide a comprehensive set of Native APIs that enable this. Everything from UI widgets (yes, including WebView), Core APIs like Networking, Filesystem, Database, all the way to OS-specific things like JS Activities in Android. On the JS runtime front, we're shipping a forked version of WebKit's JavaScriptCore in iOS and a snapshot of Rhino 1.7 R3 CVS for Android. What we actually do with your javascript source is dependent on the platform, but generally it breaks up like this:
Source is statically analyzed to find references to Titanium modules
Localization strings (strings.xml), App metadata (tiapp.xml), and density specific images all generate platform specific analogs.
In iOS:
An XCode project / configuration is generated
JS Source is base64'd and inlined as a variable into a generated C file
xcodebuild is used to generate the final binaries
provisioning profiles, signing keys etc are applied
iTunes and some other glue are used to send the IPA to your iOS device
In Android:
An Android / Eclipse project is generated
In "Development" mode, JS source is packaged as APK assets
In "Distribution" (production) mode, when you're ready to ship the app, we compile the JS to Java bytecode using the Rhino JSC compiler. You can also enable this during development mode by setting "ti.android.compilejs" to "true" in tiapp.xml, see: http://developer.appcelerator.com/question/100201/enable-android-byte-code-compile
dex, aapt, and other Android SDK tools are used to build and generate the final APK
adb and keytool are used for pushing the APK out to the emulator and/or device
There are many more details that I could dive into specifically on each of these points, but the point I wanted to drive home is that we no longer use the WebView as our Javascript engine. You can however still embed WebViews, and we provide some simple integration that allows you to call Titanium APIs from an embedded WebView.
What jhaynie is saying in your linked question is that Titanium interprets your JS code and converts it into something that is almost identical to Objective-C.
In a web application, the browser reads and interprets your Javascript and runs associated native code (perhaps C++) internally. For instance, the browser might say, "This script is executing getElementById(), so I'll run my own C++ methods to accomplish that." What Titanium is doing is figuring out what that JS->C++ (or in this case, JS->Objective-C) would be in advance, and compiling that. It still leaves an interpreter open where necessary for your dynamic code, but it will convert and compile what it can.
That means you won't find anything that looks similar to what you originally wrote in your script. Anything that must be left to an interpreter is still processed and converted, and your symbols will change (e.g. a call to myTestFunction() might be converted to A(), or 10001101001101 :P).
The usual use of Javascript is to have it interpreted real-time by a running program. That's not what's going on here, and that's why you can't see any trace of your script.
Javascript is pre-processed
Titanium performs the interpretation of your script as any other program would do (such as a web browser). It figures out what dependencies your script has on the Titanium API and sets that stuff up. It then maps your symbols directly into (in the case of the iPhone) Objective-C.
A program usually would read in your script (which is a simply a String), interprets it, and runs C code to accomplish what your script asked for. Titanium does this before-hand to figure out what C code should be run, and does the conversion in advance.
Code is compiled where possible
Based on the interpretation of your code and its dependencies on the Titanium API, Titanium figures out what code can be directly compiled, and what must not be compiled in order to allow for they full dynamics of Javascript. I don't know how it chooses what does and doesn't get compiled, but you could check out the source if you want to know that much detail.
Code that must still be interpretted (left as a script) is still converted into symbols that result in more efficient mapping to native code. So it's still an interpreted script, but that doesn't mean it's still Javascript. This means that these parts of your script will still run faster than usual Javascript.
For iPhone, the compilable C is compiled with GCC to create a native binary.
You have a runnable app*
Now you have an app that you can run on your mobile device. Your compilable code has been compiled and runs at lightning speed, while the rest is converted and still interpreted in a more efficient way which runs at near lightning speed. :P
I hope this makes sense now, because it's all I've got! :D
Related
Can Swift Scripts Execute in a Swift iOS App?
We have an iOS app (Obj-C) that grabs a JavaScript file from AWS S3 to run our proprietary algorithm on a bunch of raw image data right on the iPhone (Lambda functions produced some latency I guess). For the sake of security, the JavaScript is obfuscated and entirely unreadable, and even harder to debug. Well, the JavaScript is spitting out NaN result values back to the iPhone, and I am seriously struggling to even find where this NaN pollution starts. Very frustrating. Behind the scenes I am working on refactoring this entire project to leverage Swift instead. It's much easier to dev/maintain than Objective-C (IMHO). Also, Swift can be used for scripting, so I'm thinking I can just reduce my tech stack by removing the JavaScript entirely. Question: Can a Swift script execute in a Swift iPhone app the same way JavaScript can? If yes, how? The Objective-C code snippet (modified for brevity) functionCall = [NSString stringWithFormat: #"some JS function call"]; [jsContext evaluateScript: functionCall]; JSValue* jsv = [jsContext objectForKeyedSubscript: #"result"]; NSDictionary* result = [jsv toDictionary]; // result is != nil, but the values are all NaN // Can't find the error when debugging JavaScript in Chrome // C# utility app that does the same thing produces good results I am aware that Apple will reject an app for the App Store if using an obfuscation tool on the source code is detected, or I'd consider purchasing a license for one. Also, we have an identical Android app, so if I can do the same with Kotlin scripts then I'll be a happy camper. Another concern I have is if the obfuscated JavaScript code is even increasing the security. I understand that a jailbroken device can access device memory and get a hold of code at runtime, which makes me think I'm performing an exercise in futility. Phrased differently, is the obfuscated JavaScript effectively more secure than manually/primitively obfuscated Swift source code?
As user jvnpdx stated, it is not possible to dynamically run a Swift script within the app.
How to debug javascript with Eclipse running local Tomcat server
There are a lot of questions on SO about how to debug a standalone piece of Javascript - that isn't what I want. None of the previous Eclipse/javascript questions seem to be on point, which surprised me. I am using Eclipse for Java EE (Neon, the latest version) to develop a JSP/servlet website - a full website, not just javascript, and not just java/jsp - everything together. I can compile my Java and "debug as" on an instance of Tomcat spawned by Eclipse, and the web pages show up inside of a window in Eclipse. I can set and hit Java breakpoints all day long while using "debug as" - but setting breakpoints in javascript doesn't do diddly squat. I've been having to run a standalone instance of Tomcat, deploy war files to it, wait for the war files to decompress, then debug my Javascript inside of Firefox. This is particularly annoying because I'm relatively new to javascript and am doing some complex things on the page (and truth be told, making some silly mistakes a compiler in a typed language would catch for me before letting me waste my time trying to run the code) and the "change, watch Eclipse chew deploying war, wait for Tomcat to chew uncompressing the war, test" cycle is just unacceptably long. Isn't there an easier way to debug BOTH java and javascript from the same IDE without having to export and deploy WAR files? Is there is a setting I can toggle or something I can install in Eclipse to make it an all-in-one IDE? Ideally I would like to be able to step through, for example, an AJAX call into my servlet AND watch what happens in the javascript after it returns - within the same debugging session - so let me preemptively state that copying the changed js file(s) directly to the decompressed folder in tomcat/webapps as a faster way to continue to do split debugging is not the kind of "workaround answer" I'm looking for.
JavaScript debugging is going to be supported in Eclipse Neon 1 release (September 2016). Here is a demo video in which step-by-step process of debugging both front-end and back-end is explained - https://youtu.be/7oQz1Ja1H08 . Basically, running Chrome / Chromium with extra parameters and tuning source mapping manually is not really user-friendly now, but we are going to improve it for Neon 1 and future releases. Contributions of any kind are most welcome ;)
Working with Javascript and Xcode
I'm experiencing a less-than-ideal workflow at the moment. Here's the context: The project is a hybrid native-web application The javascript files are either local (in a .bundle) or on a http server We have a lot of javascript tests, most of which are integration tests and must be ran in the simulator. Although I love javascript and the idea of a reusable application, I must recognize that Xcode doesn't play fair. The main pain is that, quite often and despite the full clean / simu reset, Xcode will need to compile twice before it takes the javascript changes in account. I've tried to touch all the javascript files before each build (as a script run build phase). I've also tried to clear the webview cache before each run: [[NSURLCache sharedURLCache] removeAllCachedResponses]; None of the two suffice. tl; dr: What is your workflow when working with javascript files inside an Xcode project, do you like it and how could I improve mine?
How does GWT Plugin work?
It is documented that GWT converts java code ( a few extensions not supported ) to javascript which gets rendered. When does this conversion happen? I want to know the steps and the agents involved at each step. Why do we need GWT plugins for each browser? What part of the conversion is handled by the library and what part is handled by the plugin? I have read a lot of tutorials but this point is still vague.
It is important to understand about GWT that there's a big difference between production mode and development mode. You write Java code and for deployment, the GWT compiler compiles it to JavaScript which is then interpreted by the browser. So, in production, the conversion happens only one time, before you deploy your web app to a server. And in this case, no browser plugin is needed because modern browsers can interpret JavaScript without any help. In development mode however, things are different. The Java code is interpreted by the GWT browser plugin directly, without an explicit compilation from Java into JavaScript. So you only need a browser plugin in development mode. And then there's super dev mode, which is different from the scenarios above. This page explains it all.
Developing Windows apps with JavaScript
I'm currently in the need of developing a Windows application. I want to keep things simple (in the spirit of uTorrent) and I would like the result program to be a single .exe file containing all that it needs. The program is simple. It just needs some UI. It needs to run for a long period of time (lay there as a tray icon). It needs to do some routine tasks like simple I/O. It also needs to access the internet, specifically some web server. Apart from these small requirements I would like to write all of it in JavaScript, as I feel more comfortable with it than any other language. I know there's things like Windows Script Host that let you run JavaScript programs and interact with some Win32 API, but will I be able to do everything I need with Windows Script Host? Can I pack all of the Windows Script Host in a single .exe? If not, what alternatives do I have for JavaScript?
I found that there's actually a JavaScript compiler that comes with the .NET framework called jsc.exe. For more information: http://www.phpied.com/make-your-javascript-a-windows-exe/ http://msdn.microsoft.com/en-us/library/7435xtz6(VS.80).aspx I guess it's not really JavaScript since it introduces extra things like import and even some class syntax which is weird for me. But this works perfectly for me as I will just doing things as I am used to on the web.
Aside from Windows Script Host, there are Windows Desktop Gadgets (Vista and Windows 7 only) HTML Applications (HTAs) Both are written with standard web technologies, HTML, JavaScript, Flash, etc. They can also be extended with COM objects/ActiveX controls such as FileSystemObject, WMI, WScript or even ones that you write yourself. Windows Desktop Gadgets have access to a separate API/namespace with various Win32-esque properties and methods.
It seems that nobody mentioned JSDB. JSDB offers a command line environment which you can execute arbitrary javascript code. You can easily compile to a .exe file by using the command copy /b jsdb.exe+program.zip program.exe It's important to know that you've got to call your main js file main.js within a standard zip file. Not sure if the name program.zip is required. I haven't actually tried making GUI applications with this yet - although it seems to support various APIs like ActiveX. It's possible that by using the copy /b command mentioned above, you could compile a script from the wscript.exe file - but I tried and couldn't get it working. Let me know if anybody tries and has success somehow.
I think you're looking for Adobe AIR The Adobe® AIR® 2 runtime enables developers to use HTML, JavaScript, Adobe Flash® software, and ActionScript® to build web applications that run as standalone client applications without the constraints of a browser. ~ The AIR website
Internet Explorer introduced the concept of Hypertext Applications in IE 5. It never made a big breakthrough, so resources and documentation are scarce. Mozilla-backed competitor Prism seems to be alive and well, though, and is definitely worth a look. Prism is an application that lets users split web applications out of their browser and run them directly on their desktop
I believe the best way to go is V8 JavaScript Engine provided by Google. "V8 can run standalone, or can be embedded into any C++ application." - which I believe is perfect for your needs, because you can do most of the stuff in JavaScript and use provided interfaces to communicate with the system.
I'm not 100% but I believe WSH uses JScript or WScript, not JavaScript.
Color me crazy, but its only a short step form Javascript to Java or C#. I'd suggest C# as, on a windows machine, the libraries are already there. You can just copypaste your .exe and let 'er rip.
If you want a single .EXE, what runtimes are you okay if they are required pre-requisites? If you're okay with requiring .NET runtime to be preinstalled, then you do all your work in JScript.NET
Chromium Embedded Framework (CEF) may give you some help. i have not clearly know how, but i realy found many Apps using this framework. http://code.google.com/p/chromiumembedded/ Introduce for CEF are: The Chromium Embedded Framework (CEF) is an open source project founded by Marshall Greenblatt in 2008 to develop a Web browser control based on the Google Chromium project. CEF currently supports a range of programming languages and operating systems and can be easily integrated into both new and existing applications. It was designed from the ground up with both performance and ease of use in mind. The base framework includes C and C++ programming interfaces exposed via native libraries that insulate the host application from Chromium and WebKit implementation details. It provides close integration between the browser control and the host application including support for custom plugins, protocols, JavaScript objects and JavaScript extensions. The host application can optionally control resource loading, navigation, context menus, printing and more, while taking advantage of the same performance and HTML5 technologies available in the Google Chrome Web browser. Numerous individuals and organizations contribute time and resources to support CEF development, but more involvement from the community is always welcome. This includes support for both the core CEF project and external projects that integrate CEF with additional programming languages and frameworks (see the "External Projects" section below).
Why not use Rhino -- JavaScript on the JVM? You can even compile your scripts to .class files and package them into a JAR along with Rhino for easy distribution...