Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reload Single Copy XPage Design (SCXD) *Java* Application Design

Tags:

xpages

I'm using Single Copy XPage Design, with all my business logic written as Java in files in WebContent\WEB-INF.

If I need to make a change to an XPage or Custom Control, I can update my template, refresh design and the change is picked up immediately.

However, if I want to make changes to the Java code, everything seems cached and the only method I've found to pick up the changes is to restart http task.

So far I've tried:

  • refreshing the design of the SCXD database
  • replacing the design of the SCXD database
  • cleaning the SCXD database
  • editing the faces-config (both in the template and the SCXD database)
  • deleting the .class files for the compiled Java code in the SCXD database and re-building
  • issuing a "tell http xsp refresh" command to the server
  • replacing the SCXD database with a new copy
  • replacing the design of the database that's pointing to the SCXD database

Nothing seems to get the web to pick up the Java code changes, other than restarting the http task.

Is there something I've missed?

like image 308
Paul Stephen Withers Avatar asked Apr 28 '15 13:04

Paul Stephen Withers


1 Answers

We've logged this issue as SPR# LHEY9X5EBP.

I sent this question around the XPages team, and Maire Kehoe provided the following information and workaround to try.

Not a known issue. Looks like a bug in NSFComponentModule.refresh(), when there is a templateModule, it never finds any change to files, and never resets the classLoader.

Workaround: Button to click to do the reset.

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:button value="Reset App ClassLoader" id="button1">
    <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
        <xp:this.action><![CDATA[#{javascript:inapp.ResetUtil.reset()}]]></xp:this.action>
    </xp:eventHandler>
</xp:button>

Java code:

package inapp;
import com.ibm.domino.xsp.module.nsf.ModuleClassLoader;
public class ResetUtil {

    public static void reset(){
        ClassLoader appClassLoader = Thread.currentThread().getContextClassLoader();
        ((ModuleClassLoader)appClassLoader).resetDynamicClassLoader();
        // That code will give:
        // Script interpreter error, line=1, col=17: Error calling method 'reset()' on java class 'inapp.ResetUtil'
        // Access denied (java.lang.RuntimePermission getClassLoader)
        // need to edit C:\Domino\jvm\lib\security\java.policy file to have:
        // grant codeBase "xspnsf://server:0/disc2.nsf/-"{ // nsf name here must be .toLowerCase of actual nsf name.
        // permission java.lang.RuntimePermission "getClassLoader";
        //};
    }
}

Permissions to allow that Java code to run. In C:\Domino\jvm\lib\security\java.policy add a line like so, updated to your nsf name:

grant codeBase "xspnsf://server:0/disc2.nsf/-"{ // nsf name here must be .toLowerCase of actual nsf name.
    permission java.lang.RuntimePermission "getClassLoader";
};
like image 175
Brian Gleeson - IBM Avatar answered Nov 09 '22 18:11

Brian Gleeson - IBM