ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 03 이클립스에서 Jco3 테스트
    ABAP/JCO3 2017. 8. 18. 13:39

    이클립스에서 Jco3 테스트

    이클립스에서 개발환경을 구성한 다음 다운받은 예제 프로그램을 실행해 보겠습니다.

     

    1.     이클립스에서 신규 자바 프로젝트를 생성합니다.

    이클립스 메뉴 : File -> New -> Java Project

    프로젝트 명 : jco3(임의로 지정함)’

    2.     프로젝트에 다운로드 받은 드라이버를 저장할 폴더를 생성합니다.

    폴더명 : lib(임으로 지정함0


     

    3.     다운받은 앞축파일을 풀어서 sapjco3.dll, sapjco3.jar 파일을 프로젝트의 lib폴더에, examples폴더에 있는 자바파일을 모두 프로젝트의 src폴더에 복사합니다.


    4.     프로젝트 jco3에서 마우스 오른쪽 버튼을 클릭하여 Properties를 클릭합니다.


    5.     Java Build Path메뉴의 Libraries 탭화면으로 이동하여 Add JARs… 버튼을 클릭하여 lib폴더에 있는 sapjco3.jar파일을 추가합니다.


    6.     OK버튼을 누르면 소스폴더의 자바파일 오류표시가 사라집니다.


    7.     소스 폴더의 StepByStepClient.java파일을 열어서
    static String ABAP_MS = "ABAP_MS_WITHOUT_POOL";
    다음 내용을 추가합니다.

    static

        {

           Properties connectProperties = new Properties();

           connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "10.10.10.10");

           connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "00");

           connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "330");

           connectProperties.setProperty(DestinationDataProvider.JCO_USER, "testuser");

           connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "password!!");

           connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "ko");

           createDestinationDataFile(ABAP_AS, connectProperties);

           connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3");

           connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10");

           createDestinationDataFile(ABAP_AS_POOLED, connectProperties);

     

           Properties msConnectProperties = new Properties();

           msConnectProperties.setProperty(DestinationDataProvider.JCO_MSHOST, "mserver.co.kr");

           msConnectProperties.setProperty(DestinationDataProvider.JCO_R3NAME, "AEP");

           msConnectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "100");

               msConnectProperties.setProperty(DestinationDataProvider.JCO_USER,"testuser");

           msConnectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "password!!");

           msConnectProperties.setProperty(DestinationDataProvider.JCO_GROUP, "PRD");

           msConnectProperties.setProperty(DestinationDataProvider.JCO_LANG, "ko");

           createDestinationDataFile(ABAP_MS, connectProperties);

        }

     

     

    회사 환경에 맞게 설정해야 하는 항목은 아래와 같습니다.

    DestinationDataProvider.JCO_ASHOST

    SAP 어플리케이션서버

    DestinationDataProvider.JCO_SYSNR

    인스턴스 번호

    DestinationDataProvider.JCO_CLIENT

    클라이언트

    DestinationDataProvider.JCO_USER

    사용자

    DestinationDataProvider.JCO_PASSWD

    비밀번호

    DestinationDataProvider.JCO_LANG

    언어

     

    커넥션 풀을 사용할 경우에는 다음의 추가 설정을 진행합니다.

    DestinationDataProvider.JCO_POOL_CAPACITY

    초기 커넥션풀

    DestinationDataProvider.JCO_PEAK_LIMIT

    최대 커넥션풀

     

    메시지서버를 사용하여 접속하는 경우입니다.

    DestinationDataProvider.JCO_MSHOST

    메시지 서버

    DestinationDataProvider.JCO_R3NAME

    시스템 ID

    DestinationDataProvider.JCO_CLIENT

    클라이언트

    DestinationDataProvider.JCO_USER

    사용자

    DestinationDataProvider.JCO_PASSWD

    비밀번호

    DestinationDataProvider.JCO_GROUP

    그룹/서버

    DestinationDataProvider.JCO_LANG

    언어

     

    자바 프로그램 실행시에 createDestinationDataFile매서드가 작업 폴더에 다음 3개의 파일을 생성합니다.

    ABAP_AS_WITH_POOL.jcoDestination

    ABAP_AS_WITHOUT_POOL.jcoDestination

    ABAP_MS_WITHOUT_POOL.jcoDestination

    이 파일은 JCoDestinationManager.getDestination매서드 호출시 Jco가 읽어서 사용합니다.

     

    8.     다음은 자바 플그램의 전체 소스 입니다.

    import java.io.File;

    import java.io.FileOutputStream;

    import java.util.Properties;

    import java.util.concurrent.CountDownLatch;

     

    import com.sap.conn.jco.AbapException;

    import com.sap.conn.jco.JCoContext;

    import com.sap.conn.jco.JCoDestination;

    import com.sap.conn.jco.JCoDestinationManager;

    import com.sap.conn.jco.JCoException;

    import com.sap.conn.jco.JCoField;

    import com.sap.conn.jco.JCoFunction;

    import com.sap.conn.jco.JCoFunctionTemplate;

    import com.sap.conn.jco.JCoStructure;

    import com.sap.conn.jco.JCoTable;

    import com.sap.conn.jco.ext.DestinationDataProvider;

     

    /**

     * basic examples for Java to ABAP communication 

     */

    public class StepByStepClient

    {

        static String ABAP_AS = "ABAP_AS_WITHOUT_POOL";

        static String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";

        static String ABAP_MS = "ABAP_MS_WITHOUT_POOL";

     

        static

        {

             Properties connectProperties = new Properties();

             connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "10.11.3.48");

             connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "00");

             connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "330");

             connectProperties.setProperty(DestinationDataProvider.JCO_USER, "kr20");

             connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "linor5246!");

             connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "ko");

             createDestinationDataFile(ABAP_AS, connectProperties);

             connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3");

             connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10");

             createDestinationDataFile(ABAP_AS_POOLED, connectProperties);

     

             Properties msConnectProperties = new Properties();

             msConnectProperties.setProperty(DestinationDataProvider.JCO_MSHOST, "ekrerpvp.ekr.or.kr");

             msConnectProperties.setProperty(DestinationDataProvider.JCO_R3NAME, "AEP");

             msConnectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "100");

             msConnectProperties.setProperty(DestinationDataProvider.JCO_USER,"kr20");

             msConnectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "linor5246!");

             msConnectProperties.setProperty(DestinationDataProvider.JCO_GROUP, "PRD");

             msConnectProperties.setProperty(DestinationDataProvider.JCO_LANG, "ko");

             createDestinationDataFile(ABAP_MS, connectProperties);

        }

     

        static void createDestinationDataFile(String destinationName, Properties connectProperties)

        {

             File destCfg = new File(destinationName+".jcoDestination");

             try       {

                        FileOutputStream fos = new FileOutputStream(destCfg, false);

                             connectProperties.store(fos, "for tests only !");

                             fos.close();

             } catch (Exception e){

                        throw new RuntimeException("Unable to create the destination files", e);

                         }

        }

     

        /**

         * This example demonstrates the destination concept introduced with JCO 3.

         * The application does not deal with single connections anymore. Instead

         * it works with logical destinations like ABAP_AS and ABAP_MS which separates

         * the application logic from technical configuration.    

         * @throws JCoException

         */

        public static void step1Connect() throws JCoException

        {

            JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS);

            System.out.println("Attributes:");

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

            System.out.println();

     

            destination = JCoDestinationManager.getDestination(ABAP_MS);

            System.out.println("Attributes:");

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

            System.out.println();

        }

       

        /**

         * This example uses a connection pool. However, the implementation of

         * the application logic is still the same. Creation of pools and pool management

         * are handled by the JCo runtime.

         *

         * @throws JCoException

         */

        public static void step2ConnectUsingPool() throws JCoException

        {

            JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);

            destination.ping();

            System.out.println("Attributes:");

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

            System.out.println();

        }

       

        /**

         * The following example executes a simple RFC function STFC_CONNECTION.

         * In contrast to JCo 2 you do not need to take care of repository management.

         * JCo 3 manages the repository caches internally and shares the available

         * function metadata as much as possible.

         * @throws JCoException

         */

        public static void step3SimpleCall() throws JCoException

        {

            //JCoDestination is the logic address of an ABAP system and ...

            JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);

            // ... it always has a reference to a metadata repository

            JCoFunction function = destination.getRepository().getFunction("STFC_CONNECTION");

            if(function == null)

                throw new RuntimeException("BAPI_COMPANYCODE_GETLIST not found in SAP.");

     

            //JCoFunction is container for function values. Each function contains separate

            //containers for import, export, changing and table parameters.

            //To set or get the parameters use the APIS setValue() and getXXX().

            function.getImportParameterList().setValue("REQUTEXT", "Hello SAP");

           

            try

            {

                //execute, i.e. send the function to the ABAP system addressed

                //by the specified destination, which then returns the function result.

                //All necessary conversions between Java and ABAP data types

                //are done automatically.

                function.execute(destination);

            }

            catch(AbapException e)

            {

                System.out.println(e.toString());

                return;

            }

           

            System.out.println("STFC_CONNECTION finished:");

            System.out.println(" Echo: " + function.getExportParameterList().getString("ECHOTEXT"));

            System.out.println(" Response: " + function.getExportParameterList().getString("RESPTEXT"));

            System.out.println();

        }

       

        /**

         * ABAP APIs often uses complex parameters. This example demonstrates

         * how to read the values from a structure. 

         * @throws JCoException

         */

        public static void step3WorkWithStructure() throws JCoException

        {

            JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);

            JCoFunction function = destination.getRepository().getFunction("RFC_SYSTEM_INFO");

            if(function == null)

                throw new RuntimeException("RFC_SYSTEM_INFO not found in SAP.");

     

            try

            {

                function.execute(destination);

            }

            catch(AbapException e)

            {

                System.out.println(e.toString());

                return;

            }

           

            JCoStructure exportStructure = function.getExportParameterList().getStructure("RFCSI_EXPORT");

            System.out.println("System info for " + destination.getAttributes().getSystemID() + ":\n");

     

            //The structure contains some fields. The loop just prints out each field with its name.

            for(int i = 0; i < exportStructure.getMetaData().getFieldCount(); i++)

            {

                System.out.println(exportStructure.getMetaData().getName(i) + ":\t" + exportStructure.getString(i));

            }

            System.out.println();

           

            //JCo still supports the JCoFields, but direct access via getXXX is more efficient as field iterator

            System.out.println("The same using field iterator: \nSystem info for " + destination.getAttributes().getSystemID() + ":\n");

            for(JCoField field : exportStructure)

            {

                System.out.println(field.getName() + ":\t" + field.getString());

            }

            System.out.println();

        }

     

        /**

         * A slightly more complex example than before. Query the companies list

         * returned in a table and then obtain more details for each company.

         * @throws JCoException

         */

        public static void step4WorkWithTable() throws JCoException

        {

            JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);

            JCoFunction function = destination.getRepository().getFunction("BAPI_COMPANYCODE_GETLIST");

            if(function == null)

                throw new RuntimeException("BAPI_COMPANYCODE_GETLIST not found in SAP.");

     

            try

            {

                function.execute(destination);

            }

            catch(AbapException e)

            {

                System.out.println(e.toString());

                return;

            }

           

            JCoStructure returnStructure = function.getExportParameterList().getStructure("RETURN");

            if (! (returnStructure.getString("TYPE").equals("")||returnStructure.getString("TYPE").equals("S"))  )  

            {

               throw new RuntimeException(returnStructure.getString("MESSAGE"));

            }

           

            JCoTable codes = function.getTableParameterList().getTable("COMPANYCODE_LIST");

            for (int i = 0; i < codes.getNumRows(); i++)

            {

                codes.setRow(i);

                System.out.println(codes.getString("COMP_CODE") + '\t' + codes.getString("COMP_NAME"));

            }

     

            //move the table cursor to first row

            codes.firstRow();

            for (int i = 0; i < codes.getNumRows(); i++, codes.nextRow())

            {

                function = destination.getRepository().getFunction("BAPI_COMPANYCODE_GETDETAIL");

                if (function == null)

                    throw new RuntimeException("BAPI_COMPANYCODE_GETDETAIL not found in SAP.");

     

                function.getImportParameterList().setValue("COMPANYCODEID", codes.getString("COMP_CODE"));

               

                //We do not need the addresses, so set the corresponding parameter to inactive.

                //Inactive parameters will be  either not generated or at least converted. 

                function.getExportParameterList().setActive("COMPANYCODE_ADDRESS",false);

               

                try

                {

                    function.execute(destination);

                }

                catch (AbapException e)

                {

                    System.out.println(e.toString());

                    return;

                }

     

                returnStructure = function.getExportParameterList().getStructure("RETURN");

                if (! (returnStructure.getString("TYPE").equals("") ||

                       returnStructure.getString("TYPE").equals("S") ||

                       returnStructure.getString("TYPE").equals("W")) )

                {

                    throw new RuntimeException(returnStructure.getString("MESSAGE"));

                }

               

                JCoStructure detail = function.getExportParameterList().getStructure("COMPANYCODE_DETAIL");

               

                System.out.println(detail.getString("COMP_CODE") + '\t' +

                                   detail.getString("COUNTRY") + '\t' +

                                   detail.getString("CITY"));

            }//for

        }

       

        /**

         * this example shows the "simple" stateful call sequence. Since all calls belonging to one

         * session are executed within the same thread, the application does not need

         * to take into account the SessionReferenceProvider. MultithreadedExample.java

         * illustrates the more complex scenario, where the calls belonging to one session are

         * executed in different threads.

         *

         * Note: this example uses Z_GET_COUNTER and Z_INCREMENT_COUNTER. Most ABAP systems

         * contain function modules GET_COUNTER and INCREMENT_COUNTER that are not remote-enabled.

         * Copy these functions to Z_GET_COUNTER and Z_INCREMENT_COUNTER (or implement as wrapper)

         * and declare them to be remote enabled.

         * @throws JCoException

         */

        public static void step4SimpleStatefulCalls() throws JCoException

        {

            final JCoFunctionTemplate incrementCounterTemplate, getCounterTemplate;

     

            JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS);

            incrementCounterTemplate = destination.getRepository().getFunctionTemplate("Z_INCREMENT_COUNTER");

            getCounterTemplate = destination.getRepository().getFunctionTemplate("Z_GET_COUNTER");

            if(incrementCounterTemplate == null || getCounterTemplate == null)

                throw new RuntimeException("This example cannot run without Z_INCREMENT_COUNTER and Z_GET_COUNTER functions");

           

            final int threadCount = 5;

            final int loops = 5;

            final CountDownLatch startSignal = new CountDownLatch(threadCount);

            final CountDownLatch doneSignal = new CountDownLatch(threadCount);

            

            Runnable worker = new Runnable()

            {

                public void run()

                {

                    startSignal.countDown();

                    try

                    {

                        //wait for other threads

                        startSignal.await();

     

                        JCoDestination dest = JCoDestinationManager.getDestination(ABAP_AS);

                        JCoContext.begin(dest);

                        try

                        {

                            for(int i=0; i < loops; i++)

                            {

                                JCoFunction incrementCounter = incrementCounterTemplate.getFunction();

                                incrementCounter.execute(dest);

                            }

                            JCoFunction getCounter = getCounterTemplate.getFunction();

                            getCounter.execute(dest);

                           

                            int remoteCounter = getCounter.getExportParameterList().getInt("GET_VALUE");

                            System.out.println("Thread-" + Thread.currentThread().getId() +

                                    " finished. Remote counter has " + (loops==remoteCounter?"correct":"wrong") +

                                    " value [" + remoteCounter + "]");

                        }

                        finally

                        {

                            JCoContext.end(dest);                   

                        }

                    }

                    catch(Exception e)

                    {

                        System.out.println("Thread-" + Thread.currentThread().getId() + " ends with exception " + e.toString());

                    }

                   

                    doneSignal.countDown();

                }

            };

           

            for(int i = 0; i < threadCount; i++)

            {

                new Thread(worker).start();

            }

           

            try

            {

                doneSignal.await();

            }

            catch(Exception e)

            {

            }

           

        }

        public static void main(String[] args) throws JCoException

        {

            step1Connect();

            step2ConnectUsingPool();

            step3SimpleCall();

            step4WorkWithTable();

            step4SimpleStatefulCalls();

        }

    }

     

    9.     위 자바 클래스를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

    Attributes:

    DEST:                   ABAP_AS_WITHOUT_POOL

    OWN_HOST:               linor

    PARTNER_HOST:           erpd

    SYSTNR:                 00

    SYSID:                  AED

    CLIENT:                 330

    USER:                   KR20

    LANGUAGE:               3

    ISO_LANGUAGE:           KO

    OWN_CODEPAGE:           4102

    OWN_CHARSET:            UTF16

    OWN_ENCODING:           utf-16

    OWN_BYTES_PER_CHAR:     2

    PARTNER_CODEPAGE:       4102

    PARTNER_CHARSET:        UTF16

    PARTNER_ENCODING:       utf-16

    PARTNER_BYTES_PER_CHAR: 2

    OWN_REL:                721

    PARTNER_REL:            700

    PARTNER_TYPE:           3

    KERNEL_REL:             721

    TRACE:                  

    RFC_ROLE:               C

    OWN_TYPE:               E

    CPIC_CONVID:            00000000

     

     

    Attributes:

    DEST:                   ABAP_MS_WITHOUT_POOL

    OWN_HOST:               linor

    PARTNER_HOST:           erpd

    SYSTNR:                 00

    SYSID:                  AED

    CLIENT:                 330

    USER:                   KR20

    LANGUAGE:               3

    ISO_LANGUAGE:           KO

    OWN_CODEPAGE:           4102

    OWN_CHARSET:            UTF16

    OWN_ENCODING:           utf-16

    OWN_BYTES_PER_CHAR:     2

    PARTNER_CODEPAGE:       4102

    PARTNER_CHARSET:        UTF16

    PARTNER_ENCODING:       utf-16

    PARTNER_BYTES_PER_CHAR: 2

    OWN_REL:                721

    PARTNER_REL:            700

    PARTNER_TYPE:           3

    KERNEL_REL:             721

    TRACE:                  

    RFC_ROLE:               C

    OWN_TYPE:               E

    CPIC_CONVID:            00000000

     

     

    Attributes:

    DEST:                   ABAP_AS_WITH_POOL

    OWN_HOST:               linor

    PARTNER_HOST:           erpd

    SYSTNR:                 00

    SYSID:                  AED

    CLIENT:                 330

    USER:                   KR20

    LANGUAGE:               3

    ISO_LANGUAGE:           KO

    OWN_CODEPAGE:           4102

    OWN_CHARSET:            UTF16

    OWN_ENCODING:           utf-16

    OWN_BYTES_PER_CHAR:     2

    PARTNER_CODEPAGE:       4102

    PARTNER_CHARSET:        UTF16

    PARTNER_ENCODING:       utf-16

    PARTNER_BYTES_PER_CHAR: 2

    OWN_REL:                721

    PARTNER_REL:            700

    PARTNER_TYPE:           3

    KERNEL_REL:             721

    TRACE:                  

    RFC_ROLE:               C

    OWN_TYPE:               E

    CPIC_CONVID:            00000000

     

     

    STFC_CONNECTION finished:

     Echo: Hello SAP

     Response: SAP R/3 Rel. 700   Sysid: AED      Date: 20170818   Time: 130507   Logon_Data: 330/KR20/3

     

    1000   ********

    ****   ********

    1000   KR     *********

    ****   KR     Seoul

    Thread-12 finished. Remote counter has correct value [5]

    Thread-14 finished. Remote counter has correct value [5]

    Thread-15 finished. Remote counter has correct value [5]

    Thread-16 finished. Remote counter has correct value [5]

    Thread-13 finished. Remote counter has correct value [5]

     

    회사와 관련된 정보는 가렸습니다.

    10.  이클립스 실행시 dll라이브러리를 찾지 못하는 경우  Run Configuration에서 VM arguments에 다음 내용을 추가합니다.

    -Djava.library.path="${workspace_loc:jco3}/lib"

     


     

     

    'ABAP > JCO3' 카테고리의 다른 글

    02 테스트용 SAP RFC함수 만들기  (0) 2017.08.18
    01 JCO3 드라이버 다운로드  (0) 2017.08.18

    댓글

Designed by Tistory.