Transcript Greetings from the Edge: Using javaobj in DATA Step
Greetings from the Edge: Using javaobj in DATA Step
Richard A. DeVenezia Independent Consultant
SAS is a registered trademark or trademark of SAS Institute Inc. in the USA and other countries. ® indicates USA registration. Other brand and product names are registered trademarks or Trademarks of their respective companies.
Slide imagery copyright © 2004, SAS Institute Inc.
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Overview
SAS Version 9 DATA Step has experimental syntax for interfacing with objects •
Java
, Hash, HashIter Demonstration by way of examples.
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Java is ...
java.sun.com
“The Java 2 Platform provides robust end-to-end solutions for networked applications as well as a trusted standard for embedded applications”
Widespread Networked Applications • Analysis and management
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Component Interface is ...
support.sas.com/rnd/...
“DATA Step Component Interface provides a mechanism for accessing predefined component objects from within a DATA Step program.” Instantiate • Create an object •
declare Type var, var = _new_
Access •
var.method()
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
javaobj is ...
DATA Step Experimental Part of broader initiative • Component Interface • Object Dot Syntax
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Java development
Free kit •
java.sun.com/j2se
• compiler, packager and loader
javac, jar, java
• Runtime Environment • Online training Tutorials • numerous web sites and publications
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
The edge
New or experimental Where two things come together
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
SAS session
Version 9 • CLASSPATH environment variable
-set CLASSPATH myPath;%CLASSPATH%
Version 9.1
• jreoptions SAS option
-jreoptions ( -Djava.class.path=myPath;%CLASSPATH% -Dsas.jre.version=jrePath )
Default JRE is installed at shared\JRE\1.4.1
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
A little birdie
Version 9.1
Proc JAVAINFO
--log--
java.version = 1.4.1
java.vm.version = 1.4.1-b21 java.home = c:\opt\sas\shared\JRE\1.4.1
java.class.path =
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Java coding pattern - variables
public class
Class
{ private double
variable
; public double get Variable () { return this.
variable
; } public void set
Variable
(double
variable
) { this.
variable
=
variable
; } }
java.sun.com/docs/codeconv /html/CodeConvTOC.doc.html
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Java coding pattern - methods
public class
Class
{ public
(args...) {...} }
java.sun.com/docs/codeconv /html/CodeConvTOC.doc.html
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Declare statement
declare javaobj var ('Class' [,arg-1[,…[,arg-N]]) ;
- or
declare javaobj var; var = _NEW_ javaobj ('Class' [,arg-1[,…[,arg-N]]) ;
declare javaobj j (‘java/lang/String’); declare javaobj j (‘java/awt/geom/Ellipse2D/Double’); Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Accessing methods and fields
public
Type method ( args …) {…}
obj.
call
Type
Method ( ‘
method ’, args …, return );
public
Type field ;
obj.
[get|set]
Type
Field (
‘ field ’, value );
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
HelloSAS.java
public class HelloSAS { public String getMessage () { return "Hello SAS"; } } Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
HelloSAS.sas
data _null_; length message $200; declare javaobj j (’HelloSAS'); j.callStringMethod ('getMessage', message); put message=; run; --- log - message=Hello SAS Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Gotchas
Classes are cached per SAS session Did you recompile a Java class?
• Restart SAS Signature Types • pass double, String, javaobj • return double, String
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
SystemProperties.class
import java.util.Enumeration; public class SystemProperties { private Enumeration e; public SystemProperties () { e = System.getProperties().propertyNames(); } public String return getProperty () { if (e.hasMoreElements()) { String p = (String) e.nextElement(); p + "=" + System.getProperty(p) ; } else { return null ; } } } Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
SystemProperties.sas
data _null_; dcl javaobj j (’ SystemProperties '); length s $200; j.callStringMethod (' getProperty ', s); do while ( s ne '' ); run; ...
… put s; j.callStringMethod ('getProperty', s); end; --- log -- java.vm.version=1.4.2_03-b02 java.vm.vendor=Sun Microsystems Inc.
sas.jre.home=C:\j2sdk1.4.2_03\jre Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Exceptions
Always check, handle and clear
exceptionDescribe(1)
•
write exceptions to stdout or console
exceptionCheck(rc)
•
did an exception occur ?
exceptionClear()
•
clear the exception flag Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Object persistence
Intra DATA Step ? No • javaobj is gone when DATA Step ends • obj.delete() recommended Birdie:
“An instantiated javaobj creates a JNI reference which will not be garbage collected. The reference needs to be explicitly deleted.”
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Case for persistence
Creating SAS Table from Q, a DBMS Query Q java.sql.ResultSet
• Two SAS Passes • 1. ResultSetMetaData, columns and types • 2. ResultsSet, rows Without persistence, Q must be issued for each pass • not wanted
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Persistence categories
Intra SAS session • Object persists between DATA Steps in one SAS session • static fields and thread Inter SAS session • Object persists between DATA Steps and SAS sessions • Remote method invocation - RMI Require wrapper classes
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Persistence via Static
Static fields java
public class Persist {static double x,y,z; }
sas
data _null_; declare javaobj j ('Persist'); j.setStaticDoubleField('x',100); j.delete(); run; data _null_; declare javaobj j ('Persist'); j.getStaticDoubleField('x',x); j.delete(); put x=; run;
x=100
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Persistence via Thread
Runnable (R) • monitors its state • persists in Thread started by A Adapter (A) • new Thread ( new R() ) . start () • methods grant access to R’s state • static fields persist across DATA Step -reference to R
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Persistence via RMI
Server process outside of SAS DATA Step is client of server • via wrapper Server allocates resources • Returns handles • Methods accessed by handle
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
DBMS servers
Commercial Open source • Postgresql • mySQL JDBC • not an acronym (just like ess-a-ess) • trademark • 210 drivers listed at http://servlet.java.sun.com/products/jdbc/drivers
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
JDBC connection pattern
Class.forName(jdbcDriver); Connection con = DriverManager.getConnection
( URL, username, password );
jdbcDriver
=
“org.postgresql.Driver”
URL = “jdbc:postgresql://www.devenezia.com:5434/sesug03demo”
username = “sesug03demo”
password = “D3m0oeoe” Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Gateway - an RMI scheme
Three classes An Interface • GatewayInterface An Implementation • GatewayManager A Server • GatewayServer
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
GatewayInterface
Declares methods
public int getConnectionHandle ( String driverClass, String databaseURL, String username, String password ) throws RemoteException; public int getStatementHandle (int cHandle) throws RemoteException; public int executeQuery (int handle, String sql) throws RemoteException; Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
GatewayManager
Implements the Interface
public int getConnectionHandle ( { … { String driverClass, String databaseURL, String username, String password) throws RemoteException try System.out.println ("loading "+driverClass); Class.forName(driverClass); System.out.println ("connecting to "+databaseURL); con = DriverManager.getConnection (databaseURL, username, password); System.out.println ("connected"); } … Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
GatewayServer
Hosts a GatewayManager
protected static final String RMI_NAME = "JDBC-GATEWAY-MANAGER
";
public static void main(String args[]){ … try { LocateRegistry.createRegistry(1099); GatewayManager manager = new GatewayManager (5); Naming.rebind (RMI_NAME, manager); } … System.out.println ( manager.getClass().getName() + " ready to manage " + 5 + " connections."); Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
DataStepGatewayAdapter
Reimplements GatewayInterface • creates and uses delegate • performs typecasting where needed
public class DataStepGatewayAdapter { private GatewayInterface dbi; public DataStepGatewayAdapter() throws Exception { dbi=GatewayServer.getReferenceToPersistentManager (); } public int getStatementHandle (double cHandle) throws Exception { return dbi.getStatementHandle ( (int) cHandle); } Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
SAS macros
Facilitate use of Gateway
startServer
getConnectionHandle
getStatementHandle
jdbcLoadTable
jdbcQuery Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Using the macros
Reimplements GatewayInterface
%let jdbc_server_policy = gateway.policy; %let jdbc_driver = org.postgresql.Driver; %let db_url = jdbc:postgresql://www.devenezia.com:5434/sesug03demo; %let username = sesug03demo ; %let password = D3m0oeoe; %let cHandle =; %getConnectionHandle ( driver = &jdbc_driver , url = &db_url , user = &username , pass = &password , cHandle_mv = cHandle ); Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Using the macros
%jdbcLoadTable ( cHandle=&cHandle, data=sashelp.zipcode, obs=20); %jdbcQuery ( cHandle=&cHandle, sql=SELECT * FROM ZIPCODE, out=WORK.ZIPCODE); Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Other tasks handled well by Java
Directory listings Archived file sets Database connectivity 2D and 3D graphics Open Office XML HTML parsing and so much more
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Conclusion
Javaobj opens new horizons • Utilize problem solvers who work in Java Hybrid solutions • Combine features of different technologies Paper, slides and examples
www.devenezia.com/papers Copyright © 2004 , Richard A. DeVenezia. All rights reserved.