The previous article mapped Adobe Campaignβs tiers and URLs and parked βTomcat :8080β in the application layer. But Tomcat isnβt what runs your JavaScript. This article opens that layer up to show the five environments where server-side JS actually executes, workflow, delivery, JSSP, web app, and typology rule, and the single engine sitting underneath them all.
Whatever the environment, every Adobe Campaign server-side script is executed by the same interpreter: SpiderMonkey, embedded in the native nlserver core. Here is that application layer opened up:
βββββββββββββββββββββββββββββββ APPLICATION LAYER ββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββ nlserver (C++ process) ββββββββββββββββββββββββββββ
β β
β ββββββββββββββββββββββββββ SHIM Java (light) ββββββββββββββββββββββββββββββ β
β β JVM OpenJDK + Tomcat (Jakarta EE) :8080 http Β· :8005 ctrl β β
β β JSP OOB : soaprouter.jsp logon.jsp s.jsp schemawsdl.jsp ping.jsp β β
β β JSPContext + SoapMethodCall(SOAP_ENCODING_NATIVE) β executeSOAPCall() β β
β βββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ β
β β JNI in-process (soapRouter="http://jni")
β βΌ β
β βββββββββββββββββββββββββββ NATIVE CORE (C++) βββββββββββββββββββββββββββββ β
β β libnlsrvmod.so β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β libmozjs.so β SpiderMonkey (E4X) β β β
β β β executes .jssp + AC JSAPI / xtk (NLWS Β· NL Β· E4X Β· ES3/ES5) β β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β libxmldom.so (DOM XML) libxslproc.so (Xalan XSLT) β β
β ββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ β
β Shared modules: web Β· wfserver Β· mta Β· stat Β· inMail Β· syslogd β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
One engine, five environments
These are not five runtimes, but five entry points into the same SpiderMonkey interpreter. Two rules follow from that:
-
The language is identical everywhere. ES3/ES5 with E4X,
var/constbut nolet,functionbut no arrow, no template literals β a snippet valid in a workflow is valid in a JSSP. See modern best practices. -
Only the exposed objects change.
request/responsein a JSSP,instance/varsin a workflow,ctxin a web appβ¦
So the question is never βdoes this JavaScript run?β but βis this object available *here?β* β and the answer lives in the reference.
Unit tests
Tested with acc by running
acc instance exec -f test/integration/environments.spec.js in a sandbox:
loadLibrary("/nl/core/shared/nl.js"); // import NL.assert
context.es3.parseInt = NL.assert(parseInt("08") !== parseInt("08", 10));
context.es5.keys = NL.assert(typeof Object.keys === "function");
context.es5.isArray = NL.assert(typeof Array.isArray === "function");
context.es5.bind = NL.assert(typeof Function.prototype.bind === "function");
context.es5.stringify = NL.assert(typeof JSON.stringify === "function");
context.es5.strict = NL.assert(
(function () {
"use strict";
return typeof this === "undefined";
})() === true
);
context.es6.map = NL.assert(typeof Map === "undefined");
context.es6.promise = NL.assert(typeof Promise === "undefined");
context.es6.assign = NL.assert(typeof Object.assign === "undefined");
context.spiderMonkey.uneval = NL.assert(typeof uneval === "function"); // SpiderMonkey uneval() is Mozilla-only
context.spiderMonkey.oldProxy = NL.assert(typeof Proxy !== "undefined"); // 8. SpiderMonkey Proxy API, gone with ES6 Proxy
context.e4x.xml = NL.assert(typeof XML === "function"); // 3. E4X - 1 of four native XML globals
context.e4x.xmlType = NL.assert(typeof new XML("<x/>") === "xml"); // 4. E4X - 2 of four native XML globals
context.mozillaIter = NL.assert(typeof Iterator === "function"); // 9. Legacy Mozilla iteration protocol (pre-ES6)
context.nlserver.native = NL.assert(typeof getUUID() === "string");
context.nlserver.xtk = NL.assert(getOption("XtkDatabaseId").length > 0);
context.nlserver.sql = NL.assert(sqlGetInt("SELECT 1") === 1);Going further
Ready to call the API? Start with π queryDef in the
π AC JS Reference, or step back to the
π N-tier architecture to see how the layer above
routes requests down here.