1. Olan Knight
  2. PowerBuilder
  3. Tuesday, 13 July 2021 17:48 PM UTC

PowerBuilder v12.1 & PBv2019R3
Oracle 12C
PostgreSQL v12
Windows 10, 64 bit platform

I know this is not an Eclipse forum, I'm just hoping someone knows an Eclipse expert that would be willing to help me!!!


Summary:
I need an Eclipse expert to tell me what I'm doing wrong with my Class file!
An imported class is apparently not seen by the compiler in Eclipse, AND never shows up in the runtime JAR.

Details:
Our PB application invokes Java code using the RUN command. Don't laugh, it works.  :)

The Java code is written and compiled using Eclipse Juno. I inherited this setup, and I get into the Java code about twice a year. I'm Java certified, but not Eclipse certified.


I created a new class to connect to a PostgreSQL database; I used an existing Oracle connection class as a template. The issue is that the new class works perfectly in DEBUG mode or in "Run as a Java application" mode, but not in runtime when the Java process is running from a JAR file. In other words it works fine when running in the Eclipse IDE but it fails in runtime.

I suspect that something simple needs to be done in Eclipse to get the new PostgreSQL JAR file seen and accepted, but I don't have the foggiest notion of what that might be. And that's why I calling for an Eclipse expert!

The PostgreSQL driver JAR file is in the build path.
The PostgreSQL driver classes are imported into the new Class file.

If we do NOT have a ClassNotFoundException() CATCH block coded in the class, the Class file has an error:

The error on line 81 is "Class not found".
This occurs even though the specified JAR file is being imported and we can SEE the "Driver" class in the left pane!!!!



The runtime error is always "Unknown Source" / "Class Not Found exception"

 

Here's the Build Path in Eclipse:

 

Olan Knight Accepted Answer Pending Moderation
  1. Thursday, 2 September 2021 20:44 PM UTC
  2. PowerBuilder
  3. # 1

I finally got some help in this.


It seems that the Eclipe  IDE already performs the function of the ForName() call in this case, based on how EDB specified their driver in their JAR file.

1. I re-downloaded the JAR file from EBD:  postgresql-42.2.23.jar.

2. I added this JAR file to the ExternalJar files of the Eclipse IDE.


3. I ensure that the JAR file was in the Build PAth.

4. In my new class "ConnectPostGreSQL()", I commended out line 81:


5. In the PowerBuilder 2019R3 code, I wrote a new function to create the PostgreSQL connection string used in the sqlca.DBPARM slot.

//*********************************************************************
// Object        :    corp_n_cst_appmanager
// Function      :    of_build_PG_connect_string()
//
// Ancestor      :    None
// Access        :    Public
// Arguments     :    value   string   as_userid     account userid
//                    value   string   as_password   account password
//                    value   string   as_regdata    data from the Registry
//
// Returns       :    String              The CONNECTION string
// Throws        :    None
//
// Description   :    Read the INI file and create the DBPARMS string
//                    needed to connect to a PostgreSQL database.
//
//                    We us an INI file because the string created by
//                    reading entries from the Windows Registry does not
//                    work when the CONNECT is called.
//
//********************************************************************
// Revision History
//
// Developer   Date          Version     Description
// ---------   -----------   ---------   -------------------------------
// O Knight    17-JUN-2021   6.0.4.37    #2026345:  Initial installation.
//
//********************************************************************
// COPYRIGHT © 2021 <name> INTERNATIONAL, INC. AND/OR ITS
// AFFILIATES (“CSG”). ALL RIGHTS RESERVED.
//********************************************************************
long        ll_len, ll_pos, ll_start, ll_end, ll_slashhat
string      ls_value, ls_regdata, ls_DBParm, ls_data



