私が間違っているかもしれないことを理解していません。
このチュートリアルに従って、ステートフル サーブレットを実装しようとしています。
私の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 がセットアップされると、その後の呼び出しでそれを使用できると期待していました。
誰かが親切に助けてくれます.チュートリアルから後者への指示に従ったので、どこが間違っているのかわかりません.
できるだけ多くの情報を過去のものにしようとしましたが、必要に応じてさらに追加したいと思います。
ありがとうございました。