If you are familiar with Java, you probably know that starting with JDK 9, you may need to add some “–add-exports” or “–add-opens” parameters to the JAVA_TOOL_OPTIONS. This is the Strong Encapsulation, which started with JDK 9 and was only displaying warnings until JDK 16. With Java 17, however, it is now fully in effect so you may start seeing some issues if you don’t have the correct configuration.
If I’m not mistaken, Documentum 23.2 introduced support for JDK 17 for the runtime. Then Documentum 23.4 added full support for JDK 17 and it seems that binaries are now being compiled with this version as well. Therefore, I thought it would be interesting to write a blog about the consequences of not defining JAVA_TOOL_OPTIONS when trying to install and run Documentum.
I. Binaries
Installing the Documentum binaries without first defining the JAVA_TOOL_OPTIONS doesn’t generate any errors or warnings. Even if you install with DEBUG logs enabled, nothing strange pops up in the logs:
[dmadmin@cs-0 ~]$ cd $INSTALL_DIR/CS23.4/logs
[dmadmin@cs-0 logs]$
[dmadmin@cs-0 logs]$ ls
Documentum_Server_Install_02_20_2024_10_53_30.log install.log
[dmadmin@cs-0 logs]$
[dmadmin@cs-0 logs]$ grep -iE "error|warn" install.log
[dmadmin@cs-0 logs]$
[dmadmin@cs-0 logs]$ grep -A8 ^Summary Documentum_Server_Install_*.log
Summary
-------
Installation: Successful.
42 Successes
0 Warnings
0 NonFatalErrors
0 FatalErrors
[dmadmin@cs-0 logs]$
[dmadmin@cs-0 logs]$ grep -C2 "DFC" Documentum_Server_Install_*.log
Status: SUCCESSFUL
Install Merge Module: $INSTALL_DIR/CS23.4/Documentum_DFC_Environment.iam.zip
Status: SUCCESSFUL
Additional Notes: NOTE - Installing: Documentum_DFC_Environment.iam.zip
Custom Action: com.documentum.install.shared.installanywhere.plugins.DiWAExtractArchive
---
echo "Initiating Merge Module installation..."
cd "/tmp/417199.tmp"
"$JAVA_HOME/bin/java" -cp '$INSTALL_DIR/CS23.4/Documentum_DFC_Environment.iam.zip':'/tmp/install.dir.3033/InstallerData':'/tmp/install.dir.3033/InstallerData/installer.zip' -noverify -Xms262114000 -Xmx262114000 com.zerog.lax.LAX "/tmp/417199.tmp/mergeModuleLax1.lax" lax_no_temp_file
echo "...Install Merge Module script complete."
##### SCRIPT END ############
[dmadmin@cs-0 logs]$
However, there are only 2 log files. There should be 4, because the Documentum Server binaries installer triggers the DFC installation through another Java process (as shown above) and that will (should) generate 2 more log files. But if this is your first time installing Documentum or this particular version, you might think that OpenText changed their process a bit and now there are only 2 logs, it doesn’t really matter as long as there are no errors…
So, you might think that there is no impact, right? Well, try again! From what I could see, the content of $DM_HOME appears to be the expected one. It contains the Documentum binaries, the “java.ini” files, etc… Same thing for $DOCUMENTUM/dba, it looks good. However, if you look directly under $DOCUMENTUM, there is one thing that you might find strange, and that is the fact that there is no DFC, even though the installation is done. This is because the JAVA_TOOL_OPTIONS was not defined before running the installer and unfortunately, the java subprocess silently failed…
If you look at the “java.ini” file, it contains DFC references, but the files/folders are not there:
[dmadmin@cs-0 logs]$ cd $DOCUMENTUM
[dmadmin@cs-0 server]$
[dmadmin@cs-0 server]$ grep '^java' $DM_HOME/bin/java.ini
java_library_path = $DOCUMENTUM/java64/JAVA_LINK/lib/server/libjvm.so
java_version = 1.7
java_classpath = $DOCUMENTUM/product/23.4/dctm-server.jar:$DOCUMENTUM/dctm.jar:$DOCUMENTUM/config:$DOCUMENTUM/java64/JAVA_LINK/lib
java_alias_file = $DOCUMENTUM/dfc/dfc.aliases
java_options = "-Xms32M -Xmx64M -XX:+UseSerialGC -Djava.net.preferIPv4Stack=true -Djava.security.egd=file:///dev/./urandom"
[dmadmin@cs-0 server]$
[dmadmin@cs-0 server]$ ls -l $DOCUMENTUM/java64/JAVA_LINK/lib/server/libjvm.so
-rw-r--r-- 1 dmadmin dmadmin 24022392 Jul 18 2023 $DOCUMENTUM/java64/JAVA_LINK/lib/server/libjvm.so
[dmadmin@cs-0 server]$
[dmadmin@cs-0 server]$ ls -l $DOCUMENTUM/product/23.4/dctm-server.jar
-rwxr-xr-x 1 dmadmin dmadmin 291 Feb 20 10:53 $DOCUMENTUM/product/23.4/dctm-server.jar
[dmadmin@cs-0 server]$
[dmadmin@cs-0 server]$ ls -l $DOCUMENTUM/dctm.jar
ls: cannot access '$DOCUMENTUM/dctm.jar': No such file or directory
[dmadmin@cs-0 server]$
[dmadmin@cs-0 server]$ ls -l $DOCUMENTUM/config
ls: cannot access '$DOCUMENTUM/config': No such file or directory
[dmadmin@cs-0 server]$
If you have a look at the “~/.com.zerog.registry.xml” file created by the installer, you will see the Documentum Server product but no DFC. Same thing for the “DctmRegistry.xml” file created by the installer, it contains the Documentum and Java versions but not for the DFC. Please do your best to ignore the WildFly section, Documentum replaced WildFly with Tomcat since its version 21.2, but the file isn’t yet fixed:
[dmadmin@cs-0 server]$ cat ~/.com.zerog.registry.xml
<?xml version="1.0" encoding="UTF-8"?>
<registry install_date="2024-02-20 10:53:35" version="1.1" last_modified="2024-02-20 10:53:47">
<products>
<product name="Documentum Server" id="0bc3e8a8-1f03-11b2-b1a7-9350af98073e" upgrade_id="0bc3e8a8-1f03-11b2-b1a7-9350af98073e" version="23.4.0.143" copyright="2011" info_url="" support_url="" location="$DOCUMENTUM" last_modified="2024-02-20 10:53:43">
<![CDATA[]]>
<vendor name="Documentum, a division of OpenText" id="0bc3e8a7-1f03-11b2-b1a7-9350af98073e" home_page="http://www.documentum.com" email=""/>
<feature short_name="ContentServer" name="Documentum Server" last_modified="2024-02-20 10:53:43">
<![CDATA[This installs the application feature.]]>
<component ref_id="0bc3e943-1f03-11b2-b1dd-9350af98073e" version="1.0.0.0" location=""/>
<component ref_id="83d6f5b2-1f03-11b2-880c-f48d0aec226e" version="1.0.0.0" location=""/>
<component ref_id="0bc3e944-1f03-11b2-b1da-9350af98073e" version="1.0.0.0" location="$DOCUMENTUM/uninstall/server/Uninstall"/>
</feature>
<feature short_name="Task Ch" name="Task Chaining Framework" last_modified="2024-02-20 10:53:43">
<![CDATA[<Enter Product Feature description here -- do not forget to assign this Feature to desired Install Sets>]]>
<component ref_id="83d0837d-1f03-11b2-84f5-f48d0aec226e" version="1.0.0.0" location=""/>
<component ref_id="83d6f5b2-1f03-11b2-880c-f48d0aec226e" version="1.0.0.0" location=""/>
<component ref_id="0bc3e944-1f03-11b2-b1da-9350af98073e" version="1.0.0.0" location="$DOCUMENTUM/uninstall/server/Uninstall"/>
</feature>
</product>
</products>
<components>
<component id="83d0837d-1f03-11b2-84f5-f48d0aec226e" version="1.0.0.0" name="AG- Task Ch" location="" vendor="Documentum, a division of OpenText"/>
<component id="83d6f5b2-1f03-11b2-880c-f48d0aec226e" version="1.0.0.0" name="AG- ContentServer, Task Ch" location="" vendor="Documentum, a division of OpenText"/>
<component id="0bc3e943-1f03-11b2-b1dd-9350af98073e" version="1.0.0.0" name="InstallAnywhere VM Component" location="" vendor="Documentum, a division of OpenText"/>
<component id="0bc3e944-1f03-11b2-b1da-9350af98073e" version="1.0.0.0" name="InstallAnywhere Uninstall Component" location="$DOCUMENTUM/uninstall/server/Uninstall" vendor="Documentum, a division of OpenText"/>
</components>
</registry>
[dmadmin@cs-0 server]$
[dmadmin@cs-0 server]$ cat DctmRegistry.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<registry>
<product id="CS" name="Documentum Server">
<release base-version="23.4.0000.0143" install-date="Tue Feb 20 10:53:48 UTC 2024">
<components>
<component>
<name>dfc</name>
<version/>
</component>
<component>
<name>jdk</name>
<version>17.0.8</version>
</component>
<component>
<name>wildfly</name>
<version>11.0.0</version>
</component>
</components>
</release>
</product>
</registry>
[dmadmin@cs-0 server]$
Without JAVA_TOOL_OPTIONS, the DFC doesn’t get installed with the Documentum binaries but the rest looks good. If you want, you can manually install the DFC (as you would do on a standalone client, even without the options) and it would work. So, I’m not sure why it’s not handled properly by OpenText, but I guess that’s another small bug / improvement to be done.
II. Connection Broker
Let’s assume you didn’t see that there was no DFC present, and you proceeded with installing a Connection Broker without the JAVA_TOOL_OPTIONS defined. In this case, the installation of the Connection Broker looks fine and there are no errors in the generated logs. Once it has been installed, you can see the running process and the start/stop scripts have been created, so it looks good. You could then proceed with a Repository installation, and it seems that not defining the JAVA_TOOL_OPTIONS (or not having a DFC present) isn’t a problem to install a Connection Broker.
However, if you try to connect to it with the dmqdocbroker utility, or through the iAPI command, you will detect the missing DFC as it will fail and will generate a “dmcl_err_PID#pid#_#timestamp#.txt” log file:
[dmadmin@cs-0 server]$ source $DM_HOME/bin/dm_set_server_env.sh
[dmadmin@cs-0 server]$
[dmadmin@cs-0 server]$ ls dmcl_err_*
ls: cannot access 'dmcl_err_*': No such file or directory
[dmadmin@cs-0 server]$
[dmadmin@cs-0 server]$ iapi
IAPI failed to run because of a failed status returned from dmAPIInit()
[dmadmin@cs-0 server]$
[dmadmin@cs-0 server]$
[dmadmin@cs-0 server]$ ls dmcl_err_*
dmcl_err_PID3836_02-20-24_11.01.22.txt
[dmadmin@cs-0 server]$
[dmadmin@cs-0 server]$ cat dmcl_err_PID*.txt
Can't find class 'com/documentum/dmcl/impl/DmclApiNativeAdapter'
Java VM created with library $DOCUMENTUM/java64/JAVA_LINK/lib/server/libjvm.so
java.class.path for Java VM is $DOCUMENTUM/product/23.4/dctm-server.jar:$DOCUMENTUM/dctm.jar:$DOCUMENTUM/config:$DOCUMENTUM/java64/JAVA_LINK/lib
java.lang.NoClassDefFoundError: com/documentum/dmcl/impl/DmclApiNativeAdapter
Java VM created with library $DOCUMENTUM/java64/JAVA_LINK/lib/server/libjvm.so
java.class.path for Java VM is $DOCUMENTUM/product/23.4/dctm-server.jar:$DOCUMENTUM/dctm.jar:$DOCUMENTUM/config:$DOCUMENTUM/java64/JAVA_LINK/lib
[dmadmin@cs-0 server]$
If you read between the lines, it should be pretty straightforward as you can see missing classes related to DMCL (Documentum Client Library) that the DFC relies on.
In conclusion, there is no problem installing a Connection Broker without defining the JAVA_TOOL_OPTIONS, but connecting to it will obviously require a DFC. Whether you install the DFC manually (standalone) or via the Documentum Server binaries (bundled) doesn’t make any difference, it will work either way.
III. Repository
Let’s assume you still didn’t see the missing DFC and you just proceeded so far based on the error-free logs, still without any JAVA_TOOL_OPTIONS definitions. Under such circumstances, the Repository installation will quickly fail, because it starts the Repository processes at the beginning. However, the Repository wouldn’t be able to register itself with the Connection Broker since there is no DFC. That’s most probably where you would try to connect to the Repository or the Connection Broker yourself, and see the errors I mentioned just above.
If you manually installed the DFC, it would go a little further as the Repository would be able to register to the Connection Broker. In such cases, it would still fail, but a bit later, during the CAS section of the installation:
[dmadmin@cs-0 server]$ cat $DM_HOME/install/logs/install.log
...
11:08:25,549 INFO [main] com.documentum.install.server.installanywhere.actions.DiWAServerVerifyDataIni - The installer will verify data_dictionary.ini for the repository.
11:08:25,561 INFO [main] com.documentum.install.server.installanywhere.actions.DiWAServerProcessingScripts - The installer will execute the : Repository HeadStart script.
11:08:44,233 INFO [main] com.documentum.install.server.installanywhere.actions.DiWAServerProcessingScripts - The installer will execute the : Updating format objects script.
11:08:58,234 INFO [main] com.documentum.install.server.installanywhere.actions.DiWAServerProcessingScripts - The installer will execute the : Creating Electronic Signature Objects script.
11:09:06,970 ERROR [main] com.documentum.install.server.installanywhere.actions.DiWAServerProcessingScripts - The installer failed to execute : Creating Electronic Signature Objects. Please check output file $DOCUMENTUM/dba/config/gr_dbi/dm_cas_install.out for more information.
com.documentum.install.shared.common.error.DiException: The installer failed to execute : Creating Electronic Signature Objects. Please check output file $DOCUMENTUM/dba/config/gr_dbi/dm_cas_install.out for more information.
...
[dmadmin@cs-0 server]$
Let’s follow the trail and look at the CAS logs then:
[dmadmin@cs-0 server]$ cat $DOCUMENTUM/dba/config/gr_dbi/dm_cas_install.out
Start running dm_CAS_install.ebs script on docbase gr_dbi.gr_dbi
Create method esign_pdf
Create type dm_esign_template
Create Integration cabinet...
Create /Integration/Esignature folder...
Create /Integration/Esignature/Templates folder folder...
Import Default Signature Page Template
Setting a_storage_type for dm_esign_template object to filestore_01
java.lang.RuntimeException: Failed to get calling context
java.lang.RuntimeException: Static initialization for determining class call context failed. See DFC log for more details
Failed to import Default Signature Page Template
[dmadmin@cs-0 server]$
Is that better? Not really… Let’s continue and take a look at the DFC logs:
[dmadmin@cs-0 server]$ cat $DOCUMENTUM/logs/log4j.log
2024-02-20 11:09:06,924 UTC ERROR [com.documentum.fc.client.security.impl.util.ClassContextFetcher] (main) Static initialization for determining class call context failed
java.lang.reflect.InaccessibleObjectException: Unable to make protected native java.lang.Class[] java.lang.SecurityManager.getClassContext() accessible: module java.base does not "opens java.lang" to unnamed module @64b8f8f4
at java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) ~[?:?]
at java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) ~[?:?]
at java.lang.reflect.Method.checkCanSetAccessible(Method.java:199) ~[?:?]
at java.lang.reflect.Method.setAccessible(Method.java:193) ~[?:?]
at com.documentum.fc.client.security.impl.util.ClassContextFetcher.<clinit>(ClassContextFetcher.java:63) ~[dfc.jar:?]
at com.documentum.fc.client.DfTypedObject.getCallStackStartingAtTopOfStack(DfTypedObject.java:1075) ~[dfc.jar:?]
at com.documentum.fc.client.DfTypedObject.isCalledByTrustedCaller(DfTypedObject.java:1042) ~[dfc.jar:?]
at com.documentum.fc.client.DfTypedObject.verifyInternalAttributeAccessRights(DfTypedObject.java:1016) ~[dfc.jar:?]
...
[dmadmin@cs-0 server]$
Finally, some useful details! The CAS installation section of the Repository failed because of some inaccessible objects / protected classes. It even tells you that it’s about the “java.base” module that does not “opens java.lang“… If you have been using Java in the last 7 years, you should know what this means and what to do.
If, instead of running the Repository installer, you tried to ping the Connection Broker (after installing the DFC), you would have seen something very similar from the command line. It would be related to the same java.base module but this time, it does not “export sun.security.x509“:
[dmadmin@cs-0 server]$ dmqdocbroker -t `hostname -f` -p 1489 -c ping
2024-02-20 11:10:29,630 UTC ERROR [com.documentum.fc.client.security.impl.IdentityManager] (main) [DFC_SECURITY_IDENTITY_INIT] no identity initialization or incomplete identity initialization
java.lang.IllegalStateException: Error creating sun.security.x509.X509CertInfo object
at com.documentum.fc.client.security.internal.ReflectionUtil.createExact(ReflectionUtil.java:52) ~[dfc.jar:?]
at com.documentum.fc.client.security.internal.CreateIdentityCredential.createSelfSignedIdentity(CreateIdentityCredential.java:247) ~[dfc.jar:?]
at com.documentum.fc.client.security.internal.CreateIdentityCredential.<init>(CreateIdentityCredential.java:94) ~[dfc.jar:?]
at com.documentum.fc.client.security.impl.InitializeKeystoreForDfc.execute(InitializeKeystoreForDfc.java:52) ~[dfc.jar:?]
...
Caused by: java.lang.IllegalAccessException: class com.documentum.fc.client.security.internal.ReflectionUtil cannot access class sun.security.x509.X509CertInfo (in module java.base) because module java.base does not export sun.security.x509 to unnamed module @64b8f8f4
at jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392) ~[?:?]
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674) ~[?:?]
at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:489) ~[?:?]
at java.lang.reflect.Constructor.newInstance(Constructor.java:480) ~[?:?]
at com.documentum.fc.client.security.internal.ReflectionUtil.createExact(ReflectionUtil.java:46) ~[dfc.jar:?]
... 14 more
dmqdocbroker: A DocBroker Query Tool
dmqdocbroker: Documentum Client Library Version: 23.4.0000.0180
Using specified port: 1489
Successful reply from docbroker at host (cs-0) on port(1490) running software version (23.4.0000.0143 Linux64).
[dmadmin@cs-0 server]$
It responds correctly (last line), somehow, but you still get a nice exception. On the other hand, if you define the JAVA_TOOL_OPTIONS, then there is no exception anymore:
[dmadmin@cs-0 server]$ export JAVA_TOOL_OPTIONS="-Djdk.util.zip.disableZip64ExtraFieldValidation=true -Djava.locale.providers=COMPAT,SPI --add-exports=java.base/sun.security.provider=ALL-UNNAMED --add-exports=java.base/sun.security.pkcs=ALL-UNNAMED --add-exports=java.base/sun.security.x509=ALL-UNNAMED --add-exports=java.base/sun.security.util=ALL-UNNAMED --add-exports=java.base/sun.security.tools.keytool=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED"
[dmadmin@cs-0 server]$
[dmadmin@cs-0 server]$ dmqdocbroker -t `hostname -f` -p 1489 -c ping
Picked up JAVA_TOOL_OPTIONS: -Djdk.util.zip.disableZip64ExtraFieldValidation=true -Djava.locale.providers=COMPAT,SPI --add-exports=java.base/sun.security.provider=ALL-UNNAMED --add-exports=java.base/sun.security.pkcs=ALL-UNNAMED --add-exports=java.base/sun.security.x509=ALL-UNNAMED --add-exports=java.base/sun.security.util=ALL-UNNAMED --add-exports=java.base/sun.security.tools.keytool=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED
dmqdocbroker: A DocBroker Query Tool
dmqdocbroker: Documentum Client Library Version: 23.4.0000.0180
Using specified port: 1489
Successful reply from docbroker at host (cs-0) on port(1490) running software version (23.4.0000.0143 Linux64).
[dmadmin@cs-0 server]$
In summary, defining the JAVA_TOOL_OPTIONS is required for both the Documentum Server binaries (or more specifically the subprocess starting the DFC part) and the Repository installation. It also helps at runtime with utilities such as dmqdocbroker/iapi/idql. The documentation tells you what you need to do, but what I find interesting is that OpenText already includes these options in several places, such as the Repository installer (Server_Configuration_Program.bin), the Remote Repository installer (cfsConfigurationProgram.bin), the ComposerHeadless DAR deployer (dardeployer.ini), the ComposerHeadless java.ini file, and the Tomcat startup script… So basically, OpenText has already done some work, but it’s clearly not enough to have a fully functional setup. So why…? I guess we might see some changes related to this in the future, so let’s see!