// Init
ls_regdata  = Lower (as_regdata)                // Lower the Registry Data

    
// as_regdata = ls_dbconnections[ll_conn] = the connection data components string
//
// is_dbconnections [ll_noDbConn] =            &
//        ls_dbDisplayString + ","           + &                
//        ls_dbmsver         + ","           + &
//        ls_connectString                   + &
//        "/^"                               + &
//        ls_dbms                            + &
//        ";Driver="        + ls_driver      + &                                        
//        ";DatabaseName="  + ls_database    + &                                        
//        ";ServerIpAddr="  + ls_ip_address  + &
//        ";Port="          + ls_port        + &                            
//        ";ConnectParms="  + ls_conparms
//                                    
// Example finished entry:
// dev12c_PG,POSTGRESQL,                                                              &
//                 ConnectString='Driver=<driver>;Database=<db>;Server=<ip>;Port=<port>;UID=<userid>;PWD=<password>;',/^PostgreSQL;Driver=PostgreSQL Unicode;DatabaseName=ls_datatase;ServerIpAddr=10.50.68.244;Port=5444;                                                  &
//                 ConnectParms=DisableBind=1,UseServerSidePrepare=1,PBCatalogOwner='chadba',StripParmNames='Yes'
//                

// Extract the DBPARM string to be populated
ll_start     = POS (ls_regdata, "connectstring", 1)
ll_slashhat  = POS (ls_regdata, "/^", ll_start)
ll_len       = ll_slashhat - ll_start
ls_DBParm    = MID (ls_regdata, ll_start, ll_len)


// The connection string has placeholders that need to be replaced with actual values
// ls_DBParm =
//   connectstring='driver=<driver>;database=<db>;server=<ip>;port=<port>;uid=<userid>;pwd=<password>;',

    
// Replace the DRIVER
ll_start   = POS (Lower(ls_regdata), "driver=", ll_slashhat) + 7      // Driver=PostgreSQL Unicode;
ll_end     = POS (ls_regdata, ";", (ll_start + 1))
ll_len     = ll_end - ll_start
ls_data    = MID (ls_regdata, ll_start, ll_len)                       // Extract the driver

ll_start   = POS (Lower(ls_DBParm), "<driver>", 1)
ll_len     = 8
ls_DBParm  = Replace (ls_DBParm, ll_start, ll_len, ls_data)


// Replace the DATABASE
ll_start   = POS (ls_regdata, "databasename=", ll_slashhat) + 13     // DatabaseName=nttest;
ll_end     = POS (ls_regdata, ";", (ll_start + 1))
ll_len     = ll_end - ll_start
ls_data    = MID (ls_regdata, ll_start, ll_len)                      // Extract the database name

ll_start   = POS (Lower(ls_DBParm), "<db>", 1)
ll_len     = 4
ls_DBParm  = Replace (ls_DBParm, ll_start, ll_len, ls_data)


// Replace the SERVER IP ADDRESS
ll_start   = POS (ls_regdata, "serveripaddr=", ll_slashhat) + 13    // ServerIpAddr=10.50.68.244;
ll_end     = POS (ls_regdata, ";", (ll_start + 1))
ll_len     = ll_end - ll_start
ls_data    = MID (ls_regdata, ll_start, ll_len)                     // Extract the server ip address

ll_start   = POS (Lower(ls_DBParm), "<ip>", 1)
ll_len     = 4
ls_DBParm  = Replace (ls_DBParm, ll_start, ll_len, ls_data)    


// Replace the PORT
ll_start   = POS (Lower(ls_regdata), "port=", ll_slashhat) + 5    // Port=5444;
ll_end     = POS (ls_regdata, ";", (ll_start + 1))
ll_len     = ll_end - ll_start
ls_data    = MID (ls_regdata, ll_start, ll_len)                   // Extract the port number

ll_start   = POS (Lower(ls_DBParm), "<port>", 1)
ll_len     = 6
ls_DBParm  = Replace (ls_DBParm, ll_start, ll_len, ls_data)

    
// Replace the userid
ll_start   = POS (Lower(ls_DBParm), "<userid>", 1)
ll_len     = 8
ls_DBParm  = Replace (ls_DBParm, ll_start, ll_len, as_userid)


// Replace the password
ll_start   = POS (Lower(ls_DBParm), "<password>", 1)
ll_len     = 10
ls_DBParm  = Replace (ls_DBParm, ll_start, ll_len, as_password)


