cancel
Showing results for 
Search instead for 
Did you mean: 

Java Mapping adding BOM to a file

Former Member
0 Kudos

Hi Experts,

I created a Java mapping jar using NWDS as below, but I applied to my Operation Mapping, but it didn't work, the BOM didn't add to the beginning of the file. Is there anything missing?

1. Create the Java project and .java class

2. Export the Jar file

Thanks

Blue

Accepted Solutions (1)

Accepted Solutions (1)

former_member182412
Active Contributor
0 Kudos

Hi Blue,

Did you add this java mapping after the messages mapping in the operation mapping?

Regards,

Praveen.

Former Member
0 Kudos

Hi Praveen,

I did as below. I also imported all the libraries followed what is stated in the youtube in the link . Not sure what is missing

Thanks

Blue

former_member182412
Active Contributor
0 Kudos

Hi Blue,

Save the out mapping result to a file, it will create schema.zip and extract it then you will get instance.xml.

Open this file in Notepad++, open hex editor plugin to see the BOM characters.

Regards,

Praveen.

Former Member
0 Kudos

Hi Praveen,

I output the data to a .txt file and opened the file, but don't see BOM at the beginning of the file?

former_member182412
Active Contributor
0 Kudos

Mapping editor is not displaying the BOM characters when you copy those characters are not copied, download the file and open it in notepad++ like above it will show the characters

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

What text editor are you using?  Notepad++ for instance will show the encoding as UTF-8-BOM instead of UTF-8 at the bottom right of the screen instead of showing the characters.

Regards,

Ryan Crosby

Former Member
0 Kudos

Hi Praveen,

I opened the file in Hex viewer in Notepad++, still don't see BOM

Former Member
0 Kudos

Hi Ryan,

I opened the file in Notepad++, it shows it is UTF-8 only as below, not UTF-8-BOM

Is the java mapping class not correct or what is the problem?

Blue

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

I tested that same example of code in Eclipse and it worked - in the past the only thing I have seen that may affect you is if you forget to call flush and close on the output stream before the end of your Java mapping.

Regards,
Ryan Crosby

Former Member
0 Kudos

Hi Ryan,

I also have Modules used in my SFTP, would you think that will impact the Java mapping?

Thanks
Blue

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

It certainly could - what modules are you using in the SFTP and what configurations are setup for those?

Regards,

Ryan Crosby

Former Member
0 Kudos

Sorry Ryan.

I am confusing myself here. I am just sending to the file to PI directory for testing, so just using file adapter and content conversion, not testing SFTP yet.

Even with content conversion still don't see the BOM byte, and I added flush and close output stream as well.

stefan_grube
Active Contributor
0 Kudos

When you create a BOM with Java Mapping, this BOM is in front of the XML payload only. After content conversion, the BOM is not available anymore. Why do you need a BOM? I have never needed any BOM for any customer.

yeeloon-khoo
Explorer
0 Kudos

Hi Blue,

If you are using standard File adapter, test without content conversion first, see if the BOM characters appear in Notepad++?

The working solution I developed before for seeburger SFTP adapter, is  build a custom module for BOM, similar to your code.

Don't use built-in FCC, instead use MessageTransformationBean, then followed by BOM module, it should work.

Regards,

Yee Loon

Former Member
0 Kudos

Thank you Stefan.

I thought that solution would add BOM to the beginning of my text file in the receiver end, but It didn't, apparently you are right. So I can't use that for my case

My client specifically asking for BOM, since in our data there are special accent used.

Blue

Former Member
0 Kudos

Thank you Yee.

I am using MessageTransformationBean now. Is it possible that you share your Module java code and how did you apply it in your Communication Channel.

Thanks again.

Blue

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

This example is very similar to your java mapping code but fits the adapter module API:


import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.rmi.RemoteException;

import javax.ejb.Stateless;

import javax.ejb.EJBException;

import javax.ejb.SessionBean;

import javax.ejb.SessionContext;

import com.sap.aii.af.lib.mp.module.Module;

import com.sap.aii.af.lib.mp.module.ModuleContext;

import com.sap.aii.af.lib.mp.module.ModuleData;

import com.sap.aii.af.lib.mp.module.ModuleException;

import com.sap.engine.interfaces.messaging.api.Message;

import com.sap.engine.interfaces.messaging.api.MessageKey;

import com.sap.engine.interfaces.messaging.api.PublicAPIAccess;

import com.sap.engine.interfaces.messaging.api.PublicAPIAccessFactory;

