How can I resolve Null pointer exception in my transaction manager

661 views
Skip to first unread message

OmexIT

unread,
Apr 23, 2013, 1:52:48 AM4/23/13
to jpos-...@googlegroups.com
I get null pointer exception when I try my Server
......20_txnmgr_conf.xml

<?xml version="1.0" ?> 
<txnmgr name="MyTxn" logger="Q2" 
class="org.jpos.transaction.TransactionManager"> 

<property name="space" value="tspace:default" /> 
<property name="queue" value="MyTxnQueue" /> 
<property name="persistent-space" value="jdbm:MyTxnSpace" /> 
<property name="sessions" value="1" /> 
<participant class="org.mode.wallet.transactionManager.TransactionManager" logger="Q2" > 
</participant> 
</txnmgr> 

10_Wallet_Server.xml
<?xml version="1.0" ?>
<server class="org.jpos.q2.iso.QServer" logger="Q2" header="Omexic001" 
  name="Wallet_ISOServer_10000">
 <attr name="port" type="java.lang.Integer">10000</attr>

 <channel class="org.jpos.iso.channel.XMLChannel" logger="Q2"
       packager="org.jpos.iso.packager.XMLPackager" realm="server_channel_A">
 </channel>

 <request-listener class="org.jpos.RequestListener.WalletRequestListener" logger="Q2"> 
<property name="space"   value="tspace:default" /> 
  <property name="queue"   value="MyTxnQueue" /> 
</request-listener>
</server>

WalletRequestListener.java

public class WalletRequestListener extends QBeanSupport
        implements ISORequestListener {

    // Constants defined elsewhere ...
    public static final String REQUEST = "REQUEST";
    public static final String ISOSOURCE = "ISOSOURCE";
    protected Logger logger;
    protected String realm;
    Space sp;
    public WalletRequestListener() {
        super();
        this.sp = SpaceFactory.getSpace("tspace:default");
    }

    @Override
    public boolean process(ISOSource source, ISOMsg m) {
        System.out.println("-------m--------------" + m);
        //Space sp = SpaceFactory.getSpace();
        Context ctx = new Context();
        ctx.put(REQUEST, m);
        ctx.put(ISOSOURCE, source);

        sp.out(cfg.get("queue"), ctx, cfg.getLong("timeout"));
        return true;
    }
}

TransactionManager.java