// Add the connection parameters
ll_start  = POS (Lower(ls_regdata), "connectparms=", 1) + 13    // ConnectParms=DisableBind=1,.....
ls_data   = MID (ls_regdata, ll_start, 9999)                    // Last data segment in ls_regdata    
ls_DBParm = ls_DBParm + "," + ls_data


// Set up to connect with a DNS-less connection
//  These work:
//        SQLCA.DBParm    = ConnectString='Driver=PostgreSQL Unicode;Database=nttest;Server=10.50.68.244; Port=5444;UID=cabdevusr;PWD=cabdevusr;',DisableBind=1
//        SQLCA.DBParm    = ConnectString='Driver=PostgreSQL Unicode;Database=nttest;Server=10.50.68.244; Port=5444;UID=cabdevusr;PWD=cabdevusr;',DisableBind=1,UseServerSidePrepare=1,PBCatalogOwner='chadba',StripParmNames='Yes'


RETURN ls_DBParm

Comment
  1. Armeen Mazda @Appeon
  2. Thursday, 2 September 2021 21:22 PM UTC
Thanks for sharing the solution!
  1. Helpful
There are no comments made yet.
Olan Knight Accepted Answer Pending Moderation
  1. Wednesday, 14 July 2021 13:38 PM UTC
  2. PowerBuilder
  3. # 2

THANK YOU for your response, Arnd! I tried it like that and got a better error, one that indicates the COMPILE issue in the Eclipse IDE:

BUILD NUMBER  = 0210 (07-JUL-2021)
JAVA VERSION  = 1.8.0_231

DATABASE_TYPE = POSTGRESQL
DATABASE_NAME = dev12c
URL           = jdbc:postgresql://10.11.22.333:5123/dev12c
USERNAME      = myUserName
REMOTE_HOST   =


 >>>> In ProcessCodeData constructor....
In ProcessCodeData.constructor, STOREDETAIL = false, sourceFileUid = 436583, STOREHISTORY = false, inDebugMode = false
Exception in thread "C:\Personal\testing\AC.COX.S225223.VS050509.T012106" java.lang.Error: Unresolved compilation problem:
    Unhandled exception type ClassNotFoundException

    at com.intec.inteccommon.ConnectPostgreSQL.openConnection(ConnectPostgreSQL.java:81)
    at com.intec.inteccommon.IntecParams.openConnection(IntecParams.java:439)
    at com.intec.Codeprocessing.ProcessCodeData.<init>(ProcessCodeData.java:331)
    at com.intec.Codeprocessing.PreProcCodeData.<init>(PreProcCodeData.java:145)
    at com.intec.Codeprocessing.ProcessCodeFile.run(ProcessCodeFile.java:365)

 

And that's my issue: The IDE appears to see the org.postgresql.Driver class, but the Class itself does not!

In the left pane, the Driver class is highlighted. In the right pane, in the Class file, the call to "forName" fails.

Any ideas on how to get the Class file to "see" the referenced DRIVER class?



Thank You Again,

Olan

Comment
  1. Miguel Leeuwe
  2. Wednesday, 14 July 2021 15:08 PM UTC
Could it be a good old PATH problem?

(just saying something random, don't take me too seriously)

regards
  1. Helpful
  1. Miguel Leeuwe
  2. Wednesday, 14 July 2021 15:09 PM UTC
More 'randomness':

JAVA_HOME ?
  1. Helpful
There are no comments made yet.
Arnd Schmidt Accepted Answer Pending Moderation
  1. Wednesday, 14 July 2021 13:19 PM UTC
  2. PowerBuilder
  3. # 3

Build Path and Classpath during runtime are something different.

In Eclipse you can also have a different Classpath (run configuration) than in your "normal" system environment when excuted from a commandline outside the Eclipse Environment.

Furthermore you can ...

https://stackoverflow.com/questions/11033603/how-to-create-a-jar-with-external-libraries-included-in-eclipse

hth

Arnd

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.