Examining the TransactionObject in PowerBuilder During Update and Delete

PowerBuilder logo

During the upgrade of an application from Sybase PowerBuilder 6.5 to SAP PowerBuilder 12.6, I ran into a bug in the Update event that had me suspicious that the TransactionObject was somehow changing, causing the update to be directed toward a different database.

As it turns out, the bug was due to a trigger in the main database that was selecting data from another database. 

Even so, I learned about something quite valuable: the SQLPreview event. 

event sqlpreview
this.setsqlpreview(sqlsyntax)
end event

If you set a watch on sqlsyntax, you can see the SQL code associated with the data update.

Memory Issues with Oracle WebLogic Smart Update

Oracle WebLogic Smart Updater splash screen

If you need to update Oracle WebLogic 10.3.6 on Solaris / UNIX / Linux with a security patch or service pack, you will likely find yourself using the Oracle Smart Update program. 

This program, which is run by executing the script bsu.sh, is usually found in the utils/bsu folder underneath the BEA Home folder. For example, if your BEA Home folder is “/u01/app/bea64/middleware”, you would change directory to “/u01/app/bea64/middleware/utils/bsu”, and execute bsu.sh, after uploading the required patch files to the cache_dir directory.

{user@server:/:}# cd /u01/app/bea64/middleware/utils/bsu
{user@server:/u01/app/bea64/middleware/utils/bsu:}# ./bsu.sh

Officially, this is how you would execute the program. Except that, for whatever reason, it seems that this script has not provided nearly enough memory for the program to run. Unfortunately, you will likely not find this out for almost an hour, while you get the splash screen above and your server attempts to run the program.

One Eternity Later

After the interminable wait is up, your program has crashed, and you finish pulling what’s left of your hair out, you can begin to troubleshoot the problem. Or, hopefully, you will have found this post before trying any of this!

Let’s look at the source of the problem. Literally.

{user@server:/u01/app/bea64/middleware/utils/bsu:}# cat bsu.sh
#!/bin/sh
JAVA_HOME="/usr/jdk/instances/jdk1.8.0"
MEM_ARGS="-Xms256m -Xmx512m"
"$JAVA_HOME/bin/java" ${MEM_ARGS} -jar patch-client.jar $*
{user@server:/u01/app/bea64/middleware/utils/bsu:}#

See that MEM_ARGS variable? This isn’t 1999 anymore, so let’s change the memory allocation, shall we? Oh, I should mention that if you’re still using a 32-bit version of Java, you’ll be constrained by that pesky 2 GB limit and will have to adjust accordingly.

Let’s see how much memory we have. I’m running Solaris, so this is what I ran:

{user@server:/u01/app/bea64/middleware/utils/bsu:}# prtconf | grep Memory
prtconf: devinfo facility not available
Memory size: 131072 Megabytes
{user@server:/u01/app/bea64/middleware/utils/bsu:}#

Also, I ran “java -d64” just to ensure that I am indeed running a 64-bit JVM.

Using everyone’s favorite editor (vi, of course), I increased the JVM memory allocations and saved the script as a new file: bsumem.sh.

#!/bin/sh
JAVA_HOME="/usr/jdk/instances/jdk1.8.0"
MEM_ARGS="-Xms32255m -Xmx64510m"
"$JAVA_HOME/bin/java" ${MEM_ARGS} -jar patch-client.jar $*

After saving the file, I executed it: “./bsumem.sh”

Oracle Smart Update loading...

At this point, go pop some popcorn and watch an episode of something on Netflix or Amazon Prime. Don’t worry, the program will still be loading when you finish. (You might actually want to check every 15 minutes or so just to make sure that no other errors crashed the app!)

Once your show is over, you can come back and if you held your mouth right when executing the last command, the program will be ready to load the patch. Or you may have to wait another 15-20 minutes, but it should be relatively soon.

I have yet to figure out why this program takes so long to run, though from what I’ve read, it’s a common – if not universal – experience. 

Changing the Authentication Mode in Oracle Primavera P6 EPPM Using SQL

Oracle Primavera P6 EPPM

I am currently in the process of setting up an Oracle Primavera P6 EPPM 18.8 environment. The operating system on the application and Web server is Windows Server 2012 R2, the middleware is Oracle WebLogic 12c, and Oracle Database 12c for the RDBMS.

This is the first time I’ve ever set up P6 from scratch, and I’m doing it without any assistance from Oracle, other than their documentation.

I’ve learned quite a lot in my adventure so far. One thing that I learned is that you REALLY don’t want to turn on LDAP Authentication everywhere until you’re sure it’s working.

(Relevant documentation: Configuring LDAP Settings in the Primavera P6 Administrator)

