Xpages 运行时将 java 包名称解释为字符串对象

Xpages runtime interpreting java package name as String object

从我们当前的 Xpages 项目中的所有怪事来看,这个项目目前已经达到了上限:

我们在当前项目中创建了几个 java bean。在 Domino Designer 中,它们都存储在 Code >> Java 下面,因此很明显它们自动成为项目类路径的一部分。我们所有的 bean 都属于一个包结构 de.edcom.*(这就是我们一直在使用的,没有任何问题)。这些对象主要是使用完整的包名称从 SSJS 调用的(由于各种原因未注册为托管 bean),如

var o = de.edcom.myObject.someMethod();

在我以前的 Xpages 项目的 none 中,这引起了任何问题,它只是工作。然而,在当前项目中,XSP 运行时突然开始将包名称解释为 String 对象,给我们这个运行时错误:

Unknown member 'edcom' in Java class 'java.lang.String'

有问题的 ssjs 代码行如下所示:

return de.edcom.TOC.buildTOC();

我们完全不知道是什么原因导致的,为什么只在这个项目中,为什么它有时有效,但大多数情况下无效。

这个项目和之前的项目有一个区别,那就是本地化:用户可以在"english"和"german"语言环境之间切换,当然我们使用的代码是

context.setLocaleString("de")

当然,我们有几个 java 脚本代码片段来寻找本地设置,如

if(context.getLocalString()==="de"){...

今天早上我们实际上已经将所有 java beans 重命名/重构为不同的包名称 (com.edcom.*),从那时起错误就没有出现(祈祷吧!)。

不过我又觉得这太愚蠢了,不可能真的有联系,或者可以吗?

编辑:

我尝试将 importPackage()xe:objectData 数据源结合使用(正如 Adrian 和 Paul 在他们的回答中推荐的那样),但我仍然收到“unknown member 'edcom' in Java class 'java.lang,String'”消息,现在只在代码中的不同位置,在我的行中说 importPackage(de.edcom).

我将切换回 "com.edcom" 包并继续寻找更好的解决方案;不幸的是,在整个代码中搜索字符串 "de" 会产生接近 12.000 个匹配项;现在可以在大海捞针中找到真正的原因

编辑#2:

看起来我们终于找到了可怕的 "de" 变量:它很好地隐藏在计算的 customControl 属性 中;我不知道为什么我在过去几天执行的所有文件搜索都找不到这个文件。

无论如何,很高兴知道我们在命名 ssjs 变量时必须更加小心;我从没想过 ssjs 变量名会干扰 Java 包中的 TLD 部分;我们可能会制定一项内部政策,我们的变量必须命名为“vDe”、“vCom”、“vIt”等,而不仅仅是简短的小写字母......

SSJS 需要将被放入一个范围内的变量。任何带点的东西都会首先转到那些变量。听起来本地化将翻译存储在名为 "de" 的变量中,这可以解释您的问题。

也许 importPackage(de.edcom) 然后使用 return TOC.buildTOC(); 可以解决问题。我会考虑更好的做法,但无论哪种方式,在 SSJS 中你都冒着变量名冲突的风险。

就个人而言,我更喜欢用控制器支持每个 XPage Java class(我使用 Jesse Gallagher 的 frostillicus 框架,所以它总是可以通过变量 pageController 访问),所以我的 SSJS 只调用 pageController.myMethod(),然后避免所有名称冲突并允许 Java 导入以确保我映射到正确的 Java class。有更多基本的方法可以做到这一点,例如每个 XPage 的顶部都有一个 xe:dataObject。

可能您在另一个 SSJS 脚本中使用了一个变量 de(它是一个字符串),在此之前 运行 遇到问题。

我见过类似的问题,即未在脚本块中显式声明的变量可以从另一个脚本块继承值。

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:this.beforeRenderResponse><![CDATA[#{javascript:
        var ex1 = "Hello World";
        var ex2 = "Bye bye"}]]>
    </xp:this.beforeRenderResponse>
    <xp:this.afterRenderResponse><![CDATA[#{javascript:
        print("value ex1: " + ex1);
        print("value ex2: " + ex2);}]]>
    </xp:this.afterRenderResponse>
</xp:view>

结果:

[1CA8:000C-4354] 10.06.2016 14:33:01   HTTP JVM: value ex1: Hello World
[1CA8:000C-4354] 10.06.2016 14:33:01   HTTP JVM: value ex2: Bye bye

因此您应该使用 importPackage() 函数将引用导入到您的 java 类 或更好,使用托管 beans 或 dataContexts.