public class TransactionManager extends QBeanSupport implements TransactionParticipant {
    public int prepare(long id, Serializable context) {
        Context ctx = (Context) context;
        ISOMsg msg = (ISOMsg) ctx.get(cfg.get("queue"));
        Logger logger = new Logger();
        logger.addListener(new SimpleLogListener(System.out));
        ISOSource source = (ISOSource) ctx.get("ISOSOURCE");
        try {
            msg.set(39, "00");
            source.send(msg);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return PREPARED;
    }
    public void commit(long id, Serializable context) {
        Context ctx = (Context) context;
        ISOMsg msg = (ISOMsg) ctx.get("ORIGINAL");
        ISOSource source = (ISOSource) ctx.get("ISOSOURCE");
        try {
            source.send(msg);
        } catch (IOException | ISOException e) {
            e.printStackTrace();
        }
        System.out.println("Committing the inquiry process");
    }
    public void abort(long id, Serializable context) {
        System.out.println("Inquiry Process aborted");
    }
}

I use client simulator to test my server

I get the following error:

<log realm="client-simulator" at="Tue Apr 23 08:29:02 EAT 2013.464">
  <trace>
    ---------------------------[ Simple Echo Test ]---------------------------
  </trace>
</log>
<log realm="channel/127.0.0.1:10000" at="Tue Apr 23 08:29:02 EAT 2013.515" lifespan="2ms">
  <send>
    <isomsg>
      <!-- org.jpos.iso.packager.XMLPackager -->
      <field id="0" value="1800"/>
      <field id="7" value="0423082902"/>
      <field id="11" value="942509"/>
      <field id="12" value="000000"/>
      <field id="63" value="Tue Apr 23 08:29:02 EAT 2013"/>
      <isomsg id="120">
        <field id="0" value="29110001"/>
      </isomsg>
    </isomsg>
  </send>
</log>
<log realm="server_channel_A/127.0.0.1:49784" at="Tue Apr 23 08:29:02 EAT 2013.518" lifespan="277ms">
  <receive>
    <isomsg direction="incoming">
      <!-- org.jpos.iso.packager.XMLPackager -->
      <field id="0" value="1800"/>
      <field id="7" value="0423082902"/>
      <field id="11" value="942509"/>
      <field id="12" value="000000"/>
      <field id="63" value="Tue Apr 23 08:29:02 EAT 2013"/>
      <isomsg id="120">
        <field id="0" value="29110001"/>
      </isomsg>
    </isomsg>
  </receive>
</log>
-------m--------------<-- 1800 942509
java.lang.NullPointerException
<log realm="server_channel_A/127.0.0.1:49784" at="Tue Apr 23 08:29:02 EAT 2013.772" lifespan="1ms">
  <send>
    <exception name="null">
    java.lang.NullPointerException
at org.mode.wallet.transactionManager.TransactionManager.prepare(TransactionManager.java:34)
at org.jpos.transaction.TransactionManager.prepare(TransactionManager.java:438)
at org.jpos.transaction.TransactionManager.prepare(TransactionManager.java:489)
at org.jpos.transaction.TransactionManager.run(TransactionManager.java:249)
at java.lang.Thread.run(Thread.java:722)
org.jpos.iso.ISOException: unexpected exception (java.lang.NullPointerException)
at org.jpos.iso.BaseChannel.send(BaseChannel.java:574)
at org.jpos.iso.BaseChannel.send(BaseChannel.java:543)
at org.mode.wallet.transactionManager.TransactionManager.commit(TransactionManager.java:55)
at org.mode.wallet.transactionManager.TransactionManager.commit(TransactionManager.java:55)
at org.jpos.transaction.TransactionManager.commit(TransactionManager.java:448)
at org.jpos.transaction.TransactionManager.commit(TransactionManager.java:448)
at org.jpos.transaction.TransactionManager.commit(TransactionManager.java:391)
at org.jpos.transaction.TransactionManager.commit(TransactionManager.java:391)
at org.jpos.transaction.TransactionManager.run(TransactionManager.java:256)
at java.lang.Thread.run(Thread.java:722)
at org.jpos.transaction.TransactionManager.run(TransactionManager.java:256)
Nested:java.lang.NullPointerException
at java.lang.Thread.run(Thread.java:722)
    </exception>
  </send>
</log>
Committing the inquiry process
at org.jpos.iso.BaseChannel.send(BaseChannel.java:543)
at org.mode.wallet.transactionManager.TransactionManager.commit(TransactionManager.java:55)
at org.jpos.transaction.TransactionManager.commit(TransactionManager.java:448)
at org.jpos.transaction.TransactionManager.commit(TransactionManager.java:391)
at org.jpos.transaction.TransactionManager.run(TransactionManager.java:256)
at java.lang.Thread.run(Thread.java:722)
Nested:java.lang.NullPointerException
at org.jpos.iso.BaseChannel.send(BaseChannel.java:543)
at org.mode.wallet.transactionManager.TransactionManager.commit(TransactionManager.java:55)
at org.jpos.transaction.TransactionManager.commit(TransactionManager.java:448)
at org.jpos.transaction.TransactionManager.commit(TransactionManager.java:391)
at org.jpos.transaction.TransactionManager.run(TransactionManager.java:256)
at java.lang.Thread.run(Thread.java:722)
<log realm="client-simulator" at="Tue Apr 23 08:29:32 EAT 2013.512">

Assist me solve this




chhil

unread,
Apr 23, 2013, 2:15:49 AM4/23/13
to jpos-...@googlegroups.com

1. Get the jpos source code and debug the offending line.

2. ISOMsg msg = (ISOMsg) ctx.get("ORIGINAL"); 
I dont see context ever being populated by ORIGINAL.

3. You may want to do a isomsg.setResponsMTI to change the 0800 to 0810 in the response.

4. Not sure why you are doing a send in the commit. You are sending a message twice, once in the prepare and then in commit.

5.ISOMsg msg = (ISOMsg) ctx.get(cfg.get("queue")); but you do a     ctx.put(REQUEST, m); in the request listener, you should get the message using ctx.get(REQUEST).

6. Please debug your code and verify the objects you are using.

-chhil

--
--
jPOS is licensed under AGPL - free for community usage for your open-source project. Licenses are also available for commercial usage.
Please support jPOS, contact: sa...@jpos.org
 
You received this message because you are subscribed to the "jPOS Users" group.
Please see http://jpos.org/wiki/JPOS_Mailing_List_Readme_first
To post to this group, send email to jpos-...@googlegroups.com
To unsubscribe, send email to jpos-users+...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/jpos-users
 
---
You received this message because you are subscribed to the Google Groups "jPOS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jpos-users+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

OmexIT

unread,
Apr 23, 2013, 2:34:47 AM4/23/13
to jpos-...@googlegroups.com
Thank you, I just debugged my code and its is working ok. From my first code my Idea was to put the requests in a queue in case of too many transactions than the server can handle. How can I achieve this?

chhil

unread,
Apr 23, 2013, 3:03:41 AM4/23/13
to jpos-...@googlegroups.com
Thats where your transaction managers session prop comes into the picture. You have it at 1 (<property name="sessions" value="1" /> ), bumping that up will allow handling of multiple requests. As an example we have  30 sessions in one of our prod systems transaction manager.
Each request gets placed in the queue MyTxnQueue by your request listener and the framework instantiates a transaction manager per request when it sees an entry in that queue.

OmexIT

unread,
Apr 23, 2013, 3:24:15 AM4/23/13
to jpos-...@googlegroups.com
So this means that for example my i have  (<property name="sessions" value="10" /> ) and i have 30 requests coming in simultaneously: Are the following statements true?
=> Transaction manager will be instantiated 30 times.
=> The 10 sessions will handle the first 10 transaction in the queue the the next until the queue is empty. This is done automatically.
=> from my example, multiple requests is well handled.

chhil

unread,
Apr 23, 2013, 3:43:23 AM4/23/13
to jpos-...@googlegroups.com
30 simultaneous will be handled simultaneously by the tcp server (your qserver). It has a threadpool associated to it and I think its default is 100 threads.
All of these will be placed in your queue. 10 of them will simultaneously process by the transaction manager.
In all 30 Transaction managers will be instantiated in all and each transaction manager is responsible for one request, the context is not shared between transaction managers, which means objects in the context are local to it.


=> Transaction manager will be instantiated 30 times.
True.

=> The 10 sessions will handle the first 10 transaction in the queue the the next until the queue is empty. This is done automatically.
True

=> from my example, multiple requests is well handled.
True.

-chhil

--

chhil

unread,
Apr 23, 2013, 3:49:30 AM4/23/13
to jpos-...@googlegroups.com
"In all 30 Transaction managers will be instantiated"
I may have this wrong, there will be as many transaction manager threads running as the number of sessions. So there will be 10 transaction manager threads that will process your 30 requests.

-chhil

OmexIT

unread,
Apr 23, 2013, 4:18:44 AM4/23/13
to jpos-...@googlegroups.com
That is cool. I just created a regular Client Socket to communicate with the server above.... The problem is that the socket connects but i can not see any message sent to my server. Is there any other setting i need to perform to my server?

Below is my client socket code:

public class ClientDemo {