In the P6 Administration website, there are two places to change the type of authentication used: NATIVE, LDAP, and WebSSO. The Authentication tab:

P6 Administration screen - Authentication tab

And the authentication section on the database instance itself:

P6 Administration screen - Authentication section on DB instance

If both are set to “LDAP” (and presumably “WebSSO” as well) when things aren’t yet set up properly, you’ll get this lovely error: “Primavera P6 was configured to use a different authentication mode than the database selected”.

Google suggests that you read this Oracle doc to fix the problem. However, this problem is only fixed with this solution if only the DB instance setting is “LDAP”. If both are set that way, this solution does not fix the problem – though it should still be run so as to fix the setting on the DB instance page.

After poking around in the database, I discovered that the offending configuration setting was stored in a BLOB in the ADMIN_CONFIG table. Unfortunately, editing this BLOB is not easy without some assistance. Fortunately, I found an article on StackOverflow that had functions for converting a BLOB into a CLOB, at which point the REPLACE function could be used. Then convert the CLOB back to a BLOB, and UPDATE the database table.

First, create the two conversion functions:

CREATE OR REPLACE FUNCTION convert_to_clob(l_blob BLOB) RETURN CLOB IS
      l_clob         CLOB;
      l_dest_offset  NUMBER := 1;
      l_src_offset   NUMBER := 1;
      l_lang_context NUMBER := dbms_lob.default_lang_ctx;
      l_warning      NUMBER;
   BEGIN
      dbms_lob.createtemporary(l_clob, TRUE);
      dbms_lob.converttoclob(dest_lob     => l_clob,
                             src_blob     => l_blob,
                             amount       => dbms_lob.lobmaxsize,
                             dest_offset  => l_dest_offset,
                             src_offset   => l_src_offset,
                             blob_csid    => nls_charset_id('AL32UTF8'),
                             lang_context => l_lang_context,
                             warning      => l_warning);
      RETURN l_clob;
   END convert_to_clob;
   /
CREATE OR REPLACE FUNCTION convert_to_blob(l_clob CLOB) RETURN BLOB IS
      l_blob         BLOB;
      l_dest_offset  NUMBER := 1;
      l_src_offset   NUMBER := 1;
      l_lang_context NUMBER := dbms_lob.default_lang_ctx;
      l_warning      NUMBER;
   BEGIN
      dbms_lob.createtemporary(l_blob, TRUE);
      dbms_lob.converttoblob(dest_lob     => l_blob,
                             src_clob     => l_clob,
                             amount       => dbms_lob.lobmaxsize,
                             dest_offset  => l_dest_offset,
                             src_offset   => l_src_offset,
                             blob_csid    => nls_charset_id('AL32UTF8'),
                             lang_context => l_lang_context,
                             warning      => l_warning);
      RETURN l_blob;
   END convert_to_blob;
   /

Then run an UPDATE statement, something like this, changing the CONFIG_NAME appropriately:

UPDATE ADMIN_CONFIG
     SET CONFIG_DATA = convert_to_blob(
                          REPLACE(convert_to_clob(CONFIG_DATA),
                                 '<mode desc="SET_AUTHENTICATION_MODE" o1="NATIVE" o2="WebSSO" o3="LDAP" type="javax.swing.JComboBox">LDAP</mode>',
                                 '<mode desc="SET_AUTHENTICATION_MODE" o1="NATIVE" o2="WebSSO" o3="LDAP" type="javax.swing.JComboBox">NATIVE</mode>')
                          )
   WHERE CONFIG_NAME = 'myprimavera.bre.YourConfigName';
COMMIT;

After running this script and restarting the application servers, you should once again be back in NATIVE mode and able to get back into P6 to see what went wrong, and no longer crying over the website you thought you had bricked just a few minutes prior.

Enabling Integrated Windows Authentication in Chrome on a Mac

Google Chrome logo

I was surprised at how difficult it was to find this information, given that Chrome is certainly one of the most widely-used browsers in the world, and also that it is commonplace to have Macs connecting to Windows domains.

I found that the domains that would be sent IWA information are set in the AuthServerWhitelist policy. But how to change these policies?

After coming across this article, it appeared that changing the policy via the Terminal window would be the best – and possibly only – way to do this.

Enter the following line into Terminal, using comma-separated domains that you trust with your credentials (with or without wildcards), and press Enter.

$ defaults write com.google.Chrome AuthServerWhitelist "*.domain1.com, *.domain2.net, *.domain3.org"

Restart Chrome.

By accessing chrome://policy, now, you can see the new domains in the policy setting.

Chrome Policies page

While this has not proven to be foolproof – some domains still prompt for a user name and password – it seems to work more often than not.