Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
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 = <no value>
...
Copyright © 2004 , Richard A. DeVenezia. All rights reserved.
Java coding pattern - variables
public class Class
{
private double variable;
public double getVariable()
{
return this.variable;
}
public void setVariable(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 <class> methodNameAsVerb(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.callTypeMethod ( ‘method’, args…, return );
public Type field;
obj.[get|set]TypeField ( ‘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 getProperty () {
if (e.hasMoreElements()) {
String p = (String) e.nextElement();
return 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 '');
put s;
j.callStringMethod ('getProperty', s);
end;
run;
--- 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.