CAFE

ABAP

[퍼옴] jco에 대하여 2

작성자우승권|작성시간08.10.27|조회수6,276 목록 댓글 0

java랑 sap랑 연동해서 쓰기 위해서 jco를 설치했습니다.설치해서 샘플 파일을 실행하면 잘 돌아가거든요..
그런데 제가 궁금한것은 sap에서 어떻게 java파일을 불러서 쓰는가 입니다.
펑션을 만들어서 쓰는건가요?
sm59에서 뭘 어떻게 해야할지 전혀 감이 안잡히네여..ㅡㅜ
그리구 하나더..일단 테스트를 해볼라구 하는데 제 pc가 서버가 되야 하거든요. 언듯 듣기로 gateway를 설치해야한다구..하던데..
일단 도스창에서 자바파일을 실행시켜서 sap펑션을 부르는 것 까지는 됐는데 sap에서 java를 부를라구 하니...흑흑
아시는분 갈쳐주세영~~ 부탁부탁 합니다. 그럼 수고하세요

 

 


먼저, Gateway는 필요할 수도 있도 필요하지 않을 수도 있습니다.
JCO Server로 사용할 PC와 SAP Server간에 보안상 문제가 없다면,
바로 연결해서 사용하시면 됩니다.

SM59에는 JCo server 를 등록하는 것인데요..
JCO Server에 지정한 Program ID를 등록하는 것입니다. 이렇게 등록된
상태에서, JCO Server가 R3에 로그온하면, Biz Connector 처럼 Session이
생성되고 두 서버간에 Event에 따라 R3가 JCO Server를 통해 java 프로그램을
호출할 수 있게 됩니다. 자세한 것은 JCO Demo program 중 Example5.java와
Example7.java를 참고하시면 됩니다.
SM59에 프로그램ID 등록은 BC에게 의뢰하시면 되고요.
 

 

 

 

제가 쉬는 관계로 시간이 좀 있어서 계속 답을 드리내요.
RFC Function을 통하여 RFC Destination만 지정하면 LISTENER쪽으로 호출되게 되어 있습니다.

그래서 실제 호출하고자 하는 ABAP 프로그램에서는 RFC function에 RFC Destination을 지정하여 호출하면 됩니다.
RFC Server 역할을 하는 Function내에서는 코드가 필요없고 Parameter만 지정하면 됩니다.
실제 작업은 RFC Server 즉 Java쪽에서 이루어지게 되어 있죠.

Sample code는 제가 가진게 지금 없내요.
쉬는 통에 SAP 서버에 접근할 수 있는 게 없내요.. ^^
그럼 ..

 

 

 


SAP R/3를 Java환경과 연결할 수 있도록  SAP사에서  Java Connector를 제공하고 있습니다.

http://service.sap.com에서 무료로 다운로드 받을 수 있습니다.

SAP에서 RFC로 호출이 가능한 BAPI와 Function을 호출해서 사용할 수 있는데,
Function에서 있는 Import, Export와 Table parameter를 쉽게 사용할 수 있는 API를
제공하고 있습니다.

SAP에서는 2.0버전을 사용할 것을 권고하고 있습니다.

웹에서  JSP로 프로그래밍을 해서 R/3와 연결하는 것을 보면 이렇게 동작합니다.

JSP ->  JCO package -> JNI interface -> RFC C library -> R/3

