Protecting your XPages Application
One of the hallmarks and success factors of IBM Notes was the openness of the design of all Notes applications. Since lots of people put blood, sweat and tears into their applications, Lotus added the possibility to hide the design of an application to protect it from spying eyes. While I don't like hidden designs I can understand the rationale.
Others keep their design open, but compile the LotusScript libraries with references to lss files outside, so the core business logic is protected.
Hiding the design doesn't work for XPages, you can poke around and get back to the source. So what are your options?
So how would a typical workflow look like? There seem to be quite some moving parts involved:
As usual YMMV
Others keep their design open, but compile the LotusScript libraries with references to lss files outside, so the core business logic is protected.
Hiding the design doesn't work for XPages, you can poke around and get back to the source. So what are your options?
- Keep your business logic in Java classes (Pojo, Beans, Managed Beans) and develop them outside of the NSF and transfer them as jar file only
- Deliver your custom controls as Extension Library (which can be deployed using an NSF) - which obviously requires advanced Skills
- Keep your XPages lean and handle the delicate parts in custom controls that you hide (see below)
So how would a typical workflow look like? There seem to be quite some moving parts involved:
- Develop and test your application as per normal. Keep items you want to protect in custom controls and Java classes
- Make sure you have your project build before doing the next steps
- Link your database to an On Disk Project for version control (but you do that anyway don't you?). Let's call that project "OnDisk Open"
- Have your target database (the one that you will deliver to your customer) setup in a similar way. Let's call that project "OnDisk Closed"
- Copy all elements you want to keep open (Forms, Views, XPages, CSS etc.) from OnDisk Open to OnDisk Closed
- Copy your Java source files and the generated Java source files for your custom controls (found in the Local directory, actually outside the NSF) in OnDisk Open to a src structure. Custom controls live in the xsp package. Your code lives in your packages
- Compile your Java
- Put all the compiled classes into a jar
- Copy that jar into the
/WebContent/WEB-INF/lib
folder of the OnDisk Closed project. At the first time: add this jar to the classpath of your closed.nsf after sync with the OnDisk Closed project - Copy the
.xsp-config
files of the custom controls you processed in the previous 4 steps into the/WebContent/WEB-INF/
directory (the same directory yourfaces-config.xml
is living in) - Sync the OnDisk Closed project with closed.nsf
- Build your closed.nsf - done
- ANT is unaware of the EFS (Eclipse Virtual File System), it acts on regular files only, so your operations need to run against the OnDisk projects rather the NSF directly
- The Java compile command is unaware of Eclipse and its classpath too. You need to specify that. Is is easier than it looks. Use the Navigator view to locate the
build.properties
file, right click on it, select PDETools - Create ANT build file. It will create a build.xml you can use for starters. The piece you are interested in is<path id="Plug-in Dependencies.libraryclasspath">
. You need to add that to your compile classpath together with your bin directory in a statement like this:<path id="YourBeans.classpath"><pathelement location="bin" /><path refid="Plug-in Dependencies.libraryclasspath" /></path>
- Configure your Domino Designer to automatically pick up changes from the file system. File - Preferences - Workspace - Refresh automatically
- While you are on it, generate your JavaDocs too
<?xml version="1.0"?>
<project name="Protect XPages" default="main" basedir=".">
<!-- Sets variables which can later be used. -->
<!-- The value of a property is accessed via ${} -->
<property name="src.dir" location="src" />
<property name="build.dir" location="bin" />
<property name="docs.dir" location="doc" />
<property name="closed.project.dir" location="C:\ondisk\closed" />
<path id="Plug-in Dependencies.libraryclasspath">
...
</path>
<path id="YourBeans.classpath">
<pathelement location="bin" />
<path refid="Plug-in Dependencies.libraryclasspath" />
</path>
<path id="JavaDoc.classpath">
<pathelement location="bin" />
<path refid="Plug-in Dependencies.libraryclasspath" />
</path>
<!-- Compiles the java code (including the usage of library for JUnit) -->
<target name="compile">
<javac srcdir="${src.dir}" destdir="${build.dir}">
<classpath refid="YourBeans.classpath" />
</javac>
</target>
<!-- Creates Javadoc -->
<target name="docs" depends="compile">
<javadoc packagenames="src" sourcepath="${src.dir}" destdir="${docs.dir}">
<classpath refid="JavaDoc.classpath" />
<!-- Define which files / directory should get included, we include all Java -->
<fileset dir="${src.dir}">
<include name="**/*.java"/>
</fileset>
</javadoc>
</target>
<!--Creates the deployable jar file -->
<target name="jar" depends="compile">
<jar destfile="${closed.project.dir}/WebContent/WEB-INF/lib/YourBeans.jar">
<fileset dir="${build.dir}" />
<manifest>
<attribute name="Main-Class" value="com.notessensei.Test" />
</manifest>
</jar>
</target>
<!-- Copies the java and .xsp-config files, careful with the selections here
use individual copy statements or file sets -->
<target name="copy">
<copy todir="${src.dir}">
<fileset dir="Local">
<!-- presuming all your custom controls start with cc -->
<include name="**/cc*.java"/>
</fileset>
</copy>
<copy todir="${closed.project.dir}/WebContent/WEB-INF">
<fileset dir="CustomControls">
<include name="**/*.xsp-config"/>
</fileset>
</copy>
<!-- 1:1 copy of forms/views and other stuff omitted here -->
...
</target>
<target name="main" depends="copy, compile, docs, jar">
<description>Do it all </description>
</target>
</project>
You can run this ANT file, by right clicking on in in Domino Designer selecting "Run as ANT file".
<project name="Protect XPages" default="main" basedir=".">
<!-- Sets variables which can later be used. -->
<!-- The value of a property is accessed via ${} -->
<property name="src.dir" location="src" />
<property name="build.dir" location="bin" />
<property name="docs.dir" location="doc" />
<property name="closed.project.dir" location="C:\ondisk\closed" />
<path id="Plug-in Dependencies.libraryclasspath">
...
</path>
<path id="YourBeans.classpath">
<pathelement location="bin" />
<path refid="Plug-in Dependencies.libraryclasspath" />
</path>
<path id="JavaDoc.classpath">
<pathelement location="bin" />
<path refid="Plug-in Dependencies.libraryclasspath" />
</path>
<!-- Compiles the java code (including the usage of library for JUnit) -->
<target name="compile">
<javac srcdir="${src.dir}" destdir="${build.dir}">
<classpath refid="YourBeans.classpath" />
</javac>
</target>
<!-- Creates Javadoc -->
<target name="docs" depends="compile">
<javadoc packagenames="src" sourcepath="${src.dir}" destdir="${docs.dir}">
<classpath refid="JavaDoc.classpath" />
<!-- Define which files / directory should get included, we include all Java -->
<fileset dir="${src.dir}">
<include name="**/*.java"/>
</fileset>
</javadoc>
</target>
<!--Creates the deployable jar file -->
<target name="jar" depends="compile">
<jar destfile="${closed.project.dir}/WebContent/WEB-INF/lib/YourBeans.jar">
<fileset dir="${build.dir}" />
<manifest>
<attribute name="Main-Class" value="com.notessensei.Test" />
</manifest>
</jar>
</target>
<!-- Copies the java and .xsp-config files, careful with the selections here
use individual copy statements or file sets -->
<target name="copy">
<copy todir="${src.dir}">
<fileset dir="Local">
<!-- presuming all your custom controls start with cc -->
<include name="**/cc*.java"/>
</fileset>
</copy>
<copy todir="${closed.project.dir}/WebContent/WEB-INF">
<fileset dir="CustomControls">
<include name="**/*.xsp-config"/>
</fileset>
</copy>
<!-- 1:1 copy of forms/views and other stuff omitted here -->
...
</target>
<target name="main" depends="copy, compile, docs, jar">
<description>Do it all </description>
</target>
</project>
As usual YMMV
Posted by Stephan H Wissel on 24 July 2013 | Comments (4) | categories: XPages