import com.sap.engine.interfaces.messaging.api.XMLPayload;

import com.sap.engine.interfaces.messaging.api.auditlog.AuditAccess;

import com.sap.engine.interfaces.messaging.api.auditlog.AuditLogStatus;

import com.sap.engine.interfaces.messaging.api.exception.InvalidParamException;

import com.sap.engine.interfaces.messaging.api.exception.MessagingException;

@Stateless

public class BOMBean implements SessionBean, Module{

    private static final long serialVersionUID = 1883263307825505561L;

    private MessageKey amk;

    private AuditAccess audit;

    private Message msg;

    @Override

    public ModuleData process(ModuleContext mc, ModuleData md)

            throws ModuleException {

      // Get message data and audit access

      msg = (Message) md.getPrincipalData();

      XMLPayload payload = msg.getDocument();

      amk = new MessageKey(msg.getMessageId(), msg.getMessageDirection());

      PublicAPIAccess pa;

      try {

      pa = PublicAPIAccessFactory.getPublicAPIAccess();

      } catch (MessagingException e) {

        throw new ModuleException(e.getMessage());

      }

      audit = pa.getAuditAccess();

    

      // Write BOM mark followed by full unaltered input stream

      try {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        byte[] bytes = new byte[4096];

        baos.write(0xEF);

        baos.write(0xBB);

        baos.write(0xBF);

        InputStream is = payload.getInputStream();

        while(is.read(bytes) != -1)

        {

          baos.write(bytes);

        }

        payload.setContent(baos.toByteArray());

        is.close();

        baos.close();

      } catch (IOException e) {

          audit.addAuditLogEntry(amk, AuditLogStatus.ERROR, e.getMessage());

          throw new ModuleException(e);

      } catch (InvalidParamException e) {

          audit.addAuditLogEntry(amk, AuditLogStatus.ERROR, e.getMessage());

          throw new ModuleException(e);

      }

  

      // Pass updated module data back

      return md;

    }

    @Override

    public void ejbActivate() throws EJBException, RemoteException {

    }

    @Override

    public void ejbPassivate() throws EJBException, RemoteException {

    }

    @Override

    public void ejbRemove() throws EJBException, RemoteException {

    }

    @Override

    public void setSessionContext(SessionContext arg0) throws EJBException,

            RemoteException{

    }

}

If you observe that you see multiples of 4096 bytes in the output file then the read/writing to the byte array can be adjusted to be more dynamic.  I forget which streams behave that way in Java but that's easy to adjust should you find that it does not trim trailing spaces.

P.S. - this is a very basic implementation with no parameters so it's not flexible.  If you wanted to make it be a bit more flexible you could look into usage of the key/value parameters to add functionality to the module.

Regards,

Ryan Crosby

Former Member
0 Kudos

Thank you very much Ryan.

Do you know how to apply the BOMBean in the SFTP Receiver Channel Module tab?

Blue

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

Once you have the Bean deployed to your system then you would just go into the receiver channel and add it after the MessageTransformBean but before the ModuleProcessorExitBean and you don't need to add any parameters.  So the sequence would be like this:

localejbs/MessageTransformBean

localejbs/BOMBean

localejbs/ModuleProcessorExitBean

Regards,

Ryan Crosby

Former Member
0 Kudos

Thank you Ryan.

For the Java BOMBean, should I create it in NWDS and export it as a Jar file, then imported into PI?

Do you know what is the steps to import the BOMBean into PI?

Blue

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

In order to do the deployment I would follow a guide like this as you have to first package up the .jar and then generate and .ear file for the application which is what would get deployed to your system.  I've inserted a link to a blog on how to deploy (I have a more detailed hard copy that it won't let me attach and I cannot find that link).

Regards,

Ryan Crosby

Former Member
0 Kudos

Thank you Ryan.

I followed the link in your post PI 7.4 - Adapter Module Creation using EJB 3.0

but in step 11, I put my PI host and instance number then I got error message as below, so I am stuck at step 11. Any suggestions?

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

If you are unable to deploy using that option the I would see if one of the BASIS folks could deploy using one of the other possible approaches.

Regards,

Ryan Crosby

Former Member
0 Kudos

Hi Ryan,

I exported the java file as .ear file to my local, should I give that file to our Basis team?

Thanks
Blue

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

Yes, with that .ear file they should be able get it all setup and deployed so that you can try it out in the module chain.

Regards,

Ryan Crosby

Former Member
0 Kudos

