0

私が間違っているかもしれないことを理解していません。

このチュートリアルに従って、ステートフル サーブレットを実装しようとしています。

私のorg.apache.xmlrpc.webserver.XmlRpcServlet.propertiesは次のようになります。

com.mydbm.MyDBM=com.mydbm.MyDBMImpl

これは MyDBM インターフェイスと MyDBMImpl コードです:

public interface MyDBM {
  public void setUp(DBConnection dbc) throws ClassNotFoundException, 
       SQLException, JSchException;

   public ArrayList<Database> getDatabases() throws SQLException; 

  .....
}
public class MyDBMImpl implements MyDBM {
private volatile Connection connection;
private volatile Class<?> driverClass;
private volatile Statement statement;
private volatile DBConnection dbConn;

@Override
public void setUp(DBConnection dbc) throws ClassNotFoundException,
        SQLException, JSchException {
    this.dbConn = dbc;
    if (dbConn.SSHEnabled()) {
        LOG.info("SSH Requested, enabling...");
        setUpSshConnection();
        LOG.info("SSH enabled!");
    } else {
        LOG.info("SSH not Requested, skipping...");
    }
    setupConnection();


}   
    .....

    @Override
public ArrayList<Database> getDatabases() throws SQLException {

    switch (dbConn.getDatabaseType()) {  // NULL POINTER EXCEPTION HERE, 
    case MYSQL:
        return getDatabasesMySQL();
    case MSSQLSERVER:
        return getDatabasesMSServerSQL();
    case SQLITE:
        return getDatabasesSQLite();
    case SYBASE:
        return getDatabasesSyBase();
    case POSTGRESQL:
        return getDatabasesPostgreSQL();
    case ORACLE:
        return getDatabasesOracle();
    }
    return null;
}

以下は私のハンドラーコードです:

public class MyDBMXmlRpcRequestProcessorFactoryFactory implements
    RequestProcessorFactoryFactory {
private final RequestProcessorFactory factory = new MyDBMRequestProcessorFactory();
private final MyDBM dbm;

public MyDBMXmlRpcRequestProcessorFactoryFactory(
        MyDBM dbm) {
    this.dbm = dbm;
}

@Override
public RequestProcessorFactory getRequestProcessorFactory(Class aClass)
        throws XmlRpcException {
    return factory;
}

private class MyDBMRequestProcessorFactory implements
        RequestProcessorFactory {
    @Override
    public Object getRequestProcessor(XmlRpcRequest xmlRpcRequest)
            throws XmlRpcException {
        return dbm;
    }
}

}

これは私のサーバーコードです:

    public class Server {
private static final int port = 8080;

public static void main(String[] args) throws Exception {
    WebServer webServer = new WebServer(port);
    XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();
    PropertyHandlerMapping phm = new PropertyHandlerMapping();

    MyDBM dbm = new MyDBMImpl();
    phm.setRequestProcessorFactoryFactory(new   MyDBMXmlRpcRequestProcessorFactoryFactory(
            dbm));
    phm.setVoidMethodEnabled(true);
    phm.addHandler(MyDBM.class.getName(),
            MyDBM.class);
    xmlRpcServer.setHandlerMapping(phm);

    XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer
            .getConfig();
    serverConfig.setEnabledForExtensions(true);
    serverConfig.setContentLengthOptional(false);
    webServer.start();

}

}

web.xml コンテンツの抽出:

<web-app>
<!-- SOME PARTS LEFT OUT ->
<servlet>
<servlet-name>XmlRpcServlet</servlet-name>
<servlet-class>org.apache.xmlrpc.webserver.XmlRpcServlet</servlet-class>
<init-param>
  <param-name>enabledForExtensions</param-name>
  <param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>XmlRpcServlet</servlet-name>
<url-pattern>/xmlrpc</url-pattern>
</servlet-mapping>
</web-app>

そして最後に、これが私のクライアント コードです。

public class MyClient {


  public static void main(String[] args) throws Exception {
      // create configuration
      XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
      config.setServerURL(new URL("http://127.0.0.1:8080/xmlrpctest/xmlrpc"));
      config.setEnabledForExtensions(true);  
      config.setConnectionTimeout(60 * 1000);
      config.setReplyTimeout(60 * 1000);

      XmlRpcClient client = new XmlRpcClient();

      // use Commons HttpClient as transport
      client.setTransportFactory(
          new XmlRpcCommonsTransportFactory(client));
      // set configuration
      client.setConfig(config);
           // make a call using dynamic proxy
      ClientFactory factory = new ClientFactory(client);

      MyDBM dbm = (MyDBM)factory.newInstance(MyDBM.class);
      try {
       dbm.setUp(new DBConnection("myconn", DatabaseType.MYSQL, "localhost", 0, "userid", "secret", "mysql")); // Connection is setup correctly
       ArrayList<Database> dbs = dbm.getDatabases(); // Fails with NullPointerException

      } catch(Exception e) {
          System.out.println(e.getCause().getMessage());
          e.printStackTrace();
      }
  }

}

エラーログ:

Sep 27, 2013 11:49:26 AM com.myapp.MyDBMImpl setUp
INFO: SSH not Requested, skipping...
jdbc:mysql://localhost/mysql?user=userid&password=secret
Sep 27, 2013 11:49:26 AM org.apache.xmlrpc.server.XmlRpcErrorLogger log
SEVERE: Failed to invoke method getDatabases in class com.myapp.MyDBMImpl: null
org.apache.xmlrpc.common.XmlRpcInvocationException: Failed to invoke method  getDatabases in class com.myapp.MyDBMImpl: null

dbm.setUp(..) メソッドが正しく実行され、サーバー上に dbConn オブジェクトが作成されます。ただし、dbm.getDatabases() を実行すると、null ポインター例外が発生します。これは、サーバーがハンドラーの初期状態を使用する代わりに、ハンドラーの新しいインスタンスを作成するためだと思います。私はこれの専門家ではありませんが、このチュートリアルから、dbConn がセットアップされると、その後の呼び出しでそれを使用できると期待していました。

誰かが親切に助けてくれます.チュートリアルから後者への指示に従ったので、どこが間違っているのかわかりません.

できるだけ多くの情報を過去のものにしようとしましたが、必要に応じてさらに追加したいと思います。

ありがとうございました。

4

1 に答える 1

0

はい、あなたの問題は、サーバーが毎回新しいインスタンスを作成することです。私は同じ問題に遭遇し、以前のハンドラーのインスタンスを呼び出す追加のハンドラー クラスで解決しました。

このようなもの:

public class MyDBMXmlRpcRequestProcessorFactoryFactoryWrapper
{
   private MyDBMXmlRpcRequestProcessorFactoryFactoryWrapper attribute;
   public MyDBMXmlRpcRequestProcessorFactoryFactoryWrapper(class param)
   {
        attribute = MyDBMXmlRpcRequestProcessorFactoryFactory(param);
   }
}
于 2013-12-15T20:24:39.240 に答える