Hello,
Sometimes, the execution of a job/method Documentum via Java Method Server (JMS) can generate a Core dump error for various reasons : content file protected, document corrupted, …etc…especially when using IRM protection which produces the stopping of DCTM job.
Here, an example of error:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000111b9d09, pid=3684, tid=7584 # # JRE version: 7.0_17-b02 # Java VM: Java HotSpot(TM) 64-Bit Server VM (23.7-b01 mixed mode windows-amd64 compressed oops) # Problematic frame: # C [libemcdctmirm.dll+0x1f9d09] PVS_TemplateListFree+0x7069 # # Core dump written. Default location: D:\App\Workspaces\....\hs_err_pid3684.mdmp
So, I will try to expose a simple solution in order to avoid the stopping of JMS by by-passing the use of JMS:
DCTM JOB => DCTM METHOD => Script BATCH CMD => Script POWERSHELL => JAVA DFC/JVM
- Creation of a DCTM job My_Method_PowershellScript :
In Documentum Administrator, in the section Administration/Job Management/Methods, create a method My_Method_PowershellScript:***** in tab "Method Info" * Name = My_Method_PowershellScript * Verb = D:\App\MyFolder4DCTM\My_ScriptProcess.cmd * Method Type = program * Timeout Minimum = 30 * Timeout Default = 172800 * Timeout Maximum = 345600 * Launch Direct = [X] Use the exec call to execute the procedure * Launch Asynchronously = [X] Launch as a separate process * Run As Owner = [X] Run as the installation owner
- Creation of a DCTM method My_Job_BatchScript :
In Documentum Administrator, in the section Administration/Job Management/Jobs, create a method My_Job_BatchScript:***** in tab "Info" * Name = My_Job_BatchScript * Trace Level = 0 (no trace) * Designated Server = Any Running Server * State = "Inactive" ***** in tab "Method" * Method Name = My_Method_PowershellScript ***** in tab "SysObject Info" * Title = My_Job_BatchScript
- Creation of folder containing the scripts and librairies D:\App\MyFolder4DCTM on DCTM server
- Creation of BATCH CMD script My_ScriptProcess.cmd in the folder D:\App\MyFolder4DCTM calling the POWERSHELL script:
@echo off SET "DOCUMENTIDS=" :parse IF "%~1"=="" GOTO endparse if "%DOCUMENTIDS%"=="" ( SET DOCUMENTIDS=-DocumentIds %~1 ) ELSE ( SET DOCUMENTIDS=%DOCUMENTIDS%,%~1 ) SHIFT GOTO parse :endparse CD "D:\App\MyFolder4DCTM" D: SET CurrentDirectory=%CD% SET JavaHome=D:\Documentum\java64\1.7.0_17 SET DctmDirectory=D:\Documentum SET DctmConfigDirectory=%DctmDirectory%\config SET DctmIrmDirectory=%DctmDirectory%\irm powershell .\My_ScriptProcess.ps1 "%DOCUMENTIDS%" -DctmEnv ALL -CurrentDirectory "%CurrentDirectory%" -JavaHome "%JavaHome%" -DctmConfigDirectory "%DctmConfigDirectory%" -DctmIrmDirectory "%DctmIrmDirectory%"
- Creation of POWERSHELL script My_ScriptProcess.ps1 in the folder D:\App\MyFolder4DCTM calling the JAVA com.java.lu.business.service.ecm.utils.main.CreateListToProcess:
param( [Int32[]] $DocumentIds, [String] $CurrentDirectory, [String] $JavaHome, [String] $DctmConfigDirectory, [String] $DctmIrmDirectory, [String] $DctmEnv ) function CreateIdList { param( [String] $DocumentIds, [String] $CurrentDirectory, [String] $JavaHome, [String] $DctmConfigDirectory, [String] $DctmIrmDirectory, [String] $DctmEnv, [String] $IdsToProcessFile ) Write-Host "Calling CreateIdList with parameters:" Write-Host " * DocumentIds: $DocumentIds" Write-Host " * CurrentDirectory: $CurrentDirectory" Write-Host " * JavaHome: $JavaHome" Write-Host " * DctmConfigDirectory: $DctmConfigDirectory" Write-Host " * DctmIrmDirectory: $DctmIrmDirectory" Write-Host " * DctmEnv: $DctmEnv" Write-Host " * IdsToProcessFile: $IdsToProcessFile" $ClassPath = $DctmConfigDirectory; foreach($Jar IN Get-ChildItem "$CurrentDirectory\dfc" -filter "*.jar" -Name){ $ClassPath += ";$CurrentDirectory\dfc\$Jar" } foreach($Jar IN Get-ChildItem "$CurrentDirectory\lib" -filter "*.jar" -Name){ $ClassPath += ";$CurrentDirectory\lib\$Jar" } $ClassPath += ";$DctmIrmDirectory\emcdctmirm.jar" $ClassPath += ";$CurrentDirectory\IRMisationDocs4ArchivedDeliverable.jar" $JavaLibraryPath = "$DctmIrmDirectory" $JavaLibraryPath += ";$DctmIrmDirectory\Common" $JavaLibraryPath += ";$env:path" $JavaLibraryPath = $JavaLibraryPath -replace "\\", "/" $pInfo = New-Object System.Diagnostics.ProcessStartInfo $pInfo.FileName = "$JavaHome\bin\java.exe" $LogFile = "$CurrentDirectory\log\My_ScriptProcess_log_$((Get-Date).ToString("yyyyMMdd_HHmmss")).log" $pInfo.Arguments = @( #"-Xrunjdwp:transport=dt_socket,address=9797,server=y,suspend=y", #"-XX:-DumpOnCrash", #"-XX:-CoreOnCrash", "-Xmx1g", "-Doracle.net.tns_admin=""$env:TNS_ADMIN""", "-Djava.library.path=""$JavaLibraryPath""", "-cp", """$ClassPath""", "com.java.lu.business.service.ecm.utils.main.CreateListToProcess", $DctmEnv, """$LogFile""", """$IdsToProcessFile""", $DocumentIds) $p = New-Object System.Diagnostics.Process $p.StartInfo = $pInfo $p.Start() | Out-Null $p.WaitForExit() Write-Host "Content of $($IdsToProcessFile):" Get-Content -Path $IdsToProcessFile | Foreach-Object { Write-Host $_ } Write-Host "End of Content" } function LaunchSensitiveProcess { param( [String] $ObjectIds, [String] $CurrentDirectory, [String] $JavaHome, [String] $DctmConfigDirectory, [String] $DctmIrmDirectory, [String] $DctmEnv ) # .... # .... # .... # .... # .... } function MyProcess{ param( [Int32[]] $DocumentIds, [String] $CurrentDirectory, [String] $JavaHome, [String] $DctmConfigDirectory, [String] $DctmIrmDirectory, [String] $DctmEnv ) $DocumentIdsToProcess=$DocumentIds -join ',' $IdsToProcessFile = "$CurrentDirectory\My_ScriptProcess_$((Get-Date).ToString("yyyyMMdd_HHmmss")).txt" CreateIdList -DocumentIds $DocumentIdsToProcess -CurrentDirectory $CurrentDirectory -JavaHome $JavaHome -DctmConfigDirectory $DctmConfigDirectory -DctmIrmDirectory $DctmIrmDirectory -DctmEnv $DctmEnv -IdsToProcessFile $IdsToProcessFile foreach ($IdsToProcess in Get-Content -Path $IdsToProcessFile) { LaunchSensitiveProcess -ObjectIds $IdsToProcess -CurrentDirectory $CurrentDirectory -JavaHome $JavaHome -DctmConfigDirectory $DctmConfigDirectory -DctmIrmDirectory $DctmIrmDirectory -DctmEnv $DctmEnv } #Remove-Item -Path $IdsToProcessFile } $MaxNbOfDocumentIds = 150 if ($DocumentIds.Count -gt $MaxNbOfDocumentIds){ while($DocumentIds.Count -gt 0){ $NewDocumentIds = New-Object System.Collections.ArrayList while(($NewDocumentIds.Count -le $MaxNbOfDocumentIds) -and ($DocumentIds.Count -gt 0)){ $DocumentId = $DocumentIds[0] if ($DocumentIds.Count -gt 1){ $DocumentIds = $DocumentIds[1..($DocumentIds.Count -1)] }else{ $DocumentIds = @() } $NewDocumentIds.Add($DocumentId) > $null } MyProcess -DocumentIds $NewDocumentIds -CurrentDirectory $CurrentDirectory -JavaHome $JavaHome -DctmConfigDirectory $DctmConfigDirectory -DctmIrmDirectory $DctmIrmDirectory -DctmEnv $DctmEnv } }else{ MyProcess -DocumentIds $DocumentIds -CurrentDirectory $CurrentDirectory -JavaHome $JavaHome -DctmConfigDirectory $DctmConfigDirectory -DctmIrmDirectory $DctmIrmDirectory -DctmEnv $DctmEnv }
- Creation of java class com.java.lu.business.service.ecm.utils.main.CreateListToProcess:
package com.java.lu.business.service.ecm.utils.main; import java.io.File; import java.io.PrintWriter; import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Properties; import java.util.Set; import javax.naming.spi.NamingManager; import javax.sql.DataSource; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy; import org.apache.commons.lang.StringUtils; import com.documentum.com.DfClientX; import com.documentum.com.IDfClientX; import com.documentum.fc.client.DfQuery; import com.documentum.fc.client.IDfClient; import com.documentum.fc.client.IDfCollection; import com.documentum.fc.client.IDfQuery; import com.documentum.fc.client.IDfSession; import com.documentum.fc.client.IDfSessionManager; import com.documentum.fc.client.IDfUser; import com.documentum.fc.common.DfException; import com.documentum.fc.common.DfLoginInfo; import com.documentum.fc.common.IDfId; public class CreateListToProcess { public static void main(String[] args) { try { String myRepository = "MY_DOCBASE"; String adminLogin = "adminuser"; String adminPassword = "pwd4adminuser"; IDfClientX clientx = new DfClientX(); IDfClient client = clientx.getLocalClient(); final IDfSessionManager sMgr = client.newSessionManager(); sMgr.setIdentity(IDfSessionManager.ALL_DOCBASES, new DfLoginInfo(adminLogin, adminPassword)); IDfSession dfSession = sMgr.getSession(myRepository); try { if (dfSession.getUser(null).getUserPrivileges() != IDfUser.DF_PRIVILEGE_SUPERUSER) { throw new DfException(MessageFormat.format("{0} is not a superuser.", dfSession.getUser(null).getUserName())); } PrintWriter printWriterLog = new PrintWriter(new File(args[1])) { @Override public void println(String x) { super.println(x); super.flush(); System.out.println(x); } }; HashSet<String> docsIdsSet = new HashSet<String>(); File fileToCreate = null; for (int i = 2; i < args.length; i++) { if (i == 2) { fileToCreate = new File(args[i]); } else { docsIdsSet.add(args[i]); } } int cpt = 0; PrintWriter printWriterIdsFile = new PrintWriter(fileToCreate); try { final int lineSize = 100; IDfCollection dfCollection = getDocumentIdsToProcess(dfSession); try { List<String> list = new ArrayList<String>(); while (dfCollection.next()) { cpt++; IDfId dfId = dfCollection.getId("r_object_id"); list.add(dfId.getId()); if (list.size() == lineSize) { printWriterIdsFile.println(StringUtils.join(list, ',')); printWriterIdsFile.flush(); list.clear(); } } if (list.size() > 0) { printWriterIdsFile.println(StringUtils.join(list, ',')); printWriterIdsFile.flush(); list.clear(); } } finally { dfCollection.close(); } } finally { printWriterLog.write(MessageFormat.format("There {0,choice,0#are no documents|1#is one document|1<are {0,number,integer} documents} to process.", cpt)); printWriterLog.close(); } } finally { sMgr.release(dfSession); } } catch (Throwable e) { e.printStackTrace(); } } /** * Get the documents for the scope's current execution * @param session * @return * @throws Throwable */ public static IDfCollection getDocumentIdsToProcess(IDfSession session) throws Throwable { IDfCollection collection = null; StringBuilder sb = new StringBuilder(); sb.append(" SELECT DISTINCT docsall.r_object_id FROM my_document (ALL) docsall WHERE docsall.i_chronicle_id "); sb.append(" IN ( SELECT docs.i_chronicle_id from my_document docs "); sb.append(" WHERE ANY docs.r_aspect_name = 'my_aspect' and docs.my_aspect.is_ok=1 "); sb.append(" AND docs.r_content_size>0 "); //.... sb.append(" ) "); System.out.println(MessageFormat.format("Building and execution of query: {0}", sb.toString())); IDfQuery dfQuery = new DfQuery(sb.toString()); collection = dfQuery.execute(session, IDfQuery.DF_READ_QUERY); return collection; } }
- So, on the DCTM server, in the folder D:\App\MyFolder4DCTM, there will be:
o My_ScriptProcess.cmd
o My_ScriptProcess.ps1
o MyJavaLuLib.jar : containing all needed classes
o \lib : commons-collections-3.2.jar + commons-configuration-1.5.jar + commons-io-1.2.jar + commons-logging-1.1.1.jar + ojdbc6.jar + commons-csv-1.1.jar …etc.
o \dfc : all JARs and DLLs of DFC (dfc.jar,Dfc.dll, …etc).
o \log : log files
Just a last point, in the POWERSHELL script the below command allows debugging of remote server execution from local IDE (Composer) via the port 9797:
“-Xrunjdwp:transport=dt_socket,address=9797,server=y,suspend=y”
however, if this instruction is uncommented, the execution is put on hold until the launch of the IDE on the port.
Best regards,
Huseyin OZVEREN