CEP: In-Circuit Debugging of a .zxp File

It’s not common knowledge, but you can package a CEP extension into a .zxp file and debug it ‘in-circuit’, without needing to set the CEP debug flag.

My trick is to not use the ZXPSignCmd to package up the .zxp file.

Last time I checked, as far as I could tell, the ZXPSignCmd app takes notice, and will omit the .debug file and will refuse to add it.

However, my new PluginInstaller is able to inject a .debug file into a packaged .zxp.

As it so turns out, that makes the installed extension debuggable, without setting the CEP debug flag.

You would not want to do this in a release version of your extension – but when it comes to diagnosing and debugging difficult-to-catch bugs on someone else’s workstation, this can be invaluable.

Below a little cookbook to demonstrate how you can go about this.

I’ve also made a ‘live video’ about it. The quality of the video is what it is, I think you can tell I am not interested in becoming a ‘Youtuber’. My main concern is the content, not the presentation.


First, download the CEPSparker project.


Click the green Code button and then click the option Download ZIP.

CEPSparker is a framework I made to help me generate ‘starter’ projects for CEP.

Important to note: CEPSparker is not a CEP extension project. It is a precursor to a CEP extension project.

`After downloading, if you’re on a Mac, you MUST right-click the initialSetupConfigApp.command file, select Open, then allow it to run by clicking the Open button.

This de-quarantines the other .command files so they can be double-clicked.

On Windows, expect some blue warning screens (click More Info and run anyway).

You will need to run the .bat files from the command line in an elevated Administrator CMD session; you can double-click sudo.bat to start such a session.

Next, double-click the SparkerConfig or SparkerConfig.exe application. For the demo, change the STARTERCODE dropdown menu and pick IFrameUIServer.

Click Generate.

This will generate a sample CEP project that has a ‘split personality’. The CEP panel is featureless, and only contains an <iframe>.

The content of this <iframe> is pulled from a web server.

The sample code demonstrates how such server-provided code can drive a user-interface inside a CEP panel, and interact with the local host app.

For the demo, we use a small local Node.js application to play the role of the ‘remote server’. The Generate will have created a lot of folders in the CEP project folder.

One of them is IFrameUIServer

Inside you find a little file server.js. You need to have Node.js installed; Google around if you don’t have it installed yet.

All you need to do is open a command line and navigate into this folder, then run

node server.js

and that will run a tiny web server on http://localhost:8001

Next, we will tweak the CRDT manifest for this CEP panel. The CRDT manifest (a file called CRDT_manifest.json) is used by PluginInstaller to determine what it needs to do to package the CEP panel.

Open CRDT_manifest.json in a text editor and change it so it reads:

"injectDebugFile": true,

You can leave the "productCode" entry set to CEPSparkerTest, for the sake of argument – we need this code for creating a product entry in PluginInstaller.

This tell the PluginInstaller to copy the debug file from the CEP Project into the ZXP and rename it to .debug.

If you inspect the debug file in a text editor, you see it configures the debugger to use port 8888:

<?xml version="1.0" encoding="UTF-8"?>
    <Extension Id="com.rorohiko.cepsparker.samplepanel">
            <Host Name="IDSN" Port="8888" /> 

Now run PluginInstaller and switch to developer mode (File – PluginInstaller ModePublisher/Developer). If you don’t have a registered account yet, you need to create one first: after switching to Developer mode, switch to the Accounts window.

Registration is free, but needs to be approved.

To register, you need to click New and fill in a terse bit of detail.

Once you click Register you’ll need to wait for a confirmation email, and after that, I will need to handle your registration request, and I will need to approve it first; if I don’t personally know you I’ll reach out via email.

Once you have a registered developer account, you can create a product entry in the Products window.

For this test, you can just fill in some random details. The only thing that needs to match is the product code which is CEPSparkerTest (unless you changed the "productCode" in CRDT_manifest.json – these names need to match for PluginInstaller to find the manifest).

Once you complete the new product entry, you can click Package… and navigate to the CEP project folder.

Once the packaging completes, you’ll find a .zxp file in the build subfolder.

For the demo, you can now install this .zxp file using a standard CEP installer (for example Anastasiy’s Extension Manager).

Make sure the Adobe CEP debug flag is turned off before trying this out if you want to verify that the debug flag has no influence on the debuggability of this .zxp

With the IFrameUIServer running, start InDesign and open the panel.

The panel should populate and show a UI that has a New Document button. This whole UI is served from the remote web server – if you look at your Node.js terminal window, you’ll see the http requests fly past.

Click New Document to create a new document.

Now start Chrome and access http://localhost:8888 – this will show you the familiar debug interface with two available sessions: one for the panel itself and a second one for the user interface inside the <iframe> on the panel.

Reach out to me if you find this kind of stuff helpful or interesting. I can help you kickstart your automation project and greatly reduce the time needed. In most of my projects, my role is to be a temporary member of the team, and help build the software, by managing, training, designing and coding, as needed.