Great, thank you Ryan. I will try it on Monday.

Also is there anyway I can test the Java code in NWDS first to see if it works?

Blue

former_member182412
Active Contributor
0 Kudos

Hi Blue,

Check below blog for testing adapter modules in NWDS before deploying into server.

Regards,

Praveen.

Former Member
0 Kudos

Thank you Praveen.

Basis helped import the EAR file and testing in PI now.

Blue

Former Member
0 Kudos

Hi Ryan,

Basis helped imported the EAR file, tested in PI and got error as below:

Message processing failed. Cause: com.sap.engine.interfaces.messaging.api.exception.MessagingException: java.lang.Exception: Exception in XML Parser (format problem?):'org.xml.sax.SAXParseException: The markup in the document following the root element must be well-formed.

Don't think the Module Bean touched the format. Not sure what is the problem

Blue

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

Did you make sure to place the MessageTransformBean before the BOMBean?  If you have them reversed in order then you would get that SAXException possibly as the parser would may not handle the characters before the xml root node properly.  Make sure the order is way I had mentioned on one of the previous posts.

Regards,

Ryan Crosby

Former Member
0 Kudos

Hi Ryan,

For testing purpose, I am sending the data to PI, not to the client yet. So I am using Content Conversion as below

and here is the module:

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

You won't be able to test that way because the FCC is part of the adapter processing and that means you have that happening after the BOMBean processing.  You would need to test it the way you described before with the MessageTransformBean instead of FCC - in fact you can still use MessageTransformBean in the File/FTP adapter.

Regards,

Ryan Crosby

Former Member
0 Kudos

Thank you Ryan.

Let me change the CC using MessageTransformBean, then test it.

Blue

Former Member
0 Kudos

Hi Ryan,

After I change Content Conversion to using , the data file is generated and when I opened it in Notepad++, it says UTF-8-BOM which is very good, but the only thing is at the end of the file it added one line as

Is there any problems in the Java code?

Thanks

Blue

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

That is likely the type of stream thing I used in combination with the static value of 4096 for the array.  Does the file get created in some multiple of 4096 bytes?

Regards,

Ryan Crosby

Former Member
0 Kudos

So Ryan, instead of

byte[] bytes = new byte[4096];

InputStream is = payload.getInputStream();

while(is.read(bytes) != -1) 

        { 

          baos.write(bytes); 

        } 

I used :

InputStream is = payload.getInputStream();

while(IOUtils.toByteArray(is) != -1) 

        { 

            baos.write(IOUtils.toByteArray(is));

        } 



Does that look OK?

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

I'm not familiar with that Ojbect type as it looks to be something from Apache but as long as it has a method stub like that then I would assume that should work.

Regards,

Ryan Crosby

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

I could reproduce this in a sample on my Eclipse so this is one of the streams where you have to be sure to specify length.  The following should also work if you cannot get the IOUtils to work for you.

Change this:


byte[] bytes = new byte[4096];

Inputstream is = payload.getInputStream();

while(is.read(bytes) != -1)

{

baos.write(bytes);

}

To this:


byte[] bytes = new byte[4096];

int len = -1;

Inputstream is = payload.getInputStream();

while((len = is.read(bytes)) != -1)

{

  baos.write(bytes, 0, len);

}

Regards,

Ryan Crosby

Former Member
0 Kudos

Hi Ryan,

I used the code IOUtils.toByteArray, the file is generated properly with BOM. But when the EAR file is deployed in PI, it got a warning, I am just wondering is there a guide on how to generate EJB bean using 2.1

The warning is as below:

"BOMJavaBean is exposed as 3.0 local business interface and as 2.1. local component interface."

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

I wouldn't be super worried about the warning if it's doing what you need.  I have never faced that warning before when deploying a module but my guess is you are using a newer IDE that defaults to EJB 3.0 while your system is older and running a framework that supports 2.1.  Likely since it is only a warning and backwards compatibility is always an aim to achieve with any new systems I would bet that you can ignore it.

Regards,

Ryan Crosby

Regards,

Ryan Crosby

Former Member
0 Kudos

Hi Ryan,

Thank you so much for all your help, the BOM is added properly now. and the deployment warning is gone after I recreate the EAR file following Eng's blog as below:

Thanks again

Blue

Ryan-Crosby
Active Contributor
0 Kudos

Hi Blue,

You're welcome... glad I could help you get it working so you could meet your requirement.

Regards,

Ryan Crosby

Answers (0)