1

From all the weirdness in our current Xpages project this one currently hits the ceiling:

we have created a few java beans in our current project. Inside Domino Designer they all are stored below Code >> Java, so that it is clear that they are automatically part of the project's classpath. All our beans belong to a package structure de.edcom.* (that's what we have been using forever without any problems). The objects are mostly called from SSJS using the full package names (the aren't registered as managed beans for various reasons) as in

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

In none of my previous Xpages projects this caused any problems, it just worked. In the current project, however the XSP runtime all of a sudden started to interpret the package name as a String object giving us this runtime error:

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

the ssjs code line in question is looking like this:

return de.edcom.TOC.buildTOC();

We absolutely don't have any clue as to what could be causing this, why only in this project, and why it sometimes IS working, but mostly isn't.

There's one difference between this projects and others before, and that is locallization: users can switch between "english" and "german" locale, and of course we are using codes like

context.setLocaleString("de")

and of course we are having several javascript code fragments looking for local settings as in

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

This morning we in fact have renamed / refactored all java beans to different package names (com.edcom.*), and since then the error hasn't appeared (fingers crossed!).

But then again I think this is just too stupid, there can't really be a connection, or can it?

EDIT:

I tried using importPackage(), in conjunction with an xe:objectData datasource (as recommended by Adrian and Paul in their answers), but I'm still receiving that "unknown member 'edcom' in Java class 'java.lang,String'" message, now only at a different position in the code at my line saying importPackage(de.edcom).

I'll be switching back to the "com.edcom" package and keep looking for a better solution; unfortunately searching for the string "de" inside the entire code yields close to 12.000 matches; now way to find the real reason for this in that haystack

EDIT #2:

looks like we finally found the dreaded "de" variable: it was well hidden in a computed customControl property; I don't have a clue why all the File Searches that I performed over the last few days couldn't find this one.

Anyways it is very good to know that we have to be even more careful when naming our ssjs variables; I never would have thought that a ssjs variable name could ever interfere with TLD parts in Java packages; we probably will make it an internal policy that our variables have to must be named "vDe", "vCom", "vIt" etc. instead of just short lowercase letters...

Lothar Mueller
  • 2,528
  • 1
  • 16
  • 29
  • 1
    Don't forget to explain the meaning of such internal policy. Otherways you could get into trouble with variable 'vA' and packages from Vatican :-) – Frantisek Kossuth Jun 13 '16 at 20:47

2 Answers2

3

Probably you used a variable de (which is a String) in an other SSJS script that run before that one faces the problem.

I've seen similar issues that a variable that is not explicitly declared in an script block can inherit values from another script block.

<?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>

results in:

[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

So you should use the importPackage() function to import the references to your java classes or much better, use managed beans or dataContexts.

Adrian
  • 153
  • 2
  • 14
  • sorry I had to withdraw my early acceptance of your answer; even with the useage of importPackage() and in conjunction with Paul's hint regarding xe.objectData I'm still receiving the same error; see my edition above – Lothar Mueller Jun 12 '16 at 10:05
  • 1
    did you search for any variable named "de"? – Frantisek Kossuth Jun 13 '16 at 07:18
  • yes I did, and finally found one, too (see my 2nd Edit) – Lothar Mueller Jun 13 '16 at 10:24
  • I'd be interested to know if that example of re-using variables works between pageLoad and renderResponse methods. I suspect not. I suspect the variable is declared when beforeRenderResponse triggers and, because it's at the page level, it's not removed until the end of the Render Response phase. I suspect if declared in beforePageLoad it would be removed at the end of page load, but I may be wrong. – Paul Stephen Withers Jun 13 '16 at 15:19
  • 1
    Unfortunately the variable is not removed anywhere. Take a look at the prints I've made. In every script block, I've set the var to the name of it self. `event afterRestoreView undefined` `rendered property of a panel: afterRestoreView` `rendered property of a panel: rendered property of a panel` `rendered property of a panel: rendered property of a panel` `event handler onclick button1: rendered property of a panel` `event beforeRenderResponse: event handler onclick button1` `rendered property of a panel: beforeRenderResponse` `event afterRenderResponse: rendered property of a panel` – Adrian Jun 16 '16 at 11:47
1

SSJS requires variables which will be put in a scope. Anything with a dot in it will first go to those variables. It sounds like localization stores the translations in a variable named "de", that would explain your problem.

Maybe importPackage(de.edcom) and then using return TOC.buildTOC(); would resolve the problem. I would consider that better practice, but either way in SSJS you're risking variable name collisions.

Personally, I prefer to back every XPage with a controller Java class (I use Jesse Gallagher's frostillicus framework, and so it's always accessible with the variable pageController), so my SSJS just calls pageController.myMethod(), which then avoids all name collisions and allows Java imports to ensure I map to the right Java class. There are more basic ways of doing it, e.g. with an xe:dataObject at the top of every XPage.

Paul Stephen Withers
  • 15,699
  • 1
  • 15
  • 33
  • Perfect help as ever, same applies to the other answer by @Adrian; since I can only accept one answer I decided to push some points to Adrian; hope you don't mind ;) - there's a typo in your answer, btw.: it should be 'xe:dataObject'. But I found it anyways (through help of one of your blog entries) – Lothar Mueller Jun 12 '16 at 09:48
  • hmm - was a bit early to accept an answer - still not working, see edition above – Lothar Mueller Jun 12 '16 at 10:03
  • 1
    The key is going to be finding out what the de object is. Since it exists when your code is running, having you tried `print(de)` (or some other logging syntax), to find out what it is? – Paul Stephen Withers Jun 13 '16 at 07:45
  • that's more or less what I did this morning, in fact I added a computedField; and just an hour ago I was able to pin it down to to a (well hidden) computed customControl property. The bottom line is that we never may use ssjs variable namesw that could possibly interfere TLD names, like "var com='Company'", "var it='information technology'" (if you're an italian developer, that is) etc. ;) - weird stuff... – Lothar Mueller Jun 13 '16 at 10:23
  • As an enhancement, IBM could manage translations by making the variable name `localization_de`, but not sure about the likelihood of that happening. – Paul Stephen Withers Jun 13 '16 at 15:17
  • No, that was definitely my own fault as it's been a var I set myselve. I just hadn't seen it, and then I had kind of expected that calling a java object was something different than calling a String var. Which of course is rubbish if look at it at the light of day... – Lothar Mueller Jun 13 '16 at 16:42
  • 1
    Glad you tracked it down eventually. Sounds like it's been a useful learning experience, although painful at the time. – Paul Stephen Withers Jun 13 '16 at 20:39