Fixing the “Identity key store file not found” Error in Primavera P6 EPPM

Oracle Primavera P6 EPPM

Recently, I’ve installed multiple instances of Oracle Primavera P6 EPPM version 21 on Windows servers running Oracle WebLogic 12. In each case, after installing WebLogic and P6 EPPM, I get an error similar to the one below when trying to start the Node Manager:



 /security/DemoIdentity.jks, Type=jks, PassPhraseUsed=true>
  
weblogic.nodemanager.common.ConfigException: Identity key store file not found: /security/DemoIdentity.jks
at weblogic.nodemanager.server.SSLConfig.loadKeyStoreConfig(SSLConfig.java:225)
at weblogic.nodemanager.server.SSLConfig.access$000(SSLConfig.java:33)
at weblogic.nodemanager.server.SSLConfig$1.run(SSLConfig.java:118)
at java.security.AccessController.doPrivileged(Native Method)
at weblogic.nodemanager.server.SSLConfig.(SSLConfig.java:115)
at weblogic.nodemanager.server.NMServer.(NMServer.java:169)
at weblogic.nodemanager.server.NMServer.getInstance(NMServer.java:134)
at weblogic.nodemanager.server.NMServer.main(NMServer.java:589)
at weblogic.NodeManager.main(NodeManager.java:31)

From what I can tell, this must be caused by a bug in the particular version of WebLogic I’m running. Fortunately, there is a fix. This is not the only fix (or only possible cause) of this error, but it is the fix that has worked for me every time, so far.

On Windows machines, execute the following statements:


> cd %ORACLE_HOME%\wlserver\server\bin

> .\setWLSEnv.cmd

> cd %DOMAIN_HOME%\security

> java utils.CertGen -keyfilepass DemoIdentityPassPhrase -certfile democert -keyfile demokey -strength 2048 <strong>-noskid</strong>

> java utils.ImportPrivateKey -keystore DemoIdentity.jks -storepass DemoIdentityKeyStorePassPhrase -keyfile demokey.pem -keyfilepass DemoIdentityPassPhrase -certfile democert.pem -alias demoidentity

For Linux/UNIX, it is slightly different:


> cd $ORACLE_HOME/wlserver/server/bin

> . ./setWLSEnv.sh (that is DOT SPACE DOT SLASH setWLSEnv.sh )

> cd $DOMAIN_HOME/security

> java utils.CertGen -keyfilepass DemoIdentityPassPhrase -certfile democert -keyfile demokey -strength 2048 <strong>-noskid</strong>

> java utils.ImportPrivateKey -keystore DemoIdentity.jks -storepass DemoIdentityKeyStorePassPhrase -keyfile demokey.pem -keyfilepass DemoIdentityPassPhrase -certfile democert.pem -alias demoidentity

This information can be found at Oracle WebLogic DemoIdentity.jks fix. I had to wade through several irrelevant articles before stumbling across this one, so I’d like to give it more attention, as it’s the fix that worked multiple times for me.

Saying Goodbye to ActiveX

browser icons - Firefox, Edge, Chrome, and Safari

I’ve never had much reason to use ActiveX controls, though one major web application I support has a function where users are able to send log entries via Outlook email. This function was built using an ActiveX control many years ago, when Internet Explorer was the only browser we had to support. If a user wanted to run Chrome, they had to do without this function.

Now that Internet Explorer 11 is being sunsetted this year, and Microsoft Edge will only have IE 11 mode through 2025, it is high time to update any apps that rely on technologies like ActiveX that only work in IE or Edge’s IE 11 mode.

The original code that created the ActiveX control is below.

function(oContent,sSubject,sTitleHTML)
		{
			 try
			 {
				 var sContent = buildPrintHTML(oContent,sSubject,sTitleHTML,"email");
				 var outlookApp = new ActiveXObject("Outlook.Application");
				 var mailItem = outlookApp.CreateItem(0);
				 mailItem.Subject=sSubject;
				 mailItem.HTMLBody = sContent;
				 mailItem.Display (0);
			 }
			 catch(er)
			 {
				 alert(er.message);
			 }
			 finally
			 {
				mailItem = null;
				mailFolder = null;
				nameSpace = null;
				outlookApp = null;
			 }
		};

