ࡱ> OY( / 0DTimes New Roman̳0~0DCourier Newman̳0~01 DCourierNewman̳0~0  @n?" dd@  @@`` phb<    !:  ";%&'(#$<)*-.+,/0123456 789 0e0e     A@  A5% 8c8c     ?1 d0u0@Ty2 NP'p<'pA)BCD|E|| 300$$%%@8 <4!d!d$g4dd~0&%ppp@ <4BdBdܿ{Lvg4:d:d~0 p@ pp? $O =5L3Greetings from the Edge: Using javaobj in DATA Step  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 8 #javaobj is ...XDATA Step Experimental Part of broader initiative Component Interface Object Dot Syntax 62&2&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()/   ,Java developmentFree kit java.sun.com/j2se compiler, packager and loader javac, jar, java Runtime Environment Online training Tutorials numerous web sites and publications  f %   %  SAS session  CLASSPATH Location of Java classes Configuration options Host preset environment variable Command line -set CLASSPATH myPath;%CLASSPATH% configuration file (sasv9.cfg) -set CLASSPATH  myPath;%CLASSPATH%   .    Java coding patternpublic class Class { private double variable; public double getVariable() { return this.variable; } public void setVariable(double variable) { this.variable = variable; } }F   ,= - 6/Declare statement declare javaobj var; var = _NEW_ javaobj ('Class' [,arg-1[,& [,arg-N]]) ; - or - declare javaobj var ('Class' [,arg-1[,& [,arg-N]]) ; `PZ%F        Signature  public void setX (double X) { this.X = X } public void setX (String X) { try { this.X = Double.parseDouble(X); } catch (Exception e) { this.X = Double.Nan; } } Pattern of argument types Correspondence DATA Step ERROR: ? +ZF";> %+ | Accessing methods and fields public Type Method (args& ) {& } obj.callTypeMethod (  Method , args& , return ); fields: obj.[get|set]TypeField (  field , value ); Y,  t   HelloSAS.java$ opublic class HelloSAS { public HelloSAS () {} public String getMessage () { return "Hello SAS"; } } jnP Y? &% HelloSAS.sas   Bdata _null_; declare javaobj j ( HelloSAS'); length message $200; j.callStringMethod ('getMessage', message); put message=; run; --- log -- message=Hello SASdn! -1, w GotchasClasses are cached per SAS session Java class recompiled ? Restart SAS Signature Types pass double, String, Object (new) return double, StringH; 8; 8Z+Example 8 - Enumerationdimport java.util.Enumeration; public class Example8 { private Enumeration e; public Example8 () { e = System.getProperties().propertyNames(); } public String getProperty () { if (e.hasMoreElements()) { String p = (String) e.nextElement(); return p + "=" + System.getProperty(p); } else { return null; } } } zG ,w k   " " 6[,Example 8 - DATA Stepdata _null_; dcl javaobj j ('Example8'); 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.1_01-b01 java.vm.vendor=Sun Microsystems Inc. D * ? a &   Object PersistenceNo javaobj 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. ^:!$;"A Case for PersistenceCreating SAS Table from Query Query -> ResultSet Requires Two SAS Passes ResultSetMetaData Read ResultsSet into Data Set Same Query for each pass not wantedHI0 I0 >&  37  Databases  Commercial Open source Postgresql, mySQL communities of devoted developers and users JDBC 109 drivers trademark not an acronym (just like ess-a-ess) Z>;>;P b9!Persistence == RMI qObjects can persist outside SAS in RMI server process Obtaining reference and access requires Java wrapper classR    L#Gateway - an RMI SchemegServer DATA Step is client of server via a wrapper Server allocates resources Returns handles Methods \%%M%Gateway ImplementationcThree Classes An Interface GatewayInterface An Implementation GatewayManager A Server GatewayServer  > N$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;4  *   R&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"); } & DP:!  ,         $T' 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."); } & dbPAd : 4V( GatewayServer getReferenceToPersistentManager() Convience method Client starts immediately after server for (i=0;i<4;i++) { try { remote = Naming.lookup(RMI_NAME); } catch (java.rmi.NotBoundException e) { Thread.currentThread().sleep(250/*ms*/); } }>"9"9Z  X*DataStepGatewayAdapterReimplements GatewayInterface delegates everything to 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); } >;/;/I  \- SAS Macros  dFacilitate use of Gateway startServer getConnectionHandle getStatementHandle jdbcLoadTable jdbcQuery2e ?J].Using the macrosd%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 ); *pZ*p<FpFLp<~`c5:%    V  (^/Using the macros%jdbcLoadTable ( cHandle=&cHandle, data=sashelp.zipcode, obs=20); %jdbcQuery ( cHandle=&cHandle, sql=SELECT * FROM ZIPCODE, out=WORK.ZIPCODE); &`  , JDBC connection patternClass.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 ;6r   > ;  ,    J  Conclusion  Javaobj opens new horizons Hybrid solutions Combine best features of different technologies Web www.devenezia.com/papers/sesug-2003 d,1$,1$6]  /&'()*+,-. 0 1 2 3 48:<=O#P$Q%S&U'W(Y)x ` ̙33` ` ff3333f` 333MMM` f` f` 3>?" dd@,|?" dd@   " @ ` n?" dd@   @@``PR    @ ` ` p>>  H(    6d { P { T Click to edit Master title style! !  0 {  { RClick to edit Master text styles Second level Third level Fourth level Fifth level!     S  # l%%yd?l|   T%%d?+&Z  B00yd޽h ? ̙33[   P}( Њ@ X@   6 p { T Click to edit Master title style! !  0  `   { W#Click to edit Master subtitle style$ $  # l%%yd?lZ  B00yd޽h ? ̙33V 0 04(  4 4 Ht ?P   { Y*  4 H ?   { [* p 4 0 ?  {. 4 H4 ? @ { RClick to edit Master text styles Second level Third level Fourth level Fifth level!     S 4 H ?`P  { Y*  4 H ?`  { [* H 4 0޽h ? ̙33F @ (    l  C 4p {   Zgֳgֳ ?P   PRichard A. DeVenezia $H  0޽h ? ̙33   p( Њ@0j@ l  C DQP   l  C Q  H  0޽h ? ̙33  ( @ l  C dQP   l  C Q  H  0޽h ? ̙33  ( Ȉ@0h@ l  C QP  { l  C Q { H  0޽h ? ̙33  (  l  C  QP  Q l  C !Q Q H  0޽h ? ̙33  $$(  $r $ S !QP  Q r $ S $"Q Q H $ 0޽h ? ̙33  D$( @ Dr D S D#QP  Q r D S #Q Q H D 0޽h ? ̙33   0$( @ Z@ r  S $QP  Q r  S $%Q Q H  0޽h ? ̙33   PH$( @ Hr H S &QP  Q r H S 'Q Q H H 0޽h ? ̙33   ~pL( @ Lr L S (QP  Q r L S Q Q pB L HD?` vB L ND? vB L ND?`vB L ND? 0H L 0޽h ? ̙33  @( @ @l @ C QP   l @ C dQ  H @ 0޽h ? ̙33  $( @ r  S $QP   r  S Q  H  0޽h ? ̙33  ,$(  ,r , S QP   r , S Q  H , 0޽h ? ̙33  t( w tl t C $QP   l t C Q  H t 0޽h ? ̙33  x$(  xr x S DQP  R r x S Q R H x 0޽h ? ̙33   P$( @ Pr P S QP  R r P S DQ R H P 0޽h ? ̙33  0$( 0~@d r  S QP  R r  S $Q R H  0޽h ? ̙33  P$( ~ r  S RP  R r  S R R H  0޽h ? ̙33  p$(  r  S $RP  R r  S R R H  0޽h ? ̙33 # 4$( T 4r 4 S RP  R r 4 S R R H 4 0޽h ? ̙33 % D$(  Dr D S RP  S r D S R S H D 0޽h ? ̙33 $ <$(  <r < S RP  S r < S dR S H < 0޽h ? ̙33 & L$( P Lr L S RP  S r L S DR S H L 0޽h ? ̙33 ' T$( ~ Tr T S RP  S r T S $R S H T 0޽h ? ̙33 ( 0\$( ܯڣx \r \ S 4SP  S r \ S S S H \ 0޽h ? ̙33 ) Pl(  ll l C tSP  S l l C ԢS   S H l 0޽h ? ̙33  p|( \@d@ |l | C SP  S l | C S S H | 0޽h ? ̙33  $(  r  S TSP  S r  S S S H  0޽h ? ̙33  $(  r  S 4SP  S r  S S S H  0޽h ? ̙33  T$(  Tr T S SP  S r T S TS S H T 0޽h ? ̙33   ($(  (r ( S P  { r ( S  { H ( 0޽h ? ̙33f 0 &`8(  8R 8 3 4   $ 8 C Q4 @   Hello, I am Richard DeVenezia and I will be your javaobj guide for the next hour. First, by a show of hands, how many people have used java and / or java objects in SAS before.H 8 0޽h ? ̙33^ 0 (  R  3 4   Q  C D Q4 @  Q >Type: Number Char JavaObj Hash HIter - hash iterator$?6  H  0޽h ? ̙33  0 |t  ( (Ɉaa, R  3 4   Qz  C d$Q4 @  Q This is a pattern very familiar to java programmers who develop javabeans. Rarely if ever would a class have public fields. The bean pattern uses methods known as getters and setters to access the fields and is tailored for integration with advanced GUI development tools. Coding patterns are a matter of personal style, but are sometimes dictated to you by management. Whatever the situation, consistency of style makes dealing with large amounts of code easier.,@ ]%H  0޽h ? ̙33  0 ](  @~@ R  3 4     C DQ4 @   kWInternalizing the correspondence between the Java class pattern and the javaobj patternH  0޽h ? ̙339 0 ( ; R  3 4     C Q4 @   Class is HelloSAS Constructor is public method with same name as Class public methods can be run from any instance of class public H  0޽h ? ̙33 0 *(  R  3 4     C dQ4 @   8$If you edit a java source and recompile it, after the class has been used during a SAS session, then SAS must be restarted to recognize the changed class. This  problem can occur early in the development cycle, during a debugging cycle or during a rapid enhancement cycle.H  0޽h ? ̙33f 0 &(  @~@ R  3 4   Q$  C "Q4 @  Q |- Location can be a folder or jar file. Jar can be thought of as a special or compressed folder that exists within a single file. Jars can contain any type of file, including other jars. The CLASSPATH can list multiple locations by separating them with semicolons. The order listed is the order searched when java looks for classes (important if a class is in more than one jar (I.e. you might list development in front of a production jar when working on a class) The concept of a SAS catalog is similar to a one-level jar, something that contains other things. All the object in the ava Runtime Library are implicitly available,9*H  0޽h ? ̙33h 0 ( (  @~@ R  3 4   Q&  C d!Q4 @  Q There are a multitude of java development tools out there, including SAS Web/AF, but for javaobj programming you might do fine with the freely available software development kit.H  0޽h ? ̙33 0 G(  R  3 4     C $Q4 @   UAJavaobj is not available to the macro facility not to SAS/AF SCL.H  0޽h ? ̙33c  0 #`( @ Z@ R  3 4   Q!  C 'Q4 @  Q  Pattern Types: String = Char, Double = Numeric, Object = javaobj of same Class Correspondence Signature of invocation (SAS) must match signature of declaration (Java) Errors Class not found, constructor signature mismatch or exception thrown ERROR: An error has occurred during class method OM_NEW(3) of "DATASTEP.JAVAOBJ". Method not found or signature mismatch ERROR: Could not find method getLastName at line 4 column 3. ERROR: An error has occurred during instance method OM_CALLSTRINGMETHOD(3278) of "DATASTEP.JAVAOBJ". D`'`GICR'H  0޽h ? ̙33J 0  @(  X  C 4   Q  S %Q4 @  Q If java class Z is in a package A.B.C, the class in the declare statement is  A/B/C/Z . Each entry specified in the CLASSPATH is searched for relative path A/B/C, first one found is instantiated.H  0޽h ? ̙336  0 (  R  3 4   Q  C DQ4 @  Q * Type is one of Void, Double, String, Boolean, Short, Byte, Long, Float, Int. Except for String, the Type corresponds to Java primitive types and not their analog object versions. obj is a SAS variable of type JavaObj return is a SAS variable of type character or numeric, objects can not be returned. Type can also be static Type ... in which case access is obj.callStatic& or obj.[get|set]StaticTypeaL"9  Jj  H  0޽h ? ̙33 0 j(  R  3 4     C Q4 @   xBIf you don t know what java is you may have been living under a rock for the last few years. The foundations of java are very much like the foundations of SAS. q,H  0޽h ? ̙33  0 \T (  R  3 4   RZ  C dQ4 @  R What happens to javaobjs when a DATA Step ends ? Do they live on ? No. You must be careful to delete javaobjs, especially if you utilize them heavily. If you don t your SAS session may run into memory usage problems.,MmH  0޽h ? ̙33  0 og(  R  3 4   Sm  C S4 @  S Tha pattern is the typical code sequence you would find in any Java class making a connection to a database through JDBC The driver, org.postgresql.Driver, is a class found in a jar that is listed in the SAS session CLASSPATH The url is a special construct specific to the postgres driver. It contains the host and port to connect to as well as the database name The user and password correspond to a user in the database.H T' H  0޽h ? ̙33  0 RJ`(  L| X  C 4   RJ  S R4 @  R JDBC driver classes implement standard methods that to provide access to database. A Java class that works with databases does not have to be changed when connecting to a different database; only the connection parameters need to be changed (parameters can be often specified in a login dialog or configuration file, should not be hard-coded). A JDBC driver is implemented in or more Java classes and is most often deployed or distributed as one or more jar files.H  0޽h ? ̙33! 0 wo(  ? X  C 4   Ro  S R4 @  R RMI stands for remote method invocation; allowing a class or object in one VM interact with a class or object in a different VM . A wrapper class is one that perform java related tasks that SAS javaobj cannot. Such as dealing with an object returned from a method. Another case for needing a wrapper is when a java method requires a type that SAS cannot provide. SAS can only pass strings and doubles; so when a method needs something other than a double, you will need to write a wrapper class to allow the javaobj to perform the task at hand. The wrapper class would perform the necessary type casting to convert a double to an int, long, float, etc... Remember, a javaobj can only be created by using the new operator.wYH  0޽h ? ̙33E" 0 @( ? X  C 4   R  S R4 @  R EConsider the case when you want to create a SAS data set from a query on a remote database. Moving query results into a SAS table requires two steps Step One build a statement that defines the columns and types; Step Two read the results into the columns. Since we are using javaobj, this task requires two data steps, and oops would require the one query be executed two times on the remote system. Not good. If the query results could be made to persist somewhere between the DATA Steps, then the query has to be issued only one time. This is the case for finding that somewhere.6F 6 iH  0޽h ? ̙33 0 x(  R  3 4   S~  C tS4 @  S  H  0޽h ? ̙33# 0 8>(  8X 8 C 4   R 8 S dR4 @  R @Why the term gateway ? Think of a manned gate in a fence, to pass from one side to the other you need to pass through the gate. Where you are coming from and where you are going is of no concern to the gate. The gatekeepers only concern is that your credentials are verified before allowing passage. Concerns of and alternatives to this access model will not be discussed. The gateway is an RMI scheme involving a server process and a bound manager class that lives in the server process. A Java class operating in a client mode obtains a reference to the remote manager by looking up (within the rmiregistry executor process) the instance that is bound to name JDBC-GATEWAY-MANAGER. The manager class hands out integer handles to objects it instantiates and stores in hash tables (keyed by handle). The manager class has methods for connecting to a database, creating a SQL statement, executing a SQL statement and examing returned Result Sets. Each method requires a handle originally doled out.>U  KH 8 0޽h ? ̙33$ 0 ~@(  @X @ C 4   S~ @ S R4 @  S If you wanted to expand the gateway to have more functionality, you would list additional methods here and implement them in GatewayManager. You would also have to implement adapter versions in DataStepGatewayAdapter$|6H @ 0޽h ? ̙337% 0 H( @ HX H C 4   S H S DR4 @  S uOutside scope to get into great detail, numerous RMI informational sites on the web, some are mentioned in the paper.H H 0޽h ? ̙33& 0 P<(  PX P C 4   S P S R4 @  S >This class implements the methods listed in the interface. This is where the bulk of the work takes place. The manager instantiates objects as requested and places them in a hash keyed by an Integer (the handle). The integer is returned to the client who must pass it back in order to operate upon the object associated with the handle. The manager is essentially an adapter to parts of java.sql class for systems unable to fully expose the java experience.$?,v ?H P 0޽h ? ̙33' 0 og X(  XX X C 4   Sg X S tS4 @  R This class is run to persist a GatewayManager. Java security settings, which will not be discussed, can be placed on the running of this class to restrict the resources it uses. Clients wishing to use the GatewayManager have to look up the name JDBC-GATEWAY=MANAGER in the rmiregistry. There SAS macros that can be used to start a server during a SAS session. There server is designed as a low-browsystemP5 o H X 0޽h ? ̙33\( 0 @`( s,䫈 `X ` C 4   S ` S S4 @  S This is a static method of the server class and is a convenience to clients. It allows a system to start the server process followed by a client process.H ` 0޽h ? ̙33* 0 UM`p(  pR p 3 4   SS p C 4S4 @  S The adapter was written to let javaobjs to interact with the GatewayManager. All the methods have numeric arguments as double, the only numeric type javaobj can pass to java object methods. The adapter adds one method, getSasColumnType, which is not declared in GatewayInterface. The method maps the variety of remote database types to the fundamental SAS data types of character or numeric.P rH p 0޽h ? ̙33rWY`jpnlrft4:dp Rv*z|xH%ԁͲ^ο>x87pPE<dL0(wؘĚap\b^Oh+'0 hp    $,No Slide TitleRichard A. DeVeneziaPRichard A. DeVeneziaP39hMicrosoft PowerPointP@4}@0p&!@ ч`@ֵD GoM   .& &&#TNPP0{ & TNPP &&TNPP    &&--&&//- $0Z//- $Z..- $>--- $>h,,- $h++- $L))- $Lv''- $v%%- $Z*""- $*Z - $- $h8- $8h- $- $vF- $Fv&&&- & $&&-&& &&-&&&&//- $0Z//- $Z..- $>--- $>h,,- $h++- $L))- $Lv''- $v%%- $Z*""- $*Z - $- $h8- $8h- $- $vF- $Fv&- --&&&&--&&- $nR- $R- $e- $eI- $I - $ [- $[@- $@ - $R!!- $R6""- $6##- $I##- $I-$$- $-$$- $@$$- $@$&&&- & $&&-&& &&-&&&&- $nR- $R- $e- $eI- $I - $ [- $[@- $@ - $R!!- $R6""- $6##- $I##- $I-$$- $-$$- $@$$- $@$&- --&&--yyH--j}w@D }ww0- Times New Roman}ww0- .+2 "Greetings from the Edge:*.$. ..2 iUsing javaobj in DATA Step***$*!.--8-- Times New Roman}ww0- .%2 Richard A. DeVenezia  #  .--"System 0-&TNPP &ri՜.+,D՜.+,t    On-screen Showo -sK1 #Times New Roman Courier NewCourierDefault Design4Greetings from the Edge: Using javaobj in DATA Step Java is ...javaobj is ...Component Interface is ...Java development SAS sessionJava coding patternDeclare statement SignatureAccessing methods and fieldsHelloSAS.java HelloSAS.sasGotchasExample 8 - EnumerationExample 8 - DATA StepObject PersistenceA Case for Persistence DatabasesPersistence == RMI Gateway - an RMI SchemeGateway ImplementationGatewayInterfaceGatewayManagerGatewayServerGatewayServerDataStepGatewayAdapter SAS MacrosUsing the macrosUsing the macrosJDBC connection pattern Conclusion  Fonts UsedDesign Template Slide Titles 6> _PID_GUIDAN{F697EF10-2942-4872-B12A-C044BCE3A822}Root EntrydO)9,@Current User4SummaryInformation(PowerPoint Document(,_rRichard A. DeVeneziaRoot EntrydO)`T,@Current User4SummaryInformation(PowerPoint Document(,_rRichard A. DeVenezia  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~Root EntrydO)Current UserSummaryInformation(PowerPoint Document(DocumentSummaryInformation8