|
|
|
Business Object |
BAPI |
Description |
|
Z_BAPI_GET_DOCUMENT_ID |
GETDOCUMENT |
Gets the document ID |
|
|
|
Input: Company code |
|
|
|
Invoice number |
|
|
|
Financial year |
|
|
|
Output: Document ID |
|
|
GETAPPENDIX |
Gets the document appendix ID |
|
|
|
Input: Company code |
|
|
|
Invoice number |
|
|
|
Financial year |
|
|
|
Output: Document appendix ID |
A SessionBean has been implemented for contacting this object. The bean contains the method getDocid(), which returns the IDs as described in figure 3.
|
/** * Getting Document-ID, Document-Appendix-ID from SAP/R3 by invoice number * @return Document-ID */ public String getDocid() { String sDocid = ""; JCO.Client jcoConnection = null; IRepository repository = null; // getting properties try { String sClient = vrb.getString("client",""); // client String sUserid = vrb.getString("userid",""); // userid String sPassword = vrb.getString("password",""); // password String sLanguage = vrb.getString("language",""); // language String sHost = vrb.getString("host",""); // host String sSysnr = vrb.getString("sysnr",""); // system number String sBukrs = vrb.getString("buchungskreis",""); // account number String rgID = ""; // SAP-login jcoConnection = JCO.createClient(sClient,sUserid,sPassword,sLanguage,sHost,sSysnr); jcoConnection.connect(); // building repository repository = new JCO.Repository("ASG", jcoConnection); // executing BAPI // Document JCO.Function bapiDocument = repository. getFunctionTemplate("Z_BAPI_TOA02_GETDOCUMENT").getFunction(); if (bapiDocument != null) { jcoConnection.execute(bapiDocument); JCO.ParameterList input = bapiDocument.getImportParameterList(); input.setValue(sBukrs,"BUKRS"); // accounting area input.setValue(sBelnr,"BELNR"); // invoice number input.setValue(sGjahr,"GJAHR"); // financial year jcoConnection.execute(bapiDocument); JCO.ParameterList output = bapiDocument.getExportParameterList(); if (output != null) { JCO.Structure structure = output.getStructure("DOCUMENT"); sDocid = structure.getString("DOC_ID"); sArchivid = structure.getString("ARCHIV_ID"); } } // Appendix if (!sDocid.equals("")) { JCO.Function bapiAppendix = repository. getFunctionTemplate("Z_BAPI_TOA02_GETAPPENDIX").getFunction(); if (bapiAppendix != null) { jcoConnection.execute(bapiAppendix); // Input Parameter JCO.ParameterList input = bapiAppendix.getImportParameterList(); input.setValue(sBukrs,"BUKRS"); // accounting area input.setValue(sBelnr,"BELNR"); // invoice number input.setValue(sGjahr,"GJAHR"); // financial year jcoConnection.execute(bapiAppendix); JCO.ParameterList output = bapiAppendix.getTableParameterList(); JCO.Table table = output.getTable(0); if (table != null) { if (table.getNumRows() > 0) { do { for (JCO.FieldIterator e = table.fields(); e.hasMoreElements(); ) { JCO.Field field = e.nextField(); if (field.getName().equals("ARCHIV_ID")) sAnlagearchivid = field.getString(); else if (field.getName().equals("DOC_ID")) sAnlagedocid = field.getString(); } } while(table.nextRow()); } } } } } catch (Exception e) { e.printStackTrace(); } finally { if (jcoConnection != null) jcoConnection.disconnect(); } this.sDocid = sDocid; return sDocid; } // ---------------------------------------------------------------------------------- |
If you want to install the SAP Java Connector as a standalone component, you can download the installation files from SAPNet at service.sap.com/connectors. This section contains the most important guidelines for installation. Note the additional information on the download page in SAPNet.
SAP JCo 2.0 JDK version 1.2 or higher. If you still need JDK 1.1, continue to use SAP JCo 1.1 (1.1.04 or higher).
The following instructions apply for Windows32 operating systems. The instructions for the installation of SAP JCo on other operating systems are included in the corresponding download files.
1.
1. Create a directory, for example C:\\SAPJCo, and extract the JCo .zip file into this directory.
2. Copy the file librfc32.dll from your SAP JCo main directory to C:\WINNT\SYSTEM32, as long as the version that is already there is not a more recent version than the one that is delivered with the SAP JCo.
3. Make sure that the file sapjco.jar (in the SAP JCo main directory) is contained in the class path for all projects for which you want to use the SAP JCo..
For productive operation, the following files from the SAP JCo .zip file are necessary:
1. sapjco.jar
2. librfc32.dll
3. sapjcorfc.dll
In addition, the download .zip file contains the following directories:
1. The docs directory, which contains the Javadocs for SAP JCo. The Javadocs contain an overview of all SAPJCo classes and interfaces, and a detailed description of the corresponding objects, methods, parameters, and fields. Start with the file index.html (<drive>:\<SAPJCo>\docs\jco\index.html).
2. The demo directory, which contains some example programs, including the examples described in the section SAP JCo Programming .
The only difference between the prerequisites for installation of SAP JCo 2.1 and release 2.0 is the required JDK version: for SAP JCo 2.1 you required the JDK 1.3 or higher.
The procedure for the installation of SAP JCo release 2.1 is identical to the procedure described above for release 2.0.
SAP JCo release 2.1 offers the following new functions:
1. You can use a connection for DSR (Distributed Statistic Record). This function requires that you have implemented CCMS Monitoring (Computing Center Management System) .
2. SAP code pages are used with JCo 2.1, which therefore guarantees complete conversion of characters for all languages used by SAP.
The following table provides an overview of the main elements of client programming when using the SAP JCo as a standalone component:
|
Activity |
Section |
|
Creating direct connections or connection pools |
|
|
Creating a JCo repository, mapping ABAP and Java data types, accessing tables |
|
|
Access to tables and navigation in tables |
|
|
Generic processing of fields |
|
|
Optimizing performance by deactivating non-essential BAPI parameters |
|
|
Configuring error handling in SAP JCo |
|
|
Synchronizing object access to optimize performance |
|
|
Quick parameter check using the method writeHTML() |
For an overview of all SAP JCo classes, objects, methods, parameters, and fields, see the Javadocs. These HTML files are available in the docs directory of the SAPJCo installation.
There are two possible programming models for using SAP JCo to connect to an SAP server: Direct Connections and Connection Pools.
Direct connections can be opened and maintained for as long as necessary.
A connection pool makes a connection available on demand. As soon as a connection becomes free and is released back into the connection pool, it can be assigned to another user.
These models can be implemented in parallel in an application. You should always use pools for creating Web server applications, and connection pools can also be useful for desktop applications.
For more information on establishing connections to an SAP server, see:
1. · Direct Connections
2. · Connection Pools
The following section describes an example program for creating a direct connection. For the complete program, see Example Program Connect1.
2. ...
4. For establishing direct connections, you need the following classes:
l JCO: This is the main class of the SAPJCo. It contains many useful static methods.
l JCO.Client: This class represents a connection to the SAP server.
l JCO.Attributes: These classes contain the attributes of a connection, for example, the release of the SAP system.
5. In addition, each program that the SAP JCo uses contains the import statement displayed below. If this was not the case, you would have to qualify all the JCo classes and interfaces individually.
6. You then define a connection variable for contacting a specified client of the SAP system.
7.
|
JCO JCO.Client JCO.Attributes |
|
import com.sap.mw.jco.*; |
|
JCO.Client mConnection; |
For information on further procedures, see:
2. Calling a Function and Closing a Connection
3. Result of the Function Call
The complete example program for establishing a direct connection:
To instantiate JCO.Client objects, you do not use a Constructor. Instead, you use the createClient() method of the class JCO. Several versions of this method must be supported:
Connections to a specific application server
Connections to a Load Balancing server group
Connections that are based on the information in the java.util.Properties object. This is particularly useful to avoid hard-coded system and user information in the Java code.
Additional versions are described in the Javadocs .
The example illustrated below shows the version for “connections to a specific application server”. Creating the JCO.Client object does not create a connection to the SAP Server. This occurs using the subsequent call connect().
|
// Change the logon information to your own system/user mConnection = JCO.createClient (“001“, // SAP client “<userid>“, // userid “****“, // password “EN“, // language (null for default language) “<hostname>“ // application server host name “00“); // system number |
|
Try { mConnection.connect (); } catch (Exeption ex) { ex.printStackTrace (); System.exit (1) } |
For information on further procedures, see:
1. Calling a Function and Closing a Connection
2. Result of the Function Call
The complete example program for establishing a direct connection:
The following describes how to call a function in an SAP server. This is illustrated using a simple example, in which the RFC attributes of the connection are queried. The relevant coding is displayed in the diagram (calling a function). To close a connection, choose
mConnection.disconnect();
Unlike in connection pools, for direct connections it is not recommended to call a function and then close the connection immediately afterwards (until the next function call).A direct connection should only be closed if no activity is expected for a long period of time.
|
System.out.println (mConnection.getAttributes () ); |
|
mConnection.disconnect (); |
For information on further procedures, see:
1. Result of the Function Call
The complete example program for establishing a direct connection:
The result of the example above should look as follows:
If you cannot successfully execute this example program, ensure that the system and user information contains the correct values. Also check that the Class Path contains the SAP JCo directory and the actual example program. If it still does not work, there may be a network or configuration problem. If this is the case, inform your SAP Basis administrator.
For the complete example program for establishing a direct connection, see:
|
import com.sap.mw.jco.*; public class TutorialConnect1 extends Object { JCO.Client mConnection; public Connect1() { try { // Change the logon information to your own system/user mConnection = JCO.createClient("001", // SAP client "<userid>", // userid "****", // password null, // language "<hostname>", // application server host name "00"); // system number mConnection.connect(); System.out.println(mConnection.getAttributes()); mConnection.disconnect(); } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } } public static void main (String args[]) { Connect1 app = new Connect1(); } } |
If you use generic user names to log on to the SAP server (which is normally the case for Web server applications), it is advisable to use connection pools, because all connections in a pool contain the same system, user, and client information. Connection Pools have two distinct advantages compared with direct connections:
1. You avoid overhead in the SAP application because the connection remains open and can be reused as soon as one successful logon has taken place.
2. You can restrict the maximum number of concurrent logons and thus avoid consuming too many SAP system resources.
The example coding below lists the connection attributes exactly as in the section Direct Connections , except that in this case, connection pools are used. For the complete example program for establishing a connection pool, see:
3. ...
8. First, you need the following specific classes:
l JCO.Pool: This class represents a connection pool
l JCO.PoolManager: All connection pools within a Java Virtual Machine (JVM) are administrated here.
9. Choose a pool name. In SAP JCo, you can use pool names of your choice. However, because pools are valid globally within a JVM, you should use a specific naming standard if different applications are running on the same JVM.
10. The global JCO.PoolManager object administrates all pools and can be called using the method getClientPoolManager() of the class JCO. The method getPool() attempts to call a particular pool (name). If no pool exists with the specified name (return value null), a new pool is created.
|
JCO.Pool JCO.PoolManager |
|
static final String POOL_NAME = “Pool“; |
|
JCO.Pool pool = JCO.getClientPoolManager ().getPool (POOL_NAME); if (pool == null) { |
For information on further procedures, see:
2. Acquiring and Releasing a Connection
The complete example program for creating a connection pool:
To create a new connection pool, use the method addClientPool(). The maximum number of defined connections cannot be increased. You should therefore choose a value that is sufficiently large for the application. Multiple versions of addClientPool() enable you to define the logon information in different ways. The example below uses a properties object, which is created from a file that uses a utility class with the name OrderedProperties (subclass of Properties). The diagram below shows the example file logon.properties.
|
OrderedProperties logonProperties = OrderedPropertiess.load (“/logon.properties“); JCO.addClientPool (POOL_NAME, // pool name 5, // max. number of connections logonProperties); // properties |
|
jco.client.client=001 jco.client.user=userid jco.client.passwd=**** jco.client.ashost=hostname jco.client.sysnr=00 |
For information on further procedures, see:
1. Acquiring and Releasing a Connection
The complete example program for creating a connection pool:
To create a new connection pool, use the method addClientPool(). The maximum number of defined connections cannot be increased. You should therefore choose a value that is sufficiently large for the application. Multiple versions of addClientPool() enable you to define the logon information in different ways. The example below uses a properties object, which is created from a file that uses a utility class with the name OrderedProperties (subclass of Properties). The diagram below shows the example file logon.properties.
|
OrderedProperties logonProperties = OrderedPropertiess.load (“/logon.properties“); JCO.addClientPool (POOL_NAME, // pool name 5, // max. number of connections logonProperties); // properties |
|
jco.client.client=001 jco.client.user=userid jco.client.passwd=**** jco.client.ashost=hostname jco.client.sysnr=00 |
For information on further procedures, see:
1. Acquiring and Releasing a Connection
The complete example program for creating a connection pool:
4. ...
11. 1. If you need a current connection from the connection pool, you can acquire this, execute one or more function calls in the SAP server, and then return (release) the connection to the connection pool. The method getClient() is used to acquire a connection.
12. 2. If all connections in a pool are assigned and the pool has reached its maximum size, SAP JCo waits for a defined period of time (default value: 30 seconds). If no connection becomes available within this time period, an Exception Message (JCO.Exception.JCO_ERROR_RESOURCE.) is output.
13. 3. After a successful function call, the connection to the method releaseClient() is released back into the pool.
14. 4.
|
mConnection = JCO.getClient (POOL_NAME); |
|
System.out.println (mConnection.getAttributes () ); } catch (Exception ex) { ex.printStackTrace (); } finally { JCO.releaseClient (mConnection); } |
For the complete example program for establishing a connection pool, see:
|
import com.sap.mw.jco.*; public class Connect2 extends Object { static final String POOL_NAME = "Pool"; JCO.Client mConnection; public Connect2() { try { JCO.Pool pool = JCO.getClientPoolManager().getPool(POOL_NAME); if (pool == null) { OrderedProperties logonProperties = OrderedProperties.load("/logon.properties"); JCO.addClientPool(POOL_NAME, // pool name 5, // maximum number of connections logonProperties); // properties } mConnection = JCO.getClient(POOL_NAME); System.out.println(mConnection.getAttributes()); } catch (Exception ex) { ex.printStackTrace(); } finally { JCO.releaseClient(mConnection); } } public static void main (String args[]) { Connect2 app = new Connect2(); } } |
The SAP Java Connector must be able to access the metadata of all Remote Function Modules (RFMs) that are to be used by a Java client. A JCO.Repository object is created to do this. The current metadata for the RFMs is retrieved dynamically from the SAP server at runtime.
For more detailed information on the SAP JCo Repository, see:
Creating a JCO.Function Object
Mapping of Java and ABAP Data Types
Setting Scalar Import Parameters
For a complete example program for creating a JCo repository and executing BAPIs, see:
In many applications it is not sufficient to be able to access table fields or navigate through a table, you also often need to add or delete rows. SAP JCo provides methods that enable you to do this. Normally, you add rows for table parameters that are sent to the SAP server (for example, adding items to a customer order). This example uses the table returned by the BAPI CompanyCode.GetList.
1. If the method deleteRow() is called without parameters, it deletes the current row. If you define a row number, the corresponding row is deleted.
2. The method appendRow() adds a row at the end of the table. If you want to append multiple rows simultaneously, you can specify an integer argument. This leads to better performance than with adding rows individually.
3. The method insertRow(int) inserts a row at any position in the table.
4. The method deleteAllRows() deletes all rows of a table.
For an example program containing some of these methods, see:
The following table summarizes the JCO.Table methods that are not contained in JCO.Structure.
|
import com.sap.mw.jco.*; public class Bapi2 extends Object { JCO.Client mConnection; JCO.Repository mRepository; public TutorialBapi2() { try { // Change the logon information to your own system/user mConnection = JCO.createClient("001", // SAP client "<userid>", // userid "****", // password null, // language "<hostname>", // application server host name "00"); // system number mConnection.connect(); mRepository = new JCO.Repository("ARAsoft", mConnection); } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } JCO.Function function = null; JCO.Table codes = null; try { function = this.createFunction("BAPI_COMPANYCODE_GETLIST"); if (function == null) { System.out.println("BAPI_COMPANYCODE_GETLIST" + " not found in SAP."); System.exit(1); } mConnection.execute(function); JCO.Structure returnStructure = function.getExportParameterList().getStructure("RETURN"); if (! (returnStructure.getString("TYPE").equals("") || returnStructure.getString("TYPE").equals("S")) ) { System.out.println(returnStructure.getString("MESSAGE")); System.exit(1); } codes = function.getTableParameterList().getTable("COMPANYCODE_LIST"); codes.setRow(2); codes.deleteRow(); codes.deleteRow(5); codes.appendRow(); codes.setValue("XXXX", "COMP_CODE"); codes.setValue("Does not exist", "COMP_NAME"); codes.appendRows(2); codes.setValue("YYYY", "COMP_CODE"); codes.setValue("Does not exist either", "COMP_NAME"); codes.nextRow(); codes.setValue("ZZZZ", "COMP_CODE"); codes.setValue("Nor does this", "COMP_NAME"); for (int i = 0; i < codes.getNumRows(); i++) { codes.setRow(i); System.out.println(codes.getString("COMP_CODE") + '\t' + codes.getString("COMP_NAME")); } } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } try { codes.firstRow(); for (int i = 0; i < codes.getNumRows(); i++, codes.nextRow()) { function = this.createFunction("BAPI_COMPANYCODE_GETDETAIL"); if (function == null) { System.out.println("BAPI_COMPANYCODE_GETDETAIL" + " not found in SAP."); System.exit(1); } function.getImportParameterList(). setValue(codes.getString("COMP_CODE"), "COMPANYCODEID"); mConnection.execute(function); JCO.Structure returnStructure = function.getExportParameterList().getStructure("RETURN"); if (! (returnStructure.getString("TYPE").equals("") || returnStructure.getString("TYPE").equals("S") || returnStructure.getString("TYPE").equals("W")) ) { System.out.println(returnStructure.getString("MESSAGE")); } JCO.Structure detail = function.getExportParameterList(). getStructure("COMPANYCODE_DETAIL"); System.out.println(detail.getString("COMP_CODE") + '\t' + detail.getString("COUNTRY") + '\t' + detail.getString("CITY")); } } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } mConnection.disconnect(); } public JCO.Function createFunction(String name) throws Exception { try { IFunctionTemplate ft = mRepository.getFunctionTemplate(name.toUpperCase()); if (ft == null) return null; return ft.getFunction(); } catch (Exception ex) { throw new Exception("Problem retrieving JCO.Function object."); } } public static void main (String args[]) { Bapi2 app = new Bapi2(); } } |
Fields can occur in different contexts: structures and table rows contain fields, and scalar parameters are fields. The previous sections describe how each class supports methods for accessing or changing the content of a field. Because fields in different contexts have some common features, SAP JCo provides the class JCO.Field , which enables generic editing of fields.
The classes JCO.Structure, JCO.Table, and JCO.ParameterList all contain a getField() method for accessing a field. The class JCO.Field itself contains all the getter and setter methods described in previous sections. This level of abstraction can be very useful if you want to create generic methods for editing fields, independently of the origin of the fields. A field of the class JCO.Field has metadata such as
1. · Name (method getName())
2. · Description (method getDescription())
3. · Data type (method getType())
4. · Length (method getLength()), and
5. · Number of decimal places (method getDecimals())
A field can also contain extended metadata, which you can access using the method getExtendedFieldMetaData().
The previous sections have described the principles for working with parameters. You know how to access a structure, a table, and scalar parameters, and you are familiar with the class JCO.Field. This section contains further advice for optimizing performance:
|
function.getExportParameterList(). setActive(false, "COMPANYCODE_ADDRESS"); |
For exception handling, you need the following classes:
1. JCO.Exception: This is the basis class for exceptions.
2. JCO.ConversionException: Subclass for conversion errors.
3. JCO.AbapException: Subclass for exceptions that are thrown in the RFM .
SAP JCo throws exceptions as a subclass of RuntimeException. Runtime Exceptions should not be integrated or defined in the signature of the method. There can be advantages to doing this, but it is also dangerous. Local error handling is less problematic because the program still knows in which context the error has occurred. SAP therefore recommends that you always use try/catch in the code, even if the compiler does not display this.
SAP JCo also provides three exception types: JCO.Exception and two subclasses, which you can call separately if necessary. JCO.Exception also provides a getGroup() method, which you can use to distinguish between different error types. For a list of the groups, see the corresponding Javadoc in the installation directory docs.
JCO.ConversionException is always thrown if you call a getter or setter method that requests a conversion, and this conversion fails.
JCO.AbapException occurs if the ABAP code that you have called throws an exception. The diagram below shows how you can distinguish between different error types (the example shows the use of the DDIF_FIELDINFO_GET, which can be used to query structure metadata or table metadata. If an invalid name is transferred, this RFM throws the exception NOT_FOUND):
|
catch (JCO.AbapException ex) { if (ex.getKey().equalsIgnoreCase("NOT_FOUND")) { System.out.println("Dictionary structure/table not found."); System.exit(1); } else { System.out.println(ex.getMessage()); System.exit(1); } } catch (JCO.Exception ex) { ex.printStackTrace(); System.exit(1); } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } |
There are three “catch” clauses:
1. In the first catch clause you use the method getKey(), to access the exception string returned by the SAP system. If this is NOT_FOUND, a specific text is output, for all other exceptions, use getMessage() to generate a suitable text. In this way you can distinguish between different ABAP exceptions that you want to handle in a specific way, and all others that are handled generically. Because all exception strings are defined in SAP, you already know them in advance.
2. The second catch clause refers to all other JCo-relevant problems. These include conversion errors and other errors that occur in SAP JCo.
3. The third clause refers to all other exceptions that may have occurred in your code.
Note that this is also an example description. Depending on the concrete requirements of your code it can also be necessary to adjust the error handling.
To further optimize performance, SAP JCo itself synchronizes access to JCO.Pool and JCO.Repository objects. No other access to objects is synchronized.
In a multi-thread environment, distribution of objects (for example, JCO.Table objects) between different threads must be implemented carefully. Do not use JCO.Client objects that have been requested by a connection pool in any other thread. Also note that it is not possible to make multiple concurrent SAP calls for the same direct connection.
When you carry out debugging in an application, it is often advantageous to perform a quick check of the parameters that are transferred to and from SAP. SAP JCo provides the method writeHTML() for performing these checks. You can use this method to create an HTML file based on an object of the types.
1. JCO.Function
2. JCO.ParameterList
3. JCO.Structure, or
4. JCO.Table
For tables, the default setting only includes the first 100 rows of the table. This saves space and avoids very large HTML files which may cause the browser to crash. If you want to output more rows, you can set the parameter jco.html.table_max_rows to control the maximum number of rows. The following diagram shows some example code:
|
JCO.Function function = mRepository.getFunctionTemplate("BAPI_COMPANYCODE_GETLIST"). getFunction(); mConnection.execute(function); JCO.Table codes = function.getTableParameterList().getTable("COMPANYCODE_LIST"); String oldMaxRows = JCO.getProperty("jco.html.table_max_rows"); JCO.setProperty("jco.html.table_max_rows", "99999"); codes.writeHTML("c:\\COMPANYCODE_LIST.html"); JCO.setProperty("jco.html.table_max_rows", oldMaxRows); |
The example code saves the old parameter value before it is changed. After writeHTML() is called, you can reactivate the old value so you do not affect other users (this parameter is global within the Java Virtual Machine ).
The SAP Java Resource Adapter (SAP JRA) is a J2EE -compatible connector for SAP systems. It enables the integration of SAP systems with J2EE application servers. The SAP JRA implements the standard J2EE interfaces for the SAP Java Connector (SAP JCo), thus simplifying communication between heterogeneous, distributed J2EE landscapes and SAP.
You can use the SAP JRA to call remote functions of an SAP system by executing RFC calls via TCP/IP.
The SAP JRA is an add-on for the SAP JCo. If you use the SAP
SAP JRA is supplied as the file sapjra.rar, which is implemented on the application server. The .rar file contains the Java classes and their user documentation.
The J2EE Connector Architecture specifications 1.0 are currently implemented. For more information on J2EE and the J2EE Connector Architecture, go to java.sun.com/j2ee.
The SAP JRA does not support inbound communication, tRFC, IDocs, or certificates .
2. SAP JRA: FAQ
In the Business Intelligence (BI) area, SAP offers various resource adapters that can be used with the BI Java SDK. These enable the applications that you develop with the BI Java SDK to communicate with heterogeneous data sources.
The SAP JRA is based on the
This section describes the basic properties of the SAP Java Resource Adapter, giving answers to frequent questions:
Can the SAP JRA be used with every J2EE Application Server?
What restrictions does the SAPJRA 1.0 have?
Does the SAPJRA support the Common Client Interface (CCI) ?
What types of functions can be called?
Does the SAPJRA need additional libraries ?
Is the SAPJRA 100% pure Java ?
Is the SAPJRA visible for the user ?
Does the SAPJRA support connection-pooling?
Does the SAPJRA support connection-sharing ?
Does the SAPJRA support re-authentication of connections ?
Does the SAPJRA support XA-based transactions (XAResource)?
Does the SAPJRA support local transactions ?
Does the SAPJRA support authentication using Subjects (JAAS) ?
What should you not do?
SAPJRA was tested on SAP J2EE Engine and on the SUN Reference Implementation Application Server. It passed all J2EE Specification Compliance tests.
2-phase commit and re-authentication are not supported by SAP, so they are not supported by SAP JRA either.
Yes. Here are some details of the implementation:
MappedRecords, but not the IndexedRecords are supported. For calls please use the method execute(interactionSpec, input). The method execute(interactionSpec, input, output) is not implemented.
The input parameter in the method execute(interactionSpec, input) should be of type MappedRecord. The return Object in this method is of type MappedRecord too. For interactionSpec pass null, since it doesn’t affect the execute.
ResultSets represent tables. MappedRecord represent structures. MappedRecords and ResultSets may contain inner ResultSets and MappedRecords. To retrieve/set ResultSet, MappedRecord or BigInteger instances from/to MappedRecords use methods get(…)/ put(…). To retrieve/set them from/to ResultSet use methods getObject(…)/updateObject(…).
Please see FAQ Does the SAP JRA support local transactions?
Yes, the SAP JRA is based on the SAP Java Connector 2.x (SAP JCo 2.x). On SAP J2EE Engine all needed libraries are already provided.
Although the SAP JRA itself is 100% pure Java, the SAP JCo is not. The native libraries of the SAP JCo are available for several operating systems.
Only an optional class ConnectionSpecImpl, which serves for passing additional properties to login into SAP, and one optional interface ResultMap, which offers additional functions to process SAP Meta Data are visible. All other classes are not visible for the user. The goal is to call SAP functions only by using the Java standard interfaces of the J2EE Connector Architecture.
Yes.
Yes. Note, that a connection may only be shared by the Application Server within the same transaction.
No, because the SAP system does not support re-authentication.
No, because the SAP system does not support a 2-phase commit.
Yes, but the following rule must be kept:
When using the transaction management of the SAP JRA, no remote functions, which execute database statements directly (call COMMIT WORK) instead of using the update process, should be called. Since release 4.0 BAPIs don’t execute database statements directly and let the application doing or not doing this. For a few exclusions please see the note 131838. BAPIs mentioned in this note should not be called. You can write your own BAPIs in ABAP.
Designing your own BAPIs all writing of database statements should be done in the update task (i.e. following statement in your BAPI coding: call function ‘my_updating_function’ in update task). Only in this case the J2EE Connector Architecture transaction completing with commit or rollback is possible.
You can call several BAPIs within the same transaction.
In general Password-credentials (username/password, authentication-mechanism-type BasicPassword) are supported.
Pleas consider the following:
application to another. These objects are not serializable.
the “try” part of your try/catch/finally block, and to close it in the
“finally” part.)