【问题标题】:NotSerializableException with BasicDataSource in JNDIJNDI 中带有 BasicDataSource 的 NotSerializableException
【发布时间】:2014-07-19 02:00:59
【问题描述】:

我正在设置一个独立的 JNDI 并将一个数据源加载到 JNDI。 我使用的数据源是:org.apache.commons.dbcp.BasicDataSource

JNDI 设置如下

        String detectorHost = InetAddress.getLocalHost().getHostName();
        System.out.println("detectorHost: " + detectorHost);
        System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
        final NamingBeanImpl namingInfo = new NamingBeanImpl();
        namingInfo.start();

        final Main JNDIServer = new Main();

        JNDIServer.setNamingInfo( namingInfo );
        JNDIServer.setPort( 5400 );
        JNDIServer.setBindAddress(InetAddress.getLocalHost().getHostName());
        JNDIServer.start();

        final Hashtable _properties = new Hashtable();
        _properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
        _properties.put(Context.PROVIDER_URL,            "jnp://" + InetAddress.getLocalHost().getHostName() + ":5400");

        final Context _context = new InitialContext(_properties);
        _context.createSubcontext("jdbc");
        String JNDI_PATH = "jdbc" + "/" + "mydbname";
        _context.bind(JNDI_PATH, getDataSource());

我得到以下异常

javax.naming.CommunicationException [Root exception is     java.io.NotSerializableException: org.apache.commons.dbcp.BasicDataSource]
    at org.jnp.interfaces.NamingContext.bind(NamingContext.java:677)
    at org.jnp.interfaces.NamingContext.bind(NamingContext.java:611)
    at javax.naming.InitialContext.bind(Unknown Source)
    at com.lombardrisk.reform.integration.ReformIntegration.createJNDIServer(ReformIntegration.java:93)
    at     com.lombardrisk.reform.integration.ReformIntegration.main(ReformIntegration.java:44)
Caused by: java.io.NotSerializableException: org.apache.commons.dbcp.BasicDataSource
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at java.rmi.MarshalledObject.<init>(Unknown Source)
    at org.jnp.interfaces.MarshalledValuePair.<init>(MarshalledValuePair.java:65)
    at org.jnp.interfaces.NamingContext.createMarshalledValuePair(NamingContext.java:1425)
    at org.jnp.interfaces.NamingContext.bind(NamingContext.java:640)

我不太明白为什么会收到 NotSerializableException 异常,这是同一 JVM 中的本地 JNDI,而不是远程 JNDI。不知道为什么会这样。

谁能告诉我这里出了什么问题。

问候 D

【问题讨论】:

    标签: datasource jndi notserializableexception initial-context


    【解决方案1】:

    该异常具有误导性。在JVM启动中添加以下内容后异常变得清晰

    -Dsun.io.serialization.extendedDebugInfo=true

    看来我没有使用正确的库。 我已经在此链接中解释了完整的问题和解决方案。 https://community.jboss.org/thread/241498

    //Code to start a JNDI Server and a test client for the JNDI Context
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    
    import org.apache.log4j.Logger;
    import org.jnp.server.Main;
    import org.jnp.server.NamingBeanImpl;
    
    //Snippet of the code
    
        System.setProperty("java.rmi.server.hostname", "localhost");
        System.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
        System.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
        final NamingBeanImpl namingInfo = new NamingBeanImpl();            
        namingInfo.start();
    
        final Main jndiServer = new Main();
    
    
        jndiServer.setNamingInfo(namingInfo);
        jndiServer.setPort(1099);
        jndiServer.setBindAddress("localhost");
        jndiServer.setRmiPort(1098);
        jndiServer.setRmiBindAddress("localhost");
        jndiServer.start();   
        final Hashtable<String, String> _properties = new Hashtable<String, String> ();
        _properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
        _properties.put(Context.PROVIDER_URL,            "jnp://" + "localhost" + ":1099");
        final Context _context = new InitialContext(_properties);
        _context.createSubcontext("jdbc");
        JdbcTemplate jdbcTemplate = new JdbcTemplate(getDataSource());
        System.out.println("jdbcTemplate:  " + jdbcTemplate.getClass());
        System.out.println("getDataSource(): " + getDataSource().getClass());
        _context.bind("/jdbc/reformDS", getDataSource());
    
    //JNDI started
    
    
    //Test the JNDI context
    // There are 2 ways to test - 
    // Option 1: create a HashTable and pass the properties to the InitialContext constructor
        final Hashtable<String, String> _properties = new Hashtable<String, String> ();
        _properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
        _properties.put(Context.PROVIDER_URL,            "jnp://" + "localhost" + ":1099");
    
    final Context _context = new InitialContext(_properties);
    Object obj = _context.lookup("/jdbc/reformDS");
    if (null != obj) {
    System.out.println("OBJ: " + obj.getClass());
               org.apache.commons.dbcp.BasicDataSource ds = (org.apache.commons.dbcp.BasicDataSource)obj;
               JdbcTemplate jdbcTemplate2 = new JdbcTemplate(ds);
               String sql = String.format("update MESSAGE_LOG set PROCESS_INSTANCE_ID = 123456 where ID =42395 ");      
               int update = jdbcTemplate2.update(sql);
               System.out.println("Update*****************: " + update);
               }
    
    
    // Option 2: Set the System.properties and call the InitialContext 
    System.getProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
    System.getProperty(Context.PROVIDER_URL,            "jnp://" + "localhost" + ":1099");
    final Context _context = new InitialContext();
    Object obj = _context.lookup("/jdbc/reformDS");
    if (null != obj) {
    System.out.println("OBJ: " + obj.getClass());
               org.apache.commons.dbcp.BasicDataSource ds = (org.apache.commons.dbcp.BasicDataSource)obj;
               JdbcTemplate jdbcTemplate2 = new JdbcTemplate(ds);
               String sql = String.format("update MESSAGE_LOG set PROCESS_INSTANCE_ID = 123456 where ID =42395 ");      
               int update = jdbcTemplate2.update(sql);
               System.out.println("Update*****************: " + update);
               }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 2018-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多