Java는 JVM만 설치하면 실행할 수 있지만 JCO가 내부에서 C library와 인터페이스가
되기 때문에 UNIX의 경우 같은 OS라도 버전이 낮으면 동작하지 않을 수 있습니다.
(예 : 솔라리스 2.6안되고, 솔라리스 2.8부터 공식지원

 

 

 

 

 

 


Database 어뎁터의 service management를 이용하거나, 직접 만든 jdbc 서비스로
데이터를 insert, update를 하면 commit까지 자동으로 이루어지는 것 같습니다.

때때로 한 flow에서 여러개의 테이블을 순차적으로 DML 조작하는 경우 전체가
성공하지 못하면 rollback을 시켜서 데이터 정합성을 맞추어 주어야 할 때가 있습니다.
이때, rollback 서비스를 이용하면 되는데, 그 사용법을 다음과 같습니다.

startTransaction와  clearTransaction 사이에 필요한 JDBC작업을 하고 rollback을
시킬 때는 rollback을 호출한다.

                                1.11    INVOKE pub.db:startTransaction
                                           Pipeline In  Service In
                                            $dbAlias    $dbAlias  

                                1.12    INVOKE db:insert_emp
                                1.13    BRANCH on '/FLAG'
                                            1.131    C: SEQUENCE
                                                       Commit

                                                        1.1311    INVOKE pub.db:commit
                                            1.132    R: SEQUENCE
                                                       Rollback

                                                        1.1321    INVOKE pub.db:rollback
                                1.14    INVOKE db:select_emp
                                1.15    INVOKE pub.db:clearTransaction

 

 

 

 

 

 


오랜만이죠. 간만에 팁 하나 소개합니다.


1. JDK 설치

 - http://java.sun.com 참조

 

2. JConnect 설치

 - http://service.sap.com 에 가서 SAP Java Connector 1.1 를 얻거나 여기 자료실에서
   얻으세요. 원래는 각종 유닉스 버전용도 있습니다.

 - 압축을 풀어서 c:\jco-ntintel-1.1에 설치하세요.

 - c:\jco-ntintel-1.1\librfc32.dll 을 c:\winnt\system32 에 카피하세요. (win2000인 경우)

 - 환경변수 *클래스패스* 설정

  CLASSPATH=.;C:\Jco-ntintel-1.1\jCO.jar

 - 재부팅

3. 테스트

 - 회사코드리스트 출력 테스트

  c:\jco-ntintel-1.1\demo\Tutorial1.java 의 로그인정보를 수정하십시오.

   // Change the logon information to your own system/user
   mConnection =
    JCO.createClient("500",        // SAP client
    "syhan",       // userid
    "111111",      // password
    "KO",          // language
    "11.11.11.11", // host name or ip
    "00");         // system number

 - 컴파일

  도스창 혹은 명령행프롬프트를 열어서 다음과 같이 하세요.

  c:\jco-ntintel-1.1\demo>javac tutorial1.java

 - 실행

  c:\jco-ntintel-1.1\demo>java tutorial1


4. 참고

 - 이 모든 내용은 c:\jco-ntintel-1.1\docs\intro.html 파일에 더욱 자세히 나와
   있습니다.

 

cf. 1. 사실 귀찮아서 하지말자고 했는데, 개발담당자가 알아서 다해버렸네요.
    2. C보다 코딩량이 엄청 준다고 담당자께서 얘기하시네요. 이젠 RFC를 java로~

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

SAP JCo Functions 

Purpose

The SAP Java Connectorsapurl_link_0005_0003_0017 (SAP JCo) is a middleware component that enables the development of SAP-compatible components and applications in Java. The SAP JCo supports communication with the SAP Server in both directions: inbound calls (Java calls ABAP) and outbound calls (ABAP calls Java).

The SAP JCo can be implemented with Desktop applications and with Web server applications.

The SAP JCo is used as an integrated component in the following applications:

1.       SAP Business Connector, for communication with external Java applications

2.       SAP Web Application Server, for connecting the integrated J2EE server with the ABAP environment.

Implementation Considerations

The SAP Java Connector is a standalone software component that can be installed independently of the SAP system. You can access the installation files at service.sap.com/connectors. The SAP JCo is automatically installed when you use the SAP Business Connector or the SAP Web Application Server for Java.

Further Information

1.                   SAP JCo Functions

2.                   SAP JCo Architecture

3.                   SAP JCo Application Scenarios

4.                   SAP JCo Installation

5.                   SAP JCo Programming

 

The SAP JCo offers the following functions for creating SAP-capable Java applications:

 

1.      ·       RFC middleware based on the JNI (Java Native Interface).

2.      ·       Support of SAP (R/3) systems of release 3.1H and later, and other mySAP components that have BAPIs or RFMs (Remote Function Modules).

3.      ·       Execution of function calls inbound (Java client calls BAPI or RFM) and outbound (ABAP calls Java Server).

4.      ·       With the SAP JCo, you can use synchronous, transactional, and queued RFC.

5.      ·       Connection pooling (important for Web servers)

6.      ·       SAP JCo can be used on different platforms

7.      ·       Extensive code page handling, including multi-byte languages.

 

SAP JCo Architecture 

The following diagram shows the technical schema of data conversion in the SAP JCo. Starting from a Java application, a Java method is forwarded via the JCo Java API (Application Programming Interface) and an additional Middleware Interface to RFC Middleware, where it is converted to an RFC (ABAP) call using the JNI(Java Native Interface) layer, and sent to the SAP system. Using the same method in the other direction, an RFC Call is converted to Java and forwarded to the Java application:

 

 

 

 

 

SAP JCo Application Scenarios 

 

The following section describes the different implementation scenarios for the SAP Java Connector. The SAP JCo is generally used in two different ways: As an integrated component of an SAP technology component, or as a standalone tool that you can use to connect an external Java application to the ABAP environment of an SAP server.

 

1.       J2EE/ABAP Coupling in the SAP Web Application Server (integrated standard scenario)

2.       SAP JCo Scenario: SAP BC (integrated standard scenario)

3.       Displaying Invoices from the SAP System in the Web Browser (standalone scenario)

 

 

 

 

SAP JCo Scenario: J2EE/ABAP Coupling (SAP Web AS

 

In the SAP Web Application Server (SAP_BASIS), you can work in a J2EE environment and in an ABAP environment. Communication between these components is realized by the SAP JCo. Figure 1 shows an overview of the architecture of the SAP Web AS with the SAP Java Connector as the interface between the J2EE and the ABAP environment:

Figure 1: J2EE/ABAP Coupling in the SAP Web AS Using SAP JCo

Data is transferred between SAP JCo and the ABAP environment using the 'traditional' methods of RFC (with Gateway-Communication via CPI-C) or using Fast RFC (fRFC):

 

Figure 2: Communication Between ABAP and J2EE (SAP Web AS) Using CPI-C/fRFC.

Further Information

For an overview of the architecture of the SAP J2EE Engine in the SAP Web Application Server, see:

  1. Integration of the SAP J2EE Engine

SAP JCo Scenario: SAP BC 

 

The diagram below illustrates how the SAP JCo can be used with the SAP Business Connector:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

SAP JCo Scenario: Online Invoice 

Scenario: Displaying invoices online in a Web browser

The following example project describes the use of the SAP JCo in a business scenario that offers customers the option to retrieve and display their invoices online from the SAP vendor system.

The data for customer deliveries is stored in the vendor SAP system, but the actual customer invoices are stored in a document management system. In the document management system, the documents are selected by the document ID, which is stored together with the invoice number in the SAP system. The scenario must therefore find the customer data in the SAP system, and then make a connection to the document management system to retrieve the requested invoice.

Prerequisites

1.       ·       The development platform is Java

2.       ·       Enterprise JavaBeans (EJB) are used

3.       ·       You want to avoid any further installation on the SAP side

4.       ·       Transaction control in SAP occurs using BAPIs

5.       ·       You want the solution to be platform-independent

6.       ·       The project is to be implemented within a short period of time

 

Figure 1    E-Business Scenario: Displaying Invoices Online Using SAP JCo

Standard BAPIs can generally be used in this scenario. In this scenario, however, a new object is developed: Z_BAPI_GET_DOCUMENT_ID .

Figure 2    Business Object and BAPIs

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.

Figure 3    Method getDocid() in the SessionBean

 

  /**

  * 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;

  }

  // ----------------------------------------------------------------------------------

 

SAP JCo Installation 

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

Prerequisites

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).

 

Procedure

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

SAP highly recommends that you store sapjco.jar and sapjcorfc.dll in the same directory.

 

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 .

 

SAP JCo 2.1

Prerequisites

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.

Procedure

The procedure for the installation of SAP JCo release 2.1 is identical to the procedure described above for release 2.0.

New Functions

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.

 

SAP JCo Client Programming 

 

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

Establishing a Connection to an SAP Server

Creating a JCo repository, mapping ABAP and Java data types, accessing tables

The SAP JCo Repository

Access to tables and navigation in tables

Table Manipulation

Generic processing of fields

The Class JCO.Field

Optimizing performance by deactivating non-essential BAPI parameters

Deactivating Parameters

Configuring error handling in SAP JCo

Exception Handling

Synchronizing object access to optimize performance

Synchronization

Quick parameter check using the method writeHTML()

Debugging

 

Further Information

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.

 

Establishing a Connection to an SAP Server 

 

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.

 

Figure.: Connection to an SAP Server
 
 

Further Information

For more information on establishing connections to an SAP server, see:

1.       ·         Direct Connections

2.       ·         Connection Pools

 

 

 Direct Connections 

 

The following section describes an example program for creating a direct connection. For the complete program, see Example Program Connect1.

Activities

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.       

 Classes

JCO

JCO.Client

JCO.Attributes

 

 

 

Import Statements

 

import com.sap.mw.jco.*;

 

 

 

 

Defining Connection Variables

 

JCO.Client mConnection;

 

 

 

 

Further Information

For information on further procedures, see:

1.       Opening a Connection

2.       Calling a Function and Closing a Connection

3.       Result of the Function Call

The complete example program for establishing a direct connection:

1.       Example Program Connect1

 

 

Opening a 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().

 

Creating a JCO.Client Object

 

 

// 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

 

 

 

 

 

 

Opening a Connection

 

 

 

Try {

   mConnection.connect ();

}

catch (Exeption ex)   {

   ex.printStackTrace ();

   System.exit (1)

}

 

 

 

 

 

Further Information

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:

1.      Example Program Connect1

Calling a Function and Closing a Connection 

Activities

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.

Calling a Function

 

 

System.out.println (mConnection.getAttributes () );

 

 

 

 

 

 

 

 

Closing a Connection

 

 

mConnection.disconnect ();

 

 

 

 

 

 

 

 Further Information

For information on further procedures, see:

1.       Result of the Function Call

The complete example program for establishing a direct connection:

1.       Example Program Connect1

 

 

 

Result of the Function Call 

The result of the example above should look as follows:

 

Sample Output

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.

 

Further Information

For the complete example program for establishing a direct connection, see:

1.       Example Program Connect1

 

Example Program Connect1 

 

 

 

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();

  }

}

 

 

 

 

 

 

 

 

 

 

Connection Pools 

Use

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.

Select an appropriate maximum number of concurrent logons to avoid user wait times result.

Optimal use of connection pools is achieved if all pools use the same user ID. However, because the authorizations in SAP are linked to the user, this situation is only realistic if certain prerequisites are fulfilled (for example, if no security-relevant areas are affected).

 

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:

1.       Example Program Connect2.

Activities

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.

Classes

 

 

JCO.Pool

JCO.PoolManager

Defining a Pool Name

 

static final String POOL_NAME = “Pool“;

 

Does the pool exist already?

 

JCO.Pool pool = JCO.getClientPoolManager ().getPool (POOL_NAME);

if (pool == null)   {

 

 

Further Information

For information on further procedures, see:

1.       Creating a Connection Pool

2.       Acquiring and Releasing a Connection

The complete example program for creating a connection pool:

1.       Example Program Connect2

 

 

 

Creating a Connection Pool 

Activities

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.

Creating a Connection Pool

 

OrderedProperties logonProperties =

   OrderedPropertiess.load (“/logon.properties“);

JCO.addClientPool (POOL_NAME,           // pool name

                   5,                 // max. number of connections

                   logonProperties);  // properties

 

Logon Properties

 

jco.client.client=001

jco.client.user=userid

jco.client.passwd=****

jco.client.ashost=hostname

jco.client.sysnr=00

 

Further Information

For information on further procedures, see:

1.       Acquiring and Releasing a Connection

The complete example program for creating a connection pool:

1.       Example Program Connect2

 

 

Creating a Connection Pool 

Activities

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.

Creating a Connection Pool

 

OrderedProperties logonProperties =

   OrderedPropertiess.load (“/logon.properties“);

JCO.addClientPool (POOL_NAME,           // pool name

                   5,                 // max. number of connections

                   logonProperties);  // properties

 

Logon Properties

 

jco.client.client=001

jco.client.user=userid

jco.client.passwd=****

jco.client.ashost=hostname

jco.client.sysnr=00

 

Further Information

For information on further procedures, see:

1.       Acquiring and Releasing a Connection

The complete example program for creating a connection pool:

1.       Example Program Connect2

 

 

Acquiring and Releasing a Connection 

Activities

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.

To change the default value for the wait time, you can use the method setMaxWaitTime(), which is available for PoolManagers as well as for individual JCO.Pool objects. The new value is transferred in milliseconds.

13.           3.      After a successful function call, the connection to the method releaseClient() is released back into the pool.

14.           4.      This normally happens in a finally block, so that the method is always executed, independently of whether or not an exception is output. Otherwise if the connection is not released, this could lead to a shortage of available connections in the connection pool.

 

Requesting a Connection

 

mConnection = JCO.getClient (POOL_NAME);

 

 

Releasing a Connection

 

 

 

System.out.println (mConnection.getAttributes () );

}

 

catch (Exception ex)   {

   ex.printStackTrace ();

}

finally  {

   JCO.releaseClient (mConnection);

}

 

From an SAP server perspective, a session begins with the call of getClient(), and ends with releaseClient(). If you want to call different RFMs in sequence without any third-party interaction occurring during this time, maintain the connection long enough for the sequence to be executed (each RFM is a separate dialog step in the SAP server).

When calling a connection pool, never use the methods connect() or disconnect() from the class JCO.Client. For connection pools, the functions are executed by the PoolManager.

Further Information

For the complete example program for establishing a connection pool, see:

Example Program Connect2.

 

 

Example Program Connect2 

 

 

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 JCo Repository 

Definition

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.

Figure: SAP JCo Repository 1

 

Further Information

For more detailed information on the SAP JCo Repository, see:

Creating a Repository

Creating a JCO.Function Object

Executing a Function

Mapping of Java and ABAP Data Types

Type-Specific Getter Methods

Access to Tables

Setting Scalar Import Parameters

For a complete example program for creating a JCo repository and executing BAPIs, see:

1.       ·         Example Program Bapi1

 

 

Table Manipulation 

Verwendung

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.

 

Table Manipulation

 

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:

1.       Example Program Bapi2

The following table summarizes the JCO.Table methods that are not contained in JCO.Structure.

 

JCO.Table Methods

 

 

Example Program Bapi2 

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();

   }

}

 

 

The Class JCO.Field 

Definition

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().

 

Deactivating Parameters 

Use

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:

 

 

Many BAPIs have a large number of parameters, not all of which are used in an application. There is no way to prevent the SAP system from returning a parameter, but you can prevent the SAP JCo forwarding a parameter to the Java layer. To do this, you simply need to declare the parameter as inactive, as displayed in the diagram below. This is particularly effective for larger tables that are returned by the SAP system.

Deactivating Parameters

function.getExportParameterList().

  

    setActive(false, "COMPANYCODE_ADDRESS");

 

 

 

Exception Handling 

Prerequisites

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 .

 

Use

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):

 Exception Handling

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.

 

 

 

Synchronization 

 

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.

 

 

 

Debugging 

Use

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.html.table_max_rows

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 ).

 

Table Parameters Displayed as an HTML Page

 

SAP Java Resource Adapter 

Purpose

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.

Implementation Considerations

The SAP JRA is an add-on for the SAP JCo. If you use the SAP Web AS, the SAP JRA is installed automatically with the SAP JCo. It is also possible to install the SAP JRA as a standalone component from the Internet (service.sap.com/connectors).

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.

Constraints

The SAP JRA does not support inbound communication, tRFC, IDocs, or certificates .

Further Information

1.       SAP JRA Architecture

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.  

3.       BI Java Connectors

 

SAP JRA Architecture 

 

The SAP JRA is based on the J2EE Connector Architecture. The J2EE connector architecture defines a standard architecture for communication from existing, heterogeneous ERP systems to any J2EE-compatible application server.

 

 

Figure: SAP JRA Architecture

 

SAP JRA: Frequently asked Questions 

 

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?

 

Can the SAPJRA be used with every J2EE Application Server ?

SAPJRA was tested on SAP J2EE Engine and on the SUN Reference Implementation Application Server. It passed all J2EE Specification Compliance tests.

 

What restrictions does the SAPJRA 1.0 have?

2-phase commit and re-authentication are not supported by SAP, so they are not supported by SAP JRA either.

 

Does the SAPJRA support the Common Client Interface

(CCI) ?

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 doesnt 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(…).

 

What types of functions can be called ?

Please see FAQ Does the SAP JRA support local transactions?

 

Does the SAPJRA need additional libraries ?

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.

 

Is the SAPJRA 100% pure Java ?

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.

 

Is the SAPJRA visible for the user ?

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.

 

Does the SAPJRA support connection-pooling?

Yes.

 

Does the SAPJRA support connection-sharing ?

Yes. Note, that a connection may only be shared by the Application Server within the same transaction.

 

Does the SAPJRA support re-authentication of connections ?

No, because the SAP system does not support re-authentication.

 

Does the SAPJRA support XA-based transactions (XAResource)?

No, because the SAP system does not support a 2-phase commit.

 

Does the SAPJRA support local transactions ?

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 dont 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.

 

Does the SAPJRA support authentication using Subjects (Java Authentication and Authorization Service) ?

In general Password-credentials (username/password, authentication-mechanism-type BasicPassword) are supported.

Pleas consider the following:

  1. For Password credentials please configure  in the descriptor connector-j2ee-engine.xml (or using the DeployTool) one of the authentication types (configured identity / principal mapping / caller impersonation).
  2. For SAP Logon Tickets (authentication-mechanism-type GenericCredentials) ) please configure in the descriptor connector-j2ee-engine.xml the authentication type caller impersonation.
  3. Web Clients can also authenticate themselves over Certificates. The actual connection to SAP will be made in this case either through BasicPassword or GenericCredentials depending on the configuration.
  4. For details see the Documentation for Security / User Management on the SAP J2EE Engine.

 

What should you not do?

  1. Create any threads in your applications.
  2. Pass Connection, Transaction and Interaction objects from one  

   application to another. These objects are not serializable.

  1. Leave Connections open. The best way to handle connections is to open it in

   the  try part of your try/catch/finally block, and to close it in the

   finally part.)

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