When a user clicked the link that called this function, the Outlook.Application ActiveX control would open a new HTML email in Outlook containing all the text, including URLs, from the shared log entry.

Initially, I thought about building an anchor tag that would store all the email data in the URL in the query string and use an HTTP GET request to send it to the server. I discovered quickly that this wouldn’t work, as there are limitations on how long a query string can be, and that limit is around 2000 characters if the URL is to be compatible with most browsers.

An article on Stack Overflow pointed me in the right direction: creating an anchor tag with all of the data in the href attribute, but not to be used in a GET request. The link would use the download attribute, which would cause the data stored in the href attribute to be downloaded as a file. Though any file format can be placed here, only one that would cause an Outlook email to be generated would work for this purpose. A MIME file type that can be used for this is EML.

The JavaScript code below would, after building the anchor tag and adding it programmatically to the form as a hidden link, automatically “click” the hidden link, which would download the contents of the href attribute as an EML file, which would open in Outlook just as the ActiveX control did.

function(oContent,sSubject,sTitleHTML,sEmailLogEntryID)
		{
			 try
			 {
				var sContent = buildPrintHTML(oContent,sSubject,sTitleHTML,"email");
				
				if(browserUtility.isIE()||browserUtility.isIE11()) {
					var outlookApp = new ActiveXObject("Outlook.Application");
					var mailItem = outlookApp.CreateItem(0);
					mailItem.Subject=sSubject;
					mailItem.HTMLBody = sContent;
					mailItem.Display (0);
				} else {					
					sContent = sContent.replaceAll('#','%23');
					sSubject = sSubject.replaceAll('#','%23');
								 
					var emlContent = "data:message/rfc822 eml;charset=utf-8,";
					emlContent += 'To: \n';
					emlContent += 'Subject: '+sSubject+'\n';
					emlContent += 'X-Unsent: 1'+'\n';
					emlContent += 'Content-Type: text/html'+'\n';
					emlContent += ''+'\n';
					emlContent += sContent;
					
					var d = new Date();
					var sDate = d.getUTCFullYear() + ("0"+(d.getUTCMonth()+1)).slice(-2) + ("0" + d.getUTCDate()).slice(-2)   + ("0" + d.getUTCHours()).slice(-2) + ("0" + d.getUTCMinutes()).slice(-2) + ("0" + d.getUTCSeconds()).slice(-2) + ("00" + d.getUTCMilliseconds()).slice(-3);
					
					var encodedUri = encodeURI(emlContent); //encode spaces etc like a url
					var a = document.createElement('a'); //make a link in document
					var linkText = document.createTextNode("fileLink");
					a.appendChild(linkText);
					a.href = encodedUri;
					a.id = 'fileLink';
					a.download = 'logEntryEmail_' + sEmailLogEntryID + '_' + sDate + '.eml';
					a.style = "display:none;"; //hidden link
					
					document.body.appendChild(a);
					document.getElementById('fileLink').click(); //click the link
				};					
			 }
			 catch(er)
			 {
				 alert(er.message);
			 }
			 finally
			 {
				outlookApp = null;
				mailItem = null;
				sContent = null;
				emlContent = null;
				encodedUri = null;
				a = null;
				linkText = null;				
				d = null;
				dateString = null;
			 }

There were a few pitfalls that had to be overcome in completing this. If the HTML code includes any octothorpes (a.k.a, number sign, pound sign, hashtag), these must be escaped by replacing them with the hex code “%23” (no quotes). Otherwise, they will cause the URL to be processed incorrectly, causing errors.

In some cases, escaping the number signs won’t work. For instances where they are used as CSS colors, either the common name should be used when one exists (i.e., #FFFFFF is “white”), or RGB should be subbed in instead.

For the filename, I concatenated both a unique log entry ID, and the UTC time the file was created to prevent duplicate filenames in the user’s downloads folder.

 

%d bloggers like this: