XML interoperability example, VS6, OneWorld B7334

Maxim Ness

Active Member
Hello,

I created a sample console app in Visual Studio 6, which fails to submit XML request to an Enterprise server. The procedure of converting MS projects to Unicode explained here (http://www.mihai-nita.net/article.php?artID=20060723a)

#include <stdio.h>
//
//
//
char* __stdcall jdeXMLRequest(unsigned short const *,unsigned short,int,void *,int);
char* __stdcall jdeFreeXMLResponse(void *);

int wmain( int argc, char ** argv )
{
unsigned short * host = L"AS400SERVER";
char *request ="<?xml version='1.0' encoding='UTF-8'?><jdeRequest pwd='password' type='callmethod' user='user' session='' environment='DV7333' sessionidle=''><callMethodTemplate name='GetAuditInfo' app='AwiIntegrations' /></jdeRequest>";

char* resp ="";
printf("Request: %s\n", request);
resp = jdeXMLRequest((unsigned short*)host,6010,100000,(void*)request,0);
printf("Response: %s\n", resp);
jdeFreeXMLResponse(resp);
return 0;
}
I execute this code from a workstation which has a FAT client installed. The app returns following:

<returnCode code='14'>Connection to OneWorld failed</returnCode>

Just in case I decided to telnet to the enterprise server to a port 6010 and it responded.

Any thoughts?
Thank you in advance!
 
Can you check your header files for the jdeXMLRequest API? I'm wondering if the host name parameter is not unicode in your release.

For XE I have it as:
jdeXMLRequest(const char *szHostName, unsigned short usPort, const int nNetTimeout, void *xml, int size);
 
Hello Graig,

jdeXMLRequest is defined exactly the same in xmlinterop.h

I've also added following to jde.ini file on my workstation. No change.

[JDENET_KERNEL_DEF6]
krnlName=CALL OBJECT KERNEL
dispatchDLLName=XMLCallObj.dll
maxNumberOfProcesses=1
numberOfAutoStartProcesses=1

[JDENET-KERNEL_DEF15]
krnlName=XML TRANSACTION KERNEL
dispatchDLLName=XMLTransactions.dll
maxNumberOfProcesses=1
numberOfAutoStartProcesses=1

By the way i found an interesting code example where one fellow stated that I do not even need a FAT client installed, just require a few libraries. Here is the link:
http://it.toolbox.com/blogs/daniel-at-work/introduction-to-using-the-jde-xml-api-from-a-very-thin-client-20570
 
Check the jde.ini on the E1 server. dispatchDLLName in JDENET_KERNEL_DEF6 must be set to the appropriate XML DLL in order for XML transactions to work.
 
Hello barrier,

How do I get to jde.ini on as/400 server via a console?

Thanks
 
Maxim,

Check the INI on your AS/400. Those sections have to be there as well.
They are different than the client:
[JDENET_KERNEL_DEF6]
...
dispatchDLLName=XMLCALLOBJ

[JDENET_KERNEL_DEF15]
...
dispatchDLLName=XMLTRANS

And yes, you do NOT need a full fat client. I posted a list of the required DLLs in another thread.
 
Maxim,

I would recommend that you have your CNC look into this because if a change is required the JDE services need to be bounced for the change to take effect.
 
Take a look at this:

<font class="small">Code:</font><hr /><pre>


typedef void* (__stdcall *JDEXMLREQUEST)(void*,unsigned short,int,void *,int);
typedef void* (__stdcall *JDEFREEXMLRESPONSE)(void*);

int XMLTransaction::SendDocument(void)
{
wchar_t szHostName[20];
int nNetTimeout = 5;
void* xml;
int nSize = 0;
char* ret;
HMODULE hLib;
JDEXMLREQUEST jdeXMLRequest = NULL;
JDEFREEXMLRESPONSE jdeFreeXMLResponse = NULL;


/* Load DLL */
hLib = LoadLibrary(_T("xmlinterop.dll"));
if (hLib == NULL)
{
AfxMessageBox ("Could not load xmlinterop.dll.");
FreeLibrary(hLib);
return -1;
}
/* Map Function pointers */
jdeXMLRequest = (JDEXMLREQUEST)GetProcAddress(hLib,"_jdeXMLRequest@20");
if (jdeXMLRequest == NULL)
{
AfxMessageBox ("Could not load jdeXMLRequest from xmlinterop.dll.");
FreeLibrary(hLib);
return -1;
}

jdeFreeXMLResponse = (JDEFREEXMLRESPONSE)GetProcAddress(hLib,"_jdeFreeXMLResponse@4");
if (jdeFreeXMLResponse == NULL)
{
AfxMessageBox ("Could not load jdeFreeXMLResponse from xmlinterop.dll.");
FreeLibrary(hLib);
return -1;
}

/* XML Request */
xml = malloc(2048);
memset(xml, 0x00, 2048);

strncpy((char*)xml,xmlString.GetBuffer(),xmlString.GetLength());
/* Host */
mbstowcs(szHostName,(LPCTSTR)xmlServer,xmlServer.GetLength()+1);

/* Execute Request */
ret=(char*)jdeXMLRequest(szHostName, xmlServerPort, nNetTimeout, (void*)xml, 2048);
xmlString=ret;

/* Clean Up */

jdeFreeXMLResponse(ret);
FreeLibrary(hLib);
free(xml);

/* Look for the return code */
int lowerLocation = 0;
int higherLocation = 0;
// Find the variable we want to extract

lowerLocation=xmlString.Find("returnCode code");
if(lowerLocation<0){
AfxMessageBox ("The call to the Enterprise One XML Server failed. Verify your Configuration.",MB_ICONSTOP |MB_OK);
return -1;
}
// the values are between single quotes
//-- find the first '
lowerLocation = xmlString.Find("'",lowerLocation);
//-- find the next '>'
higherLocation = xmlString.Find("'",lowerLocation+1);
//-- between these locations is the string we want
CString code = xmlString.Mid(lowerLocation,higherLocation-lowerLocation);
code.TrimLeft("'");
code.TrimRight("'");

// throw an error if the return code isn't 'zero'
if(code.Compare("0")!=0){
AfxMessageBox ("The call to the Enterprise One XML Server failed. Verify your Configuration.",MB_ICONSTOP |MB_OK);
return -1;
}

return 0;
}

</pre><hr />

This is C++, but I trust you can read it. Note the use of mbstowcs to convert to unicode. Of extra special note is the system variable JDE_B9_ICU_DATA. It's value must point to the location of icudt32l.dat. Standard install path for this object is: C:\E812\system\locale\xml

In your project you'll also need available: icudt32.dll, icui18n.dll, icuuc.dll, jdel.dll, jdeunicode.dll, and PSThread.dll. This pertains to tools 8.97 and later, so your version may differ.
 
Craig,

Wow, it took me 5 hours to find the file and to edit it. AS400 files are really something.
Thank you for your help!
I am now getting following error:

<returnCode code='16'>jdeXMLResponse receive failed</returnCode>

By the way I could now find all dll files, could it be that the list of files is for more recent JDE release?
 
Well, no CNC admin here. We were shipped a AS400 box with enterprise server, nothing else.
No documentation, no deployment server ...
smile.gif
 
Hello Darren,

We have OneWorld B733. Will the same code work in our environment?
Thank you
 
The DLLs will be different on XE. Run your app through the debuger and break after you load the interop DLL. Select Modules from the Debug menu and you'll see the all the required DLLs from your XE install.

I think you'll need to view the log files for the XMLCallObject kernel on the AS/400. That should provide more info.
 
Update:
When I execute my C code - it just hangs there with no response. But if I change my xml to include an invalid parameter - I get an error back right away. I was not able to find any record in jde.ini file for "CALL OBJECT KERNEL" process
 
Ok, I've got it working.

Thanks to everyone who helped me via this thread and via private messaging.
 
Back
Top