    public static void main(String[] args) {
        try {
            new ClientDemo().startClient();
        } catch (Exception e) {
            System.out.println("Something falied: " + e.getMessage());
            e.printStackTrace();
        }
    }

    public void startClient() throws IOException {

        Socket socket = null;
        PrintWriter out = null;
        BufferedReader in = null;
        InetAddress host = null;
        BufferedReader stdIn = null;

        try {
            host = InetAddress.getLocalHost();
            socket = new Socket(host.getHostName(), 10000);

            out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            stdIn = new BufferedReader(new InputStreamReader(System.in));
            String fromServer;
            String fromUser = null;
            OUTER:
            while ((fromServer = in.readLine()) != null) {
//                System.out.println("Server - " + fromServer);

                switch (fromServer) {
                    case "Welcome":
                        try{
                        fromUser = ClientHelper.createISO();
                        }catch(ISOException e){
                            System.err.println("Error: "+e.getMessage());
                        }
                        break;
                    case "exit":
                        break OUTER;
                    default:
                        try {
                             ClientHelper.unpackISO(fromServer);
                        } catch (ISOException e) {
                            e.printStackTrace();
                        }
                        fromUser="bye";
                        break;
                }

                if (fromUser != null) {
                    //System.out.println("Client - " + fromUser);
                    out.println(fromUser);
                }
            }
        } catch (UnknownHostException e) {
            System.err.println("Cannot find the host: " + host.getHostName());
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't read/write from the connection: " + e.getMessage());
            System.exit(1);
        } finally { //Make sure we always clean up
            out.close();
            in.close();
            stdIn.close();
            socket.close();

chhil

unread,
Apr 23, 2013, 4:35:38 AM4/23/13
to jpos-...@googlegroups.com
Sorry my java aint that good, try asking this on a java forum or stackoverflow :)

Why did you regress from using the client sim?

-chhil

OmexIT

unread,
Apr 23, 2013, 5:04:32 AM4/23/13
to jpos-...@googlegroups.com
I had earlier (when I thought i could not understand JPOS) created a normal client server application to send ISO Message and unpack it. I was just testing it to see if it will work with my server. In the JPOS Source, i have seen SocketFactory. How can I it

Mark Salter

unread,
Apr 23, 2013, 5:11:40 AM4/23/13
to jpos-...@googlegroups.com

On Tuesday, April 23, 2013 9:18:44 AM UTC+1, OmexIT wrote:
That is cool. I just created a regular Client Socket to communicate with the server above.... The problem is that the socket connects but i can not see any message sent to my server. Is there any other setting i need to perform to my server?

For this to work, you need to produce the same data that the receiving end is expecting to get, failure to do so will result in 'strange' behavior.

Why not use jPOS components to do the work, then you could ask for assistance on a jPOS mailing list and expect help?

If you choose not to use jPOS classes, then you are on your own here unless some kind soul cares to help;  as Chhil has already suggested, perhaps you need another mailing list to help you in your 'testing'.

I suspect data is traveling over the network, but that the lengths involved might be wrong or missing?  Perhaps the receiver has read a length from the stream and is waiting for the number of bytes specified to arrive - just a guess of course.
To independently check if data *is* flowing try a network monitoring tool - like wireshark - with filtering on the ports you are interested in?

--
Mark

OmexIT

unread,
Apr 23, 2013, 5:31:34 AM4/23/13
to jpos-...@googlegroups.com
I get you. I appreciate the way JPOS universe help people assist people. I am almost there. 

Alejandro Revilla

unread,
Apr 23, 2013, 9:57:58 AM4/23/13
to jpos-...@googlegroups.com

I'm surprised by this:

public class TransactionManager extends QBeanSupport implements TransactionParticipant

I find

  • Confusing that you name your participant TransactionManager, it's OK, you can do that, but it's confusing.
  • Why do you extend QBeanSupport in your participant, given this is not a QBean?
--
@apr



--

OmexIT

unread,
Apr 23, 2013, 10:13:20 AM4/23/13
to jpos-...@googlegroups.com
I extend QBeanSupport because I needed to use the method cfg.get(). How can I get  cfg.get().

Alejandro Revilla

unread,
Apr 23, 2013, 10:17:14 AM4/23/13
to jpos-...@googlegroups.com

You need to implement Configurable instead. Implementing it is very simple, you just need to add a method:

   public void setConfiguration(Configuration cfg) throws ConfigurationException

In that method, you can either cache the cfg object locally, or get the properties you need and save them in local variables.

You probably also want either implement `LogSource` or `extend Log` in order to be able to use the jPOS logger system.

--
@apr

chhil

unread,
Apr 23, 2013, 10:22:18 AM4/23/13
to jpos-...@googlegroups.com
Or extend TxnSupport .

-chhil

Alejandro Revilla

unread,
Apr 23, 2013, 10:44:47 AM4/23/13
to jpos-...@googlegroups.com
Good point ! :)

--
@apr



OmexIT

unread,
Apr 23, 2013, 12:11:41 PM4/23/13
to jpos-...@googlegroups.com
Thanx for that. I tried to find  TxnSupport  the project but could not find. What do I need to import to my project

Alejandro Revilla

unread,
Apr 23, 2013, 12:22:19 PM4/23/13
to jpos-...@googlegroups.com
It's in the jPOS-EE 'txn' module, but you can copy the code to your source tree:


--
@apr



OmexIT

unread,
Apr 23, 2013, 1:11:35 PM4/23/13
to jpos-...@googlegroups.com
Thank you! I have found it. 

OmexIT

unread,
Apr 23, 2013, 1:13:00 PM4/23/13
to jpos-...@googlegroups.com
Thank you. You have really made a difference to me!
Reply all
Reply to author
Forward
0 new messages