Programmi Java e server AS400 (IBM i) Franco Lombardo [email protected] Molteni Informatica - Lecco 1 IBM Developer Kit for Java Driver JDBC locale Classe com.ibm.db2.jdbc.app.DB2Driver URL jdbc:db2://NomeDB dove NomeDB è una voce di WRKRDBDIRE (posso utilizzare jdbc:db2://*local /QIBM/ProdData/OS400/Java400/ext/db2_classes.jar Si aggancia ad un lavoro server di preavvio nnnnn/QUSER/QSQSRV Lavora per conto del profilo utente di logon, ma non assume la JOBD legata a tale profilo, e non richiama neppure eventuali programmi iniziali: attenzione alla lista librerie! (Mantenuta libreria corrente) 2 IBM Toolbox for Java Libreria 100% pure Java per accedere a risorse AS400 Utilizzabile sia su client, sia su AS400 Contiene (tra le altre cose) Driver JDBC Classi per richiamo programmi, accesso a code dati, profili utente, stampe, messaggi, job, aree dati, IFS, valori di sistema, stato del sistema... Classi di utilità (es. table model Swing bufferizzato “MS Access”-like, JarMaker per estrarre sottoinsiemi di classi da un Jar) 3 IBM Toolbox for Java Dove trovarlo Installato su AS400 come programma su licenza (gratuito) nell’IFS Installato a richiesta con Client Access (i-Series Access) /QIBM/ProdData/HTTP/Public/jt400/lib/jt400.jar C:\Programmi\IBM\Client Access\jt400\lib\jt400.jar Scaricabile gratuitamente da internet nella sua versione open-source (JTOpen). E’ sempre la versione più aggiornata, che consiglio di usare. Sul server AS400 richiede l’installazione e l’avvio degli Host Servers 4 IBM Toolbox for Java JDBC Driver di tipo 4 Classe com.ibm.as400.access.AS400JDBCDriver URL jdbc:as400://nomeOIpAs[/libreria][;listaProprietà] Si appoggia allo stesso demone di sistema utilizzato da ODBC: QZDASRVSD Avviato con STRHOSTSVR *DATABASE In ascolto su porta TCP 8471 Associa ad ogni client un lavoro di preavvio nnnnnn/QUSER/QZDASOINIT 5 IBM Toolbox for Java JDBC: QZDASOINIT E’ utile abbassare la priorità di default di tale lavoro e regolare il numero di lavori avviati automaticamente CRTCLS CLS(ODBC) RUNPTY(25) TIMESLICE(3000) CHGPJE SBSD(QUSRWRK) PGM(QZDASOINIT) INLJOBS(20) THRESHOLD(15) ADLJOBS(5) CLS(ODBC) Esempio per avviare automaticamente 20 lavori, aggiungerne automaticamente 5 quando ne sono in esecuzione meno di 15 ed avviarli a priorità 25 (più veloci dei batch e più lenti degli interattivi) Su V4Rx il sottosistema è QSERVER 6 IBM Toolbox for Java JDBC: properties Impostabili anche nell’URL, per esempio: jdbc:as400://myAS;trace=true;user=pino;password=x; Vediamone alcune transaction isolation gestione transazioni. Se i file non sono sotto giornale, occorre impostare il valore none, che non è il default! server trace gestione log su AS400. Valore 4: avvia STRDBG per QZDASOINIT, che registra anche suggerimenti per costruzione indici. Valore 8: salva JOBLOG per QZDASOINIT. 7 IBM Toolbox for Java JDBC: properties trace gestione ordinamento/ricerche. Valore true: stampa sullo standard output del client la registrazione dettagliate di tutte le chiamate JDBC. Forte scadimento delle prestazioni: solo per debug. sort gestione ordinamento/ricerche. Valore language: effettua ricerche/ordinamenti in base alla lingua specificata nella proprietà sort language (per noi ITA). Impostando tale valore è possibile effettuare ricerche non case-sensitive (sul modello MS SQLServer). Possibile scadimento delle prestazioni. 8 IBM Toolbox for Java JDBC: Exit programs E’ possibile eseguire un programma su AS400 Al collegamento di ogni client Prima dell’esecuzione di ogni statement SQL Punto di uscita QIBM_QZDA_INIT Punto di uscita QIBM_QZDA_SQL1 Tali programmi ricevono in ingresso i dati della richiesta (profilo utente, statement SQL...) e restituiscono un flag che indica se accettarla. Gestiti con il comando WRKREGINF 9 IBM Toolbox for Java JDBC: Exit programs /* /* /* /* /* Un esempio CL per il controllo del collegamento PGM PARM(&STATUS &REQUEST) Flag di accettazione/rifiuto richiesta */ DCL VAR(&STATUS) TYPE(*CHAR) LEN(1) Parametro di ingresso contenente anche il nome utente */ DCL VAR(&REQUEST) TYPE(*CHAR) LEN(2000) DCL VAR(&UTENTE) TYPE(*CHAR) LEN(10) Di default rifiuto tutte le connessioni */ CHGVAR VAR(&STATUS) VALUE('0') Recupero nome utente */ CHGVAR VAR(&UTENTE) VALUE(%SST(&REQUEST 1 10)) Abilito solo le connessioni di FRANCO */ IF COND(&UTENTE *EQ 'FRANCO') THEN(CHGVAR + VAR(&STATUS) VALUE('1')) ENDPGM Per attivare il programma ADDEXITPGM EXITPNT(QIBM_QZDA_INIT) FORMAT(ZDAI0100) PGMNBR(1) PGM(LIB/PGM) (Tutti i pgm QZDASOINIT in esecuzione devono essere riavviati) 10 IBM Toolbox for Java JDBC: chiamata programmi E’ possibile richiamare un qualsiasi programma AS400 da una connessione JDBC utilizzando lo statement SQL CALL Se non si devono ricevere dei parametri di ritorno dal programma, non è necessario creare anticipatamente una definizione di Stored procedure Altrimenti occorre prima definire la procedura con lo statement SQL CREATE PROCEDURE 11 IBM Toolbox for Java JDBC: chiamata programmi Esempio di chiamata a programma senza restituzione parametri: il programma chiamato… PGM DCL DCL CPYF PARM(&FILE &LIB) VAR(&FILE) TYPE(*CHAR) LEN(10) VAR(&LIB) TYPE(*CHAR) LEN(10) FROMFILE(&LIB/&FILE) TOFILE(QSYSPRT) ENDPGM 12 IBM Toolbox for Java JDBC: chiamata programmi …ed il programma chiamante try { Class.forName("com.ibm.as400.access.AS400JDBCDriver"); Connection c = DriverManager.getConnection( "jdbc:as400://AS400;user=PIPPO;password=X"); Statement s = c.createStatement(); s.execute( "CALL MYLIB.MYPGM ('NOMEFILE ', 'NOMELIB ')"); } catch (Exception e) {} Fate attenzione agli spazi nei parametri stringa: devono riempire la capacità della variabile (nell'esempio 10 caratteri) 13 IBM Toolbox for Java JDBC: chiamata programmi Esempio di chiamata a programma con restituzione parametri: il programma chiamato… PGM DCL DCL CHGVAR IF PARM(&INGR &USC) VAR(&INGR) TYPE(*CHAR) LEN(10) VAR(&USC) TYPE(*CHAR) LEN(2) VAR(&USC) VALUE('KO') COND(&INGR *EQ 'FRANCO') THEN(CHGVAR + VAR(&USC) VALUE('OK')) ENDPGM Lo statement SQL di creazione procedura CREATE PROCEDURE MYLIB.MYPGM2(IN INGR CHAR (10 ), OUT USC CHAR (2 )) LANGUAGE CL NOT DETERMINISTIC CONTAINS SQL EXTERNAL PARAMETER STYLE GENERAL 14 IBM Toolbox for Java JDBC: chiamata programmi …ed il programma chiamante try { Class.forName("com.ibm.as400.access.AS400JDBCDriver"); Connection c = DriverManager.getConnection( "jdbc:as400://AS400;user=PIPPO;password=X"); CallableStatement cs = c.prepareCall("CALL MYLIB.MYPGM2 (?, ?)"); cs.registerOutParameter(2, Types.CHAR); cs.setString(1, "FRANCO"); cs.executeUpdate(); System.out.println("Risultato: " + cs.getObject(2)); } catch (Exception e) {} 15 IBM Toolbox for Java JDBC: esecuzione comandi Come eseguire un comando? Con il programma di sistema qcmdexc, che ha come primo parametro un comando e come secondo la lunghezza del primo parametro try { Class.forName("com.ibm.as400.access.AS400JDBCDriver"); Connection c = DriverManager.getConnection( "jdbc:as400://AS400;user=PIPPO;password=X"); CallableStatement cs = c.prepareCall("CALL qsys.qcmdexc (?, ?)"); String cmd = "CHGJOB RUNPTY(15)"; cs.setString(1, cmd); cs.setObject(2, new Integer(cmd.length())); cs.execute(); 16 } catch (Exception e) {} IBM Toolbox for Java JDBC: esecuzione comandi Utilizzando l'interfaccia CallableStatement, occorre prima creare la definizione di stored procedure con: CREATE PROCEDURE QSYS.QCMDEXC(IN CMD VARCHAR(1024), IN CMDLEN DECIMAL(15, 5)) EXTERNAL NAME QSYS.QCMDEXC LANGUAGE C GENERAL 17 IBM Toolbox for Java JDBC: esecuzione comandi L'esempio precedente potrebbe essere realizzato anche senza l'utilizzo di CallableStatement: try { Class.forName("com.ibm.as400.access.AS400JDBCDriver"); Connection c = DriverManager.getConnection( "jdbc:as400://AS400;user=PIPPO;password=X"); Statement s = c.createStatement(); s.execute( "call qsys.qcmdexc('CHGJOB RUNPTY(15)',000000017.00000)"); } catch (Exception e) {} 18 IBM Toolbox for Java JDBC: esecuzione comandi Nell'esempio precedente abbiamo modificato la priorità del lavoro JDBC che serve le nostre chiamate. Questo può essere fatto solo se il profilo utente di collegamento ha l'autorizzazione speciale *JOBCTL 19 IBM Toolbox for Java JDBC Come scambiare grosse quantità di dati? Tramite file nella libreria QTEMP: libreria "virtuale" di cui esiste una istanza per ogni lavoro. I file creati in tale libreria sono visibili solo dal lavoro corrente e vengono cancellati automaticamente alla fine del lavoro stesso. Tramite file normali, magari indicizzati dal numero di lavoro, reperibile come nell'esempio iniziale (ricordarsi di riorganizzare con RGZPFM) 20 IBM Toolbox for Java JDBC Come estrarre un sottoinsieme di classi dal Toolbox (es. JDBC)? Con la classe AS400ToolboxJarMaker (solo JTOpen): java -cp jt400.jar utilities.AS400ToolboxJarMaker -component JDBC -ccsid 1144 estrae le classi necessarie al dirver JDBC per la code-page italiana con simbolo euro (1144) Estensione di JarMaker: classe di JTOpen per l’estrazione da file Jar dell’insieme minimo di classi necessarie per l’esecuzione di una classe. 21