Tuesday, July 28, 2015

jdbc driver with oracle wallets

The processes of converting a jdbc connection as configured in most java application can be confusing. These notes should provide some help and perhaps a better overview.

The first task is to create a wallet. Below, I created two sets of credentials for the same user; RIAD_JAVA. I created two because I wanted to try two types of configurations. One which uses the database connection string and the other which uses a TNS alias.

#first create the wallet 
mkstore -wrl t-riad-wallet -create

#create first of two credentials for user RIAD_JAVA. This will be used for configuration, which needs a tnsname.ora file.
mkstore -wrl t-riad-wallet -createCredential triad RIAD_JAVA secret2015$

#create second set of credentials also for RIAD_JAVA but this time with part of the connection string taken for the java programms externalized properties file. The configuration won't need a tnsname.ora file.
mkstore -wrl t-riad-wallet -createCredential t-riad-dwh-db.tadnet.net:1521/triad.tst.tadnet.net         RIAD_JAVA secret2015$

Before continuing, let me give an over view of what will be shown. 

1. Configuration Using thin client (jdbc:oracle:thin:)

   a.) with Database Configuration String (@hostname:port:service)
   b.) with TNS alias (@anyalias which can be found in tnsname.ora)

2. Configuration Using oci (jdbc:oracle:oci:)



1. Configuration Using thin client (jdbc:oracle:thin:) 


The following jars are needed:
ojdbc6-11.3.0.jar, oraclepki.jar and ucp.jar

a.) with Database Configuration String


Set up the Java application with the following connection string. This should correspond to what was used while creating the second set of credentials above.

jdbc:oracle:thin:/@t-riad-dwh-db.tadnet.net:1521/triad.tst.tadnet.net

Program must be started with the following JVM parameter:

oracle.net.wallet_location


Example:
java -cp .:/global/riad-app/tomcat/lib/ojdbc6-11.3.0.jar:./jlib/oraclepki.jar:./ucp.jar 
-Doracle.net.wallet_location=/tmp/wallet/t-riad-wallet  WalletTest


Note: no tnsname.ora file is needed only the a copy of the wallet created above.


b.) with TNS alias

The above mentioned jar will also be need here. This time the connection string is as follows, which is what was used to create the first set of credentials above.

jdbc:oracle:thin:/@triad

Program must be started with the following JVM parameters:

oracle.net.wallet_location
oracle.net.tns_admin

The following tnsnames.ora will be needed and should exist where oracle.net.wallet_location shown above points to.


 triad =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(Host = t-riad-dwh-db.tadnet.net)(Port = 1521))
    )
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = triad.tst.tadnet.net)
    )
  )

Example call:

java -cp .:./ojdbc6-11.3.0.jar:./jlib/oraclepki.jar:./ucp.jar -Doracle.net.wallet_location=/tmp/wallet/t-riad-wallet  -Doracle.net.tns_admin=/tmp/wallet WalletTest



2. Configuration Using oci (jdbc:oracle:oci:)

Here the jdbc connection string looks as follows:

jdbc:oracle:oci:/@triad


Before starting the programm the following enviroment variables are needed:

ORACLE_HOME=/opt/oracle/product/11.2.0;export ORACLE_HOME

LD_LIBRARY_PATH=/opt/oracle/product/11.2.0/lib:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH

Also a tnsname.ora file


and a sqlnet.ora file are need.









Friday, July 24, 2015

Unified Functional Testing from Hewlett Packard behind a NTLM proxy server.

A colleague of mine wanted to work with Hewlett Packard's UFT/QTP version 11 behind a proxy server, which only supported NTLM. The secret to making it work, because UTF version 11 doesn't support NTLM, was to install cntlm (version 0.92.3) from sourceforge between the test suite and the proxy server on the machine, which was hosting the HP program. After setting up the default cntlm.ini file with the proper proxy server host and port information, user name and password, cntlm was then started as follows:

cntlm -c cntlm.ini -u myuser@mydomain

When UTF asked for the proxy information, localhost and 3128, the port which cntlm was configure to listen on, were entered in the screen below:



Sunday, July 5, 2015

Creating a maven plugin with java 5 annotations rather than javadoc tags

Actually, creating a plugin with the Maven Plugin Tools, is something, thanks to the plugins themselves, which is relatively trivial; however, because it took me a long time to get my plugin working properly with Java 5 annotations rather than Javadoc Tags, I decided to write it down.

I must confess that, sadly enough, Maven has never been a strength of mine so that it was no surprise that my plugin didn't immediately function properly. The problem I faced was in the passing of the parameters to my Mojo during execution of my newly created plugin.

When converted to Java 5 annotation, the class "outputDirectory" attribute, in the default created Mojo,  was always null even though I had the proper configuration in my host project's pom.xml

<configuration>                     
    <outputDirectory>C:\Users\wnpr\Downloads</outputDirectory>         
 </configuration> 

To make sure that we all have the same starting point let me begin, by showing how I used the Maven Integration for Eclipse plugin, M2E, to create a new Maven project as shown below.


Then I selected the "maven-archetype-mojo" as a  temple for my new project,


  and finally gave my plugin a groupId and artefactId.


What follows is a view of the Maven project from within eclipse. As you can see, the project already contains a Mojo class, called MyMojo, which was created from me


Every plugin needs a plugin.xml file, which is generated by the maven-plugin-plugin and which can be found the the META-INF\maven folder of the generated jar file. By default, maven-plugin-plugin generates the plugin.xml file from the Mojo Javadoc Tags found in the Java code. These tags look like this:

/** 
 * Goal which touches a timestamp file. * 
 * @goal touch 
 * 
 * @phase process-sources 
 */

If you, as I did, would rather use Java 5 annotations, such as:

@Mojo( name = "touch" )
public class MyMojo
    extends AbstractMojo {

   @Parameter(defaultValue = "c:\\", required=true)
    public File outputDirectory;

   @Parameter(defaultValue = "Hello World!!!!", required=true)
    public String greeting;
.
.
}

for you plugin.xml generation, then you will have to rely on another plugin; namely: maven-plugin-annotations.

To do this you will have to add an additional dependency, to your plugin project's pom.xml.

<!-- dependencies to annotations -->
<dependency>
   <groupId>org.apache.maven.plugin-tools</groupId>
   <artifactId>maven-plugin-annotations</artifactId>
   <version>3.4</version>
    <scope>provided</scope>
</dependency>    


and override Maven core's default-descriptor execution phase to process-classes as follows:

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-plugin-plugin</artifactId>
        <version>3.4</version>
        <executions>
          <execution>
            <id>default-descriptor</id>
            <phase>process-classes</phase>
          </execution>
          <!-- if you want to generate help goal -->
          <!-- 
          <execution>
            <id>help-goal</id>
            <goals>
              <goal>helpmojo</goal>
            </goals>
          </execution>
           -->
        </executions>
      </plugin>
      </plugins>
    </build>

It wasn't until this last change that the @Parameter annotated attributes of my Mojo were finally set properly during execution of my plugin.  Both of these additions are well described here; however, when I read them for the first time, I wasn't smart enough to understand them; as often is the case, and needed to waste a day before I finally came to my senses.

If you get a message like this:

Error extracting plugin descriptor: 'Goal: touch already exists in the plugin descriptor for prefix: junk
[ERROR] Existing implementation is: org.wmmnpr.junk_maven_plugin.MyMojo

then be sure to delete the old Javadoc Tags.

Good luck!