Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug Report: InitialContext lookup returns clone of the binded java.util.Hashtable/FISH-7944 #6449

Open
sabrieker opened this issue Oct 13, 2023 · 3 comments
Assignees
Labels
Status: Accepted Confirmed defect or accepted improvement to implement, issue has been escalated to Platform Dev Type: Bug Label issue as a bug defect

Comments

@sabrieker
Copy link

sabrieker commented Oct 13, 2023

Brief Summary

InitialContext lookup returns clone of binded java.util.Hashtable

Expected Outcome

We bind java.util.Hashtable to InitialContext. Later when we lookup the Hashtable Payara6 returns a clone of the source object. However if we wrap Hashtable within a class as a bean then it works, it returns same reference object of the Hashtable with the binded.

Current Outcome

Every time when we asked InitialContext with lookup we retrieve different reference of the java.util.Hashtable.

Reproducer

If you can execute following code within a simple Servlet. When you execute it you can see the log as "ERROR : Record is not in this Hashtable.".

In this code we bind a Hashtable to InitialContext later we put record to it. Then we get Hashtable from InitialContext via lookup but it is a cloned object and empty.

Hashtable sourceHashtable;
        Context context = null;
        try {
            context = new InitialContext();

        } catch (NamingException e) {
            e.printStackTrace();
        }

        try {
            sourceHashtable = (Hashtable)context.lookup("LOOKUP_MAP1");
        } catch (Exception var5) {
            sourceHashtable = new Hashtable();
            try {
                context.bind("LOOKUP_MAP1", sourceHashtable);
            } catch (Exception var4) {
                throw new TransactionException("Not able to bind app scoped resource queues to JNDI.", 16, 2);
            }
            sourceHashtable.put("1","FIRST_ENTRY");
        }
        Hashtable hashtableFromInitialContext = null;
        try {
            Object object = context.lookup("LOOKUP_MAP1");
            hashtableFromInitialContext = (Hashtable)context.lookup("LOOKUP_MAP1");
            if(hashtableFromInitialContext.isEmpty()){
                System.out.println("ERROR : Record is not in this Hashtable. ");
            }
            System.out.println("Lookup Done.");
        } catch (NamingException e) {
            e.printStackTrace();
        }


Operating System

macOS Monterey / Version 6.2023.6

JDK Version

openjdk/17.0.2

Payara Distribution

Payara Server Full Profile

@sabrieker sabrieker added Status: Open Issue has been triaged by the front-line engineers and is being worked on verification Type: Bug Label issue as a bug defect labels Oct 13, 2023
@felixif
Copy link

felixif commented Oct 16, 2023

Hello @sabrieker,

I was able to reproduce the issue using your description, but I was not able to verify the functionality with a wrapped Hashtable as a bean. Could you please send here a reproducer for this case, so I can raise up the issue with all the information necessary, to make the development process easier for the Platform Development team.

@sabrieker
Copy link
Author

@felixif here you can find my simple test servlet.

Source lookupSample and lookupSample2 from InitialContext both have same instance of the "table" object.

I tried to put some comments , I hope it helps.


import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.heirloomcomputing.etp.transaction.exception.TransactionException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.collections.map.HashedMap;

import java.io.IOException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class LookupServlet extends HttpServlet {

    public class LookupSample{
        public HashedMap table = new HashedMap();
        public String key = "LOOKUP";
    }
    @Override
    protected void doGet(HttpServletRequest req,
                         HttpServletResponse res)
            throws ServletException, IOException {


        Hashtable sourceHashtable;
        Context context = null;
        try {
            context = new InitialContext();

        } catch (NamingException e) {
            e.printStackTrace();
        }

        /**
         * We want to bind a Hashtable to InitialContext.
         * We will use this table as a record keeper.
         * And all threads need to access same reference to update it.
         * With Payara6 every lookup calls to InitialContext returns a different instance of the table.
         */
        try {
            sourceHashtable = (Hashtable)context.lookup("LOOKUP_MAP1");
        } catch (Exception var5) {
            sourceHashtable = new Hashtable();
            try {
                // BIND LOOKUP_MAP1
                context.bind("LOOKUP_MAP1", sourceHashtable);
            } catch (Exception var4) {
                throw new TransactionException("Not able to bind app scoped resource queues to JNDI.", 16, 2);
            }
        }
        //insert record to the hashtable, it is already binded.
        sourceHashtable.put("1","FIRST_ENTRY");

        Hashtable hashtableFromInitialContext = null;
        try {
            Object object = context.lookup("LOOKUP_MAP1");
            hashtableFromInitialContext = (Hashtable)context.lookup("LOOKUP_MAP1");

            // object, hashtableFromInitialContext and sourceHashtable should point to same instance
            if(hashtableFromInitialContext == sourceHashtable){
                System.out.println("Lookup for LOOKUP_MAP1 returns same instance with casting");
            }
            if(object == sourceHashtable){
                System.out.println("Lookup for LOOKUP_MAP1 returns same instance without casting");
            }

            if(hashtableFromInitialContext.isEmpty()){
                System.out.println("ERROR : Record is not in this Hashtable. ");
            }
            System.out.println("Lookup Done for Hashtable.");
        } catch (NamingException e) {
            e.printStackTrace();
        }






        /**
         * In here we wrapped our Hashtable in class and we binded the instance of the class.
         * Every time we accessed the Bean we got the same instance of the HashedMap or Hashtable
         */

        Map map;
        LookupSample lookupSample = new LookupSample();
        try {
            context.bind("DUMMY", "DUMMY");
            map = new HashMap<String,Object>();
            context.bind("MAP", map);
            context.bind("LOOKUP_SAMPLE", lookupSample);

        } catch (NamingException e) {
            e.printStackTrace();
        }
        lookupSample.table.put("RECORD","This record is put after BIND.");


        HashedMap appResourceQueues2;
        try {
            appResourceQueues2 = (HashedMap)context.lookup("LOOKUP_MAP1");
            Object o = context.lookup("LOOKUP_MAP1");
            String dummy = (String)context.lookup("DUMMY");
            Map map2 = (HashMap)context.lookup("MAP");
            LookupSample lookupSample2 = (LookupSample)context.lookup("LOOKUP_SAMPLE");
            if (lookupSample2.table.isEmpty()) {
                System.out.println("ERROR: Record can not be accessed within the bean.");
            }
            System.out.println("lookupSample2.table.get(\"RECORD\") = " + lookupSample2.table.get("RECORD"));
            System.out.println("Lookup Done.");
        } catch (NamingException e) {
            e.printStackTrace();
        }

    }

    @Override
    protected void doPost(HttpServletRequest req,
                          HttpServletResponse res)
            throws ServletException, IOException {


    }

}




@felixif
Copy link

felixif commented Oct 16, 2023

@sabrieker,

Thank you for the update, I just managed to get it working on my own. I have raised an internal issue with the reference FISH-7944, in which I detailed the issue encountered and the workaround via wrapping. Thank you very much for your report!

Best regards,
Felix

@felixif felixif added Status: Accepted Confirmed defect or accepted improvement to implement, issue has been escalated to Platform Dev and removed Status: Open Issue has been triaged by the front-line engineers and is being worked on verification labels Oct 16, 2023
@felixif felixif changed the title Bug Report: InitialContext lookup returns clone of the binded java.util.Hashtable Bug Report: InitialContext lookup returns clone of the binded java.util.Hashtable/FISH-7944 Oct 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Accepted Confirmed defect or accepted improvement to implement, issue has been escalated to Platform Dev Type: Bug Label issue as a bug defect
Projects
None yet
Development

No branches or pull requests

2 participants