2

So this is the very simplified Lotus Domino Java agent code I am trying to run...

import lotus.domino.*;

enum SingletonTest { 
    INSTANCE;

    public void helloWorld() {
        System.out.println("Hello World");
    }
}

public class JavaAgent extends AgentBase {

    public void NotesMain() {

        try {
            System.out.println("Started");
            SingletonTest.INSTANCE.helloWorld();
            System.out.println("Done");

        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

But when I try to run it this is what appears on the Java Console...

Started
Exception in thread "AgentThread: JavaAgent" java.lang.VerifyError: JVMCFRE028 ldc* bytecode must reference a constant; class=, method=valueOf(Ljava/lang/String;)LSingletonTest;, pc=0
    at java.lang.ClassLoader.defineClassImpl(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:275)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:212)
    at lotus.domino.AgentLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:626)
    at JavaAgent.NotesMain(JavaAgent.java:17)
    at lotus.domino.AgentBase.runNotes(Unknown Source)
    at lotus.domino.NotesThread.run(Unknown Source)

I am using Java 1.6 for my agent. I am using v8.5.3 FP3 and in my notes.ini I have..

JavaCompilerTarget=CurrentJavaVersion

So what am I doing wrong?

Is there a problem with the IBM Java version class loader using an enum that contains code?

This is the singleton coding pattern I have tried to follow...

https://stackoverflow.com/a/71399/2530065

edit: I probably should add I am running this as a Notes client agent with "Trigger:On event:Action Menu selection" and "Target:None".

edit2: So I have tested this exact code in a standalone Java program using the same IBM JRE/JVM and the code works perfectly without any issues. I just can't seem to get it to work as a Java agent within the Notes client.

Community
  • 1
  • 1
  • Did you check the Java requirements for that version of Domino? – Jim Garrison Jul 01 '13 at 23:56
  • @Jim Garrison. Thanks for your response. I am showing my ignorance here. But when you say "Java requirements for that version of Domino" what exactly do you mean? I am just using the Java that comes with the Notes client that I am running the agent in. – James Fricker Jul 02 '13 at 00:12
  • @Blaine. Have a read of [instantiating-and-using-an-enum-singleton](http://stackoverflow.com/questions/8758558/instantiating-and-using-an-enum-singleton). I think I am following the enum singleton coding pattern correctly. – James Fricker Jul 02 '13 at 00:15
  • Given that Notes uses IBM's own JVM implementation, it seems to me that this is a question that would best be addressed by IBM's support. Have you tested this exact same code in a standalone Java program? – Richard Schwartz Jul 02 '13 at 01:46

2 Answers2

1
  1. Open the Designer preferences and select the Compiler settings.

    Preferences

  2. Click on "Configure Project Specific Settings..."

  3. Select your project and click OK.

    select project

  4. Change the settings to 1.6 and default compliance settings.

    compliance settings

  5. Click OK. You should get a few prompts, select the default. Then open and save your agent again to recompile it.

Using your code I did this and ran it without error.

Simon O'Doherty
  • 9,259
  • 3
  • 26
  • 54
1

In the end I found changing the NOTES.INI setting JavaCompilerTarget from...

JavaCompilerTarget=CurrentJavaVersion

...to...

JavaCompilerTarget=1.6

and recreating the agent from scratch fixed the problem.

For Java agents it looks like there are two fields on the agent doc which control source and target Java versions.

These are $JavaCompilerSource and $JavaCompilerTarget.

They are set when a Java agent is created. The value of these fields depends on the value of the NOTES.INI JavaCompilerTarget entry when the agent was created. Changing the NOTES.INI entry after the agent is created and editing or recompiling the agent has no effect.

If I create a Java agent when the NOTES.INI variable "JavaCompilerTarget" is set to "CurrentJavaVersion", the field "$JavaCompilerTarget" gets set to the value "CurrentJ" and the field "$JavaCompilerSource" gets set to the value "1.6".

If I create a Java agent when the NOTES.INI variable "JavaCompilerTarget" is set to "1.6" then the field "$JavaCompilerTarget" gets set to the value "1.6" and the field "$JavaCompilerSource" gets set to the value "1.6".

If this particular agent's "$JavaCompilerTarget" field has a value of "CurrentJ" then I get the exception.

Whereas if I recreate the same agent and its "$JavaCompilerTarget" field has a value of "1.6", I do not get the exception.

If I recreate this agent when the NOTES.INI variable is set to "1.5" then both the agent field values are set to "1.5" and the agent runs without any errors.

If I use ytria scanEZ to change the broken agent (the one that has the field $JavaCompilerTarget="CurrentJ") so that the value is "1.6" instead, and I then open and re-save the agent in designer, it no longer throws an exception. If I change the field value back to "CurrentJ" and re-save the agent it throws the exception again.

So it seems having a Java agent field $JavaCompilerTarget="CurrentJ" is not good and this happens when you have a NOTES.INI entry of JavaCompilerTarget=CurrentJavaVersion.

I have no idea why this changes the JVM behaviour but it does for me on 8.5.3 FP3.