Sap Jco 2.X-3.0 (Standalone) Migration Guide
Sap Jco 2.X-3.0 (Standalone) Migration Guide
Sap Jco 2.X-3.0 (Standalone) Migration Guide
BCMIDCONF
Release 2.x-3.0
SAP AG
18.07.2011
Contents
Contents ............................................................................................................................... 2
SAP JCo 3.0 (Standalone) Client........................................................................................... 3
Features ............................................................................................................................ 3
Required Changes............................................................................................................. 4
General Coding Changes................................................................................................... 4
Renaming of Java Packages....................................................................................... 4
Sequence of setValue() Operations............................................................................. 5
Replacing JCo Classes ............................................................................................... 5
Changes to the Client Role ................................................................................................ 7
Adapting Connection Management ............................................................................. 7
Stateful Connections................................................................................................. 10
Exception Handling................................................................................................... 11
Changes to the Metadata Model ............................................................................... 12
Changes to the Server Role............................................................................................. 19
IDoc Support.................................................................................................................... 20
New Method Names in SAP JCo 3.0................................................................................ 20
SAP AG
18.07.2011
Connection and repository (metadata) management is done within the JCo layer
Version 3.0 supports several runtime environments (AS Java, JCo standalone, VMC)
Both client and server are based on a more robust programming model.
The RFC Library has been replaced by a Java RFC implementation, thus
o
SAP AG
18.07.2011
Required Changes
Some clear alterations have been made to JCo API using SAP JCo Standalone Version 3.0.
You will need to make some changes to the coding when switching from an older JCo version
(2.x) to JCo 3.0.
Below you will find the necessary information about the type of changes that have been made
and actions required for the migration.
Modifications are possibly required in the following areas:
General changes
Connection management
Exception handling
Metadata model
Server adaptations
Migration Scenarios
The scope of the changes to be made depends largely on the application scenario used.
There are basically three possible scenarios:
Client Scenarios
You application communicates as a client with an ABAP server. In this case you need
to make changes in areas.
You client application has hard-coded metadata or metadata-relevant APIs. In this
case you need to make changes in areas.
Server Scenario
Your application was developed on a Java application server and executes server
functions, that is it processes ABAP server calls.
Additionally, there are some general changes to be done regardless of the scenario you use.
More Information
For more detailed information on each of the changes to be made, see:
General Coding Changes
Changes to the Client Role
Changes to the Server Role
SAP AG
18.07.2011
Example
The changed value sequence for setValue()operations is made clear in the
examples below:
JCo 2.x
JCO.Structure myStruct=new
JCO.Stucture(repository.getStructureDefinition(FOOBAR));
myStruct.setValue(Madonna, ARTIST);
myStruct.setValue(Lucky Star, 1); // 1 is index of field SONG
myStruct.setValue(3.87, LENGTH);
JCo 3.0
JCoStructure myStruct=
JCo.createStucture(repository.getStructureDefinition(FOOBAR))
;
myStruct.setValue(ARTIST, Madonna);
myStruct.setValue(1, Lucks Star); // 1 is index of field SONG
myStruct.setValue(LENGTH, 3.87);
SAP AG
18.07.2011
JCo 2.x
IRepository repository = JCO.createRepository(REPO, SAP);
IFunctionTemplate template =
repository.getFunctionTemplate("FUNCTION_MOCULE");
IMetaData structureDefinition =
repository.getStructureDefinition("MY_STRUCT");
JCO.Structure structure=JCO.createStructure(structureDefinition);
structure.setValue(Hello World, TITLE);
structure.setValue(Good Morning, 1);
JCO.FieldIterator iterator=new JCO.FieldIterator(structure);
while(iterator.hasNextFields())
{
JCO.Field field=iterator.nextField();
System.out.println(FieldValue: +field.getString());
}
JCO.Function function = template.getFunction();
JCO.ParameterList tables=function.getTablesParameterList();
JCO.Table tracks = tables.getTable("TRACKS");
if (!tracks.isEmpty())
{
for (int i=0; i<tracks.getNumRows(); i++)
{
tracks.setRow(i);
System.out.println(tracks.getString("ARTIST")+
": "+
tracks.getString("SONG"));
}
}
JCO.AbapException[] exceptions=function.getExceptionList();
if (exceptions!=null)
for (int i=0; i<exceptions.length(); i++)
System.out.println(ExceptionName: +exceptions[i].getKey());
JCo 3.0
JCoRepository repository = destination.getRepository();
JCoFunctionTemplate template =
repository.getFunctionTemplate("FUNCTION_MOCULE");
JCoRecordMetaData structureDefinition =
repository.getStructureDefinition("MY_STRUCT");
SAP AG
18.07.2011
JCoStructure structure=JCo.createStructure(structureDefinition);
structure.setValue(TITLE, Hello World);
structure.setValue(1, Good Morning);
JCoFieldIterator iterator=structure.getFieldIterator();
while(iterator.hasNextField())
{
JCoField field=iterator.nextField();
System.out.println(FieldValue: +field.getString());
}
JCoFunction function = template.getFunction();
JCoParameterList tables=function.getTablesParameterList();
JCoTable tracks = tables.getTable("TRACKS");
if (!tracks.isEmpty())
{
for (int i=0; i<tracks.getNumRows(); i++)
{
tracks.setRow(i);
System.out.println(tracks.getString("ARTIST")+
": "+
tracks.getString("SONG"));
}
}
AbapException[] exceptions=function.getExceptionList();
if (exceptions!=null)
for (int i=0; i<exceptions.length(); i++)
System.out.println(ExceptionName: +exceptions[i].getKey());
SAP AG
18.07.2011
Example
The following example shows the changes in the code at connection setup:
JCo 2.x
JCO.addClientPool("FOO", 10, "000", "hugo", "*****", "EN", "appserver",
"00");
JCO.Repository repository = JCO.createRepository("MyRepository", SID);
IFunctionTemplate template =
repository.getFunctionTemplate("BAPI_COMPANY_GETLIST");
if(template != null)
{
JCO.Client client = null;
try
{
JCO.Function function = template.getFunction();
client = JCO.getClient("FOO");
client.execute(function);
JCO.ParameterList exports=function.getExportParameterList();
JCO.ParameterList tables=function.getTablesParameterList();
JCO.Structure bapiReturn = exports.getStructure("RETURN");
System.out.println("BAPI_COMPANY_GETLIST RETURN: " +
bapiReturn.getString("MESSAGE"));
JCO.Table companies = tables.getTable("COMPANY_LIST");
if (companies.getNumRows()>0)
{
for (int i=0; i<companies.getNumRows(); i++)
{
companies.setRow(i);
System.out.println(companies.getString("COMPANY")+
": "+companies.getString("NAME1"));
}
}
}
catch (JCO.AbapException ex)
{
System.out.println("Caught a function module exception: \n" + ex);
}
catch (JCO.Exception ex)
{
System.out.println("Caught an exception: \n" + ex);
}
finally
SAP AG
18.07.2011
{
JCO.releaseClient(client);
}
}
JCo 3.0
JCoDestination foo= JCoDestinationManager.getDestination("FOO");
JCoRepository repository = foo.getRepository();
JCoFunctionTemplate template =
repository.getFunctionTemplate("BAPI_COMPANY_GETLIST");
if(template != null)
{
try
{
JCoFunction function = template.getFunction();
function.execute(foo);
JCoParameterList exports=function.getExportParameterList();
JCoParameterList tables=function.getTablesParameterList();
JCoStructure bapiReturn = exports.getStructure("RETURN");
System.out.println("BAPI_COMPANY_GETLIST RETURN: " +
bapiReturn.getString("MESSAGE"));
JCoTable companies = tables.getTable("COMPANY_LIST");
if (companies.getNumRows()>0)
{
for (int i=0; i<companies.getNumRows(); i++)
{
companies.setRow(i);
System.out.println(companies.getString("COMPANY")+
": "+companies.getString("NAME1"));
}
}
}
catch (AbapException ex)
{
System.out.println("Caught a function module exception: \n" + ex);
}
catch (JCoException ex)
{
System.out.println("Caught an exception: \n" + ex);
}
SAP AG
18.07.2011
The JCo Runtime receives the connection parameters through the interface
DestinationDataProvider. You can register an environment-specific
implementation of DestinationDataProvider to enable integration into the
application environment. You will find detailed information in the SAP JCo 3.0
documentation.
Stateful Connections
In SAP JCo Release 2.x any function call was executed in a stateful connection by default.
For this reason it was not necessary to define a stateful connection explicitly.
As of JCo 3.0 the statements JCoContext.begin(destination) and
JCoContext.end(destination) are required for a stateful connection.
Consequently the application only has to define the scope for the stateful communication. JCo
runtime takes care of the connection management: all calls to a particular destination
between begin and end will be invoked on the same connection.
Example
The following example shows the code differences between 2.x and 3.0:
JCo 2.x
JCO.Function bapiFunction1 = ...
JCO.Function bapiFunction2 = ...
JCO.Function bapiTransactionCommit = ...
JCO.Function bapiTransactionRollback = ...
JCO.Client client = ...
try
{
try
{
client.execute(bapiFunction1);
client.execute(bapiFunction2);
client.execute(bapiTransactionCommit);
}
catch(JCO.AbapException ex)
{
client.execute(bapiTransactionRollback);
}
}
catch(JCO.Exception ex)
{
[...]
}
JCo 3.0
10
SAP AG
18.07.2011
Exception Handling
As a result of changes to exception handling, instead of enhancing of
java.lang.RuntimeException, java.lang.Exception has been introduced as a new
parent class.
When using RuntimeExceptions, it was not mandatory that exceptions be added to a throws
clause. However, when using 'normal' exceptions you must always decide whether an
exception is to be handled explicitly or if it is to be added to the throws clause.
Procedure
To adapt your code, either set try-catch [-finally] blocks, or add your exceptions to a
throw clause.
JCo 2.x
public void executeFunction(JCO.Function function, String where)
{
JCO.Client client = JCO.getClient(where);
client.execute(function);
}
11
SAP AG
18.07.2011
12
SAP AG
18.07.2011
It is of course still recommended that you exercise caution with the general
configuration of the Repository. For example, you should be sure to avoid using
the same name for different functions in different systems.
Reducing Metadata Objects in the Memory
Only one object is stored in the memory for a particular metadata type. This object referenced
by the corresponding function parameter lists or tables. The result is a reduced memory
consumption, particularly for nested tables.
Consequences
A consequence of these changes is that specific metadata operations (for example,
addinfo())are no longer usable for the metadata of record and list objects, if it is
already in use.
Also, the ParameterList.appendValue() method no longer exists.
However, it is still possible to create JCoFunction and its JcoParameterLists on
the fly.
Additionally, it is now possible to lock a metadata object after you have created it to
avoid any unwanted changes.
Note:
The following activities are only relevant if you want to use an application with hardcoded metadata or with metadata-relevant APIs.
Examples
The following examples show the differences between JCo 2.x and 3.0 in three different
areas:
Retrieving metadata when only the data container is available
Creating a parameterList on the fly.
Setting up hard-coded metadata
Retrieving Metadata
JCo 2.x
JCO.Function function = template.getFunction();
JCO.ParameterList exports=function.getExportParameterList();
for (int i=0; i<exports.getFieldCount(); i++)
System.out.println("Parameter: " + exports.getName(i) +
" length " + exports.getLength(i) +
" is " + (exports.isOptional(i)?"":"not ") +
"optional");
JCO.ParameterList tables=function.getTableParameterList();
JCO.Table theTable = tables.getTable("THE_TABLE");
for (int i=0; i<theTable.getFieldCount(); i++)
System.out.println("Field: " + theTable.getName(i) +
" length " + theTable.getLength(i) +
" offset " + theTable.getOffset(i));
13
SAP AG
18.07.2011
JCo 3.0
JCoFunction function = template.getFunction();
JCoParameterList exports=function.getExportParameterList();
JCoListMetaData listMetaData=exports.getListMetaData();
for (int i=0; i< listMetaData.getFieldCount(); i++)
System.out.println("Parameter: " + listMetaData.getName(i) +
" length " + listMetaData.getByteLength(i) +
" is " + (listMetaData.isOptional(i)?"":"not ") +
"optional");
JCoParameterList tables=function.getTableParameterList();
JCoTable theTable = tables.getTable("THE_TABLE");
JCoRecordMetaData recordMetaData = theTable.getRecordMetaData();
for (int i=0; i< recordMetaData.getFieldCount(); i++)
System.out.println("Field: " + recordMetaData.getName(i) +
" length " + recordMetaData.getByteLength(i) +
" offset " + recordMetaData.getByteOffset(i));
System.out.println("Table length: " + recordMetaData.getRecordLength());
JCo 3.0
JCoListMetaData importsMeta = JCo.createListMetaData(IMPORT);
importsMeta.add("PARAM", JCoMetaData.TYPE_CHAR, 30, 60, 0, null, null, 0,
null, null);
importsMeta.lock();
//no exports, changings, tables and exceptions for this function
JCoFunction function = JCo.createFunctionTemplate("JCO_HELLO_WORLD",
14
SAP AG
18.07.2011
Hard-Coded Metadata
JCo 2.x
IMetaData.TYPE_CHAR,
1,
2,
0, 0,
bapiReturnUC.addInfo("CODE",
null, null, 0, null, null);
IMetaData.TYPE_CHAR,
5,
10,
2, 0,
bapiReturnUC.addInfo("MESSAGE",
null, null, 0, null, null);
12, 0,
bapiReturnUC.addInfo("LOG_NO",
null, null, 0, null, null);
IMetaData.TYPE_NUM,
bapiReturnUC.addInfo("LOG_MSG_NO", IMetaData.TYPE_CHAR,
null, null, 0, null, null);
bapiReturnUC.addInfo("MESSAGE_V1", IMetaData.TYPE_CHAR,
null, null, 0, null, null);
20,
40, 452, 0,
6,
12, 492, 0,
bapiReturnUC.addInfo("MESSAGE_V2", IMetaData.TYPE_CHAR,
null, null, 0, null, null);
bapiReturnUC.addInfo("MESSAGE_V3", IMetaData.TYPE_CHAR,
null, null, 0, null, null);
bapiReturnUC.addInfo("MESSAGE_V4", IMetaData.TYPE_CHAR,
null, null, 0, null, null);
bapiReturnUC.setTabLength(904);
bapiReturn.addInfo("TYPE",
null, null, 0, null, null);
IMetaData.TYPE_CHAR,
1,
1,
0, 0,
bapiReturn.addInfo("CODE",
IMetaData.TYPE_CHAR,
5,
5,
1, 0,
15
SAP AG
18.07.2011
bapiReturn.addInfo("LOG_NO",
null, null, 0, null, null);
IMetaData.TYPE_NUM,
6, 0,
20,
20, 226, 0,
bapiReturn.addInfo("LOG_MSG_NO", IMetaData.TYPE_CHAR,
null, null, 0, null, null);
6,
6, 246, 0,
bapiReturn.addInfo("MESSAGE_V1", IMetaData.TYPE_CHAR,
null, null, 0, null, null);
50,
50, 252, 0,
bapiReturn.addInfo("MESSAGE_V2", IMetaData.TYPE_CHAR,
null, null, 0, null, null);
50,
50, 302, 0,
bapiReturn.addInfo("MESSAGE_V3", IMetaData.TYPE_CHAR,
null, null, 0, null, null);
50,
50, 352, 0,
bapiReturn.addInfo("MESSAGE_V4", IMetaData.TYPE_CHAR,
null, null, 0, null, null);
50,
50, 402, 0,
bapiReturn.setTabLength(452);
companyListUC.addInfo("COMPANY", IMetaData.TYPE_CHAR,
null, 0, null, null);
companyListUC.addInfo("NAME1",
null, 0, null, null);
6, 12,
0, 0, null,
companyListUC.setTabLength(72);
companyList.addInfo("COMPANY", IMetaData.TYPE_CHAR,
null, 0, null, null);
companyList.addInfo("NAME1",
null, 0, null, null);
6,
6, 0, 0, null,
companyList.setTabLength(36);
JCO.MetaData exportsMetaUC=new JCO.MetaData("EXPORTS", 1);
exportsMetaUC.addInfo("RETURN", IMetaData.TYPE_STRUCTURE, 452, 904, 0, 0,
null, null, 0, bapiReturnUC, null);
JCO.MetaData exportsMeta=new JCO.MetaData("EXPORTS", 1);
exportsMeta.addInfo("RETURN", IMetaData.TYPE_STRUCTURE, 452, 452, 0, 0,
null, null, 0, bapiReturn, null);
JCO.MetaData tablesMetaUC=new JCO.MetaData("TABLES", 1);
tablesMetaUC.addInfo("COMPANY_LIST", IMetaData.TYPE_TABLE, 36, 72, 0, 0,
16
SAP AG
18.07.2011
JCo 3.0
JCoRecordMetaData bapiReturn = JCo.createRecordMetaData("BAPIRETURN", 9);
17
SAP AG
18.07.2011
JCoMetaData.TYPE_CHAR,
1,
0,
2,
0, 0,
bapiReturn.add("CODE",
null, null, null);
JCoMetaData.TYPE_CHAR,
5,
1,
10,
2, 0,
bapiReturn.add("MESSAGE",
null, null,
null);
bapiReturn.add("LOG_NO",
null, null, null);
JCoMetaData.TYPE_CHAR, 220,
6, 440,
12, 0,
JCoMetaData.TYPE_NUM,
bapiReturn.add("LOG_MSG_NO", JCoMetaData.TYPE_CHAR,
null, null, null);
20, 226,
40, 452, 0,
6, 246,
12, 492, 0,
bapiReturn.add("MESSAGE_V1", JCoMetaData.TYPE_CHAR,
null, null, null);
bapiReturn.add("MESSAGE_V2", JCoMetaData.TYPE_CHAR,
null, null, null);
bapiReturn.add("MESSAGE_V3", JCoMetaData.TYPE_CHAR,
null, null, null);
bapiReturn.add("MESSAGE_V4", JCoMetaData.TYPE_CHAR,
null, null, null);
bapiReturn.setRecordLength(452, 904);
bapiReturn.lock();
companyList.add("COMPANY", IMetaData.TYPE_CHAR,
null, 0, null, null);
companyList.add("NAME1",
null, 0, null, null);
6,
IMetaData.TYPE_CHAR, 30,
0, 12,
0, 0, null,
companyList.setRecordLength(36, 72);
companyList.lock();
JCoListMetaData exportsMeta=JCo.createListMetaData("EXPORTS", 1);
exportsMeta.add("RETURN", JCoMetaData.TYPE_STRUCTURE, 452, 904, 0, null,
null, 0, bapiReturn, null);
18
SAP AG
18.07.2011
JCoFunctionTemplate
bapiCompanyGetListTemplate=JCo.createFunctionTemplate("BAPI_COMPANY_GETLIST"
, null, exportsMeta, null, tablesMeta, null);
try
{
JCoDestination foo=JCoDestinationManager.getDestination("FOO");
JCO.Function
bapiCompanyGetList=bapiCompanyGetListTemplate.getFunction();
bapiCompanyGetList.execute(foo);
JCoParameterList tables= bapiCompanyGetList.getTableParameterList();
JCoTable companies=tables.getTable("COMPANY_LIST");
for (int i=0; i<companies.getNumRows(); i++)
{
conmpanies.setRow(i)
System.out.println(companies.getString("COMPANY")+
": "+companies.getString("NAME1"));
}
}
catch(Exception e)
{
System.err.println("Exception occured: "+e.toString());
}
19
SAP AG
18.07.2011
Enter the corresponding values in the file services.txt. The file is located in the
following directory:
o
UNIX: /etc/services
Windows: /Windows/system32/drivers/etc/services
Further Information
You can find detailed Information and example programs for the server role in the SAP JCo
3.0 documention.
IDoc Support
The IDoc class library 3.0 enables IDoc-based communication via SAP JCo.
Contrary to former versions, the IDoc class library 3.0 is based on a destiantion model for the
communication with partner systems.
Further Information
You can find further information and programming examples for the IDoc class library 3.0 in
the SAP JCo documentation.
New Name
IMetaData.getTabName()
JCoMetaData.getRecordTypeName()
IMetaData.getMetaData()
JCoMetaData.getRecordMetaData()
IMetaData.getTabName()
JCoRecordMetaData.getRecordTypeName()
IRepository.getTableDefinition()
JCoRecordMetaData.getStructureDefinition()
IMetaData.getOffset()
JCoRecordMetaData.getByteOffset()/
getUnicodeByteOffset()
IMetaData.getInternalLength()
JCoMetaData.getByteLength()/
getUnicodeByteLength()
IMetaData.getTabLength()
JCoRecordMetaData.getRecordLength()
IMetaData.setTabLength()
JCoRecordMetaData.setRecordLength()
20