Запрашивающая сторона не может установить соединение. Причал, Лифт/Scala, iSeries DB2/400

Я работаю над «Поваренной книгой по разработке приложений для лифтов» Гилберто Т. Гарсиа-младшего и столкнулся с проблемой, которую не могу решить. Я скопировал исходный код Chap06-map-table и пытаюсь изменить его для работы с моей базой данных IBM i (iSeries, AS/400, i5). Я смог заставить его работать с первым типом соединения, используя Squeryl Record. Однако я не могу понять, как заставить это работать с использованием источника данных JNDI. Я потратил пару дней на поиски в Интернете примеров такой настройки и не нашел хорошего примера, связанного с подключением к базе данных DB/400. Ниже приведена ошибка, которую я получаю, когда пытаюсь запустить контейнер, и код, который я изменил, чтобы заставить его работать. Любая помощь будет оценена по достоинству. Кажется, есть несколько вариантов класса источника данных из jt4oo.jar (jtOpen), и я не уверен, какой из них лучше использовать, или, возможно, есть другой. Я пробовал это с каждым из трех и предполагаю, что первый правильный.

com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource
com.ibm.as400.access.AS400JDBCConnectionPoolDataSource
com.ibm.as400.access.AS400JDBCDataSource

Спасибо. Боб

Это начало ошибки:

> container:start
[info] jetty-8.0.4.v20111024
[info] No Transaction manager found - if your webapp requires one, please config
ure one.
[info] NO JSP Support for /, did not find org.apache.jasper.servlet.JspServlet
[info] started o.e.j.w.WebAppContext{/,[file:/C:/Users/Bob/Lift26Projects/scala_
210/chap06-map-table/src/main/webapp/]}
[info] started o.e.j.w.WebAppContext{/,[file:/C:/Users/Bob/Lift26Projects/scala_
210/chap06-map-table/src/main/webapp/]}
18:21:47.062 [pool-7-thread-1] ERROR n.liftweb.http.provider.HTTPProvider - Fail
ed to Boot! Your application may not run properly
java.sql.SQLException: The application requester cannot establish the connection
. ("jdbc:as400://www.busapp.com;libraries=PLAY2TEST";naming=system;errors=full;)
        at com.ibm.as400.access.JDError.throwSQLException(JDError.java:524) ~[jt
400-6.7.jar:JTOpen 6.7]
        at com.ibm.as400.access.AS400JDBCConnection.setProperties(AS400JDBCConne
ction.java:3142) ~[jt400-6.7.jar:JTOpen 6.7]
        at com.ibm.as400.access.AS400JDBCManagedDataSource.createPhysicalConnect...

Мой файл Build.sbt:

name := "Lift 2.5 starter template"
version := "0.0.1"
organization := "net.liftweb"
scalaVersion := "2.10.0"
resolvers ++= Seq("snapshots" at "http://oss.sonatype.org/content/repositories/snapshots",
          "staging"         at "http://oss.sonatype.org/content/repositories/staging",
          "releases"        at "http://oss.sonatype.org/content/repositories/releases"
            )
seq(com.github.siasia.WebPlugin.webSettings :_*)
unmanagedResourceDirectories in Test <+= (baseDirectory) { _ / "src/main/webapp" }
scalacOptions ++= Seq("-deprecation", "-unchecked")
env in Compile := Some(file("./src/main/webapp/WEB-INF/jetty-env.xml") asFile)
libraryDependencies ++= {
  val liftVersion = "2.5"
  Seq(
    "net.liftweb"       %% "lift-webkit"        % liftVersion        % "compile",
    "net.liftmodules"   %% "lift-jquery-module_2.5" % "2.3",
    "org.eclipse.jetty"     % "jetty-webapp"       % "8.0.4.v20111024"  % "container",
    "org.eclipse.jetty"     % "jetty-plus"         % "8.0.4.v20111024"  % "container",
    "ch.qos.logback"    % "logback-classic"     % "1.0.6",
    "org.specs2"        %% "specs2"             % "1.14"           % "test",
    "net.liftweb"       %% "lift-squeryl-record" % liftVersion % "compile",
    "net.sf.jt400"    % "jt400"       % "6.7",
    "org.liquibase"    %  "liquibase-maven-plugin" % "3.0.2"
  )
}

Это мой файл boot.scala:

package bootstrap.liftweb

    import _root_.liquibase.database.DatabaseFactory
    import _root_.liquibase.database.jvm.JdbcConnection
    import _root_.liquibase.exception.DatabaseException
    import _root_.liquibase.Liquibase
    import _root_.liquibase.resource.FileSystemResourceAccessor
    import net.liftweb._
    import util._
    import Helpers._
    import common._
    import http._
    import sitemap._
    import Loc._
    import net.liftmodules.JQueryModule
    import net.liftweb.http.js.jquery._
    import net.liftweb.squerylrecord.SquerylRecord
    import org.squeryl.Session
    import java.sql.{SQLException, DriverManager}
    import org.squeryl.adapters.DB2Adapter
    import javax.naming.InitialContext
    import javax.sql.DataSource
    import code.model.LiftBookSchema
    /**
    * A class that's instantiated early and run.  It allows the application
    * to modify lift's environment
    */
    class Boot {
     def runChangeLog(ds: DataSource) {
     val connection = ds.getConnection
       try {
        val database = DatabaseFactory.getInstance().
         findCorrectDatabaseImplementation(new JdbcConnection(connection))
        val liquibase = new Liquibase(
        "database/changelog/db.changelog-master.xml",
        new FileSystemResourceAccessor(),
        database
        )

      liquibase.update(null)
      } catch {
        case e: SQLException => {
         connection.rollback()
         throw new DatabaseException(e)
       }
     }
    }
    def boot {

    // where to search snippet
    LiftRules.addToPackages("code")

    prepareDb()


    // Build SiteMap
    val entries = List(
      Menu.i("Home") / "index", // the simple way to declare a menu

      // more complex because this menu allows anything in the
      // /static path to be visible
      Menu(Loc("Static", Link(List("static"), true, "/static/index"),
        "Static Content")))

    // set the sitemap.  Note if you don't want access control for
    // each page, just comment this line out.
    LiftRules.setSiteMap(SiteMap(entries: _*))

    //Show the spinny image when an Ajax call starts
    LiftRules.ajaxStart =
      Full(() => LiftRules.jsArtifacts.show("ajax-loader").cmd)

    // Make the spinny image go away when it ends
    LiftRules.ajaxEnd =
      Full(() => LiftRules.jsArtifacts.hide("ajax-loader").cmd)

    // Force the request to be UTF-8
    LiftRules.early.append(_.setCharacterEncoding("UTF-8"))

    // Use HTML5 for rendering
    LiftRules.htmlProperties.default.set((r: Req) =>
      new Html5Properties(r.userAgent))

    //Init the jQuery module, see http://liftweb.net/jquery for more information.
    LiftRules.jsArtifacts = JQueryArtifacts
    JQueryModule.InitParam.JQuery = JQueryModule.JQuery172
    JQueryModule.init()

  }

  def prepareDb() {

    Class.forName("com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource")

    val ds = new InitialContext().lookup("java:/comp/env/jdbc/dsliftbook").asInstanceOf[DataSource]

    runChangeLog(ds)

    SquerylRecord.initWithSquerylSession(
      Session.create(
        ds.getConnection,
        new DB2Adapter)
    )
  }


}

Это мой файл jetty-env-xml

<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
    <New id="dsliftbook" class="org.eclipse.jetty.plus.jndi.Resource">
   <Arg></Arg>
   <Arg>jdbc/dsliftbook</Arg>
   <Arg>
      <New class="com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource">
         <Set name="serverName">"jdbc:as400://www.[server].com;libraries=PLAY2TEST";naming=system;errors=full;</Set>
         <Set name="user">[user]</Set>
         <Set name="password">[password]</Set>
       </New>
   </Arg>
    </New>
</Configure>

person Bob Nicholson    schedule 16.12.2013    source источник
comment
Вы получаете SQLException от драйвера JDBC, говорящего вам, что он не может подключиться к базе данных. Убедитесь, что ваш URL, имя пользователя и пароль указаны правильно. Если они выглядят правильно, попробуйте подключиться к серверу с компьютера, на котором запущено ваше приложение, без использования Java, и посмотрите, удастся ли это. Вы также можете найти дополнительную информацию о том, почему db отказывается от соединений в журналах db.   -  person Dave Whittaker    schedule 16.12.2013
comment
Цитата кажется неуместной в вашей базе данных uri: "jdbc:as400://www.[server].com;libraries=PLAY2TEST";naming=system;errors=full; должно быть "jdbc:as400://www.[server].com;libraries=PLAY2TEST;naming=system;errors=full;"   -  person James Allman    schedule 16.12.2013
comment
Я исправил цитату, фактически удалил их полностью. Все еще не работает. Для соединения без источника данных работает следующее. import org.squeryl.Session import org.squeryl.adapters.DB2Adapter import net.liftweb.squerylrecord.SquerylRecord Class.forName("com.ibm.as400.access.AS400JDBCDriver") def connection = DriverManager.getConnection("jdbc:as400://www.{server].com/;naming=1; libraries=PLAY2TEST;", "[user]", "[password]") SquerylRecord.initWithSquerylSession(Session.create(connection, new DB2Adapter))   -  person Bob Nicholson    schedule 16.12.2013


Ответы (1)


Хорошо, мне удалось подключиться. Одной из проблем были кавычки в файле jetty-env-xml. И имя пользователя/пароль, которые я использовал, по-видимому, не обладали полномочиями, необходимыми для выполнения этой работы. Я не уверен, почему, поскольку это тот же самый идентификатор/пароль, который я использую для всех своих разработок iSeries. Так что на данный момент я являюсь еще одним профилем пользователя с полномочиями сотрудника службы безопасности, пока не смогу выяснить, что происходит или какие полномочия требуются.

Как только я вошел в систему, я не смог установить список библиотек для пользователя, и это приводило к сбою SQL. Он искал имя библиотеки, совпадающее с идентификатором пользователя. На данный момент я обошел эту проблему, создав новую библиотеку с таким же именем, как и идентификатор пользователя.

Еще одна проблема заключается в том, что, несмотря на то, что я предоставляю и идентификатор, и пароль, мне предлагается ввести идентификатор и пароль перед подключением. Идентификатор и URL-адрес заполняются, но пароль всегда нужно вводить повторно.

Я включил текущий исходный код для файла jetty-env-xml и файла boot.scala. Надеюсь, это может помочь другим.

Спасибо Дейву и Джеймсу за помощь!

Боб

boot.scala:

package bootstrap.liftweb

// import _root_.liquibase.database.DatabaseFactory
// import _root_.liquibase.database.jvm.JdbcConnection
// import _root_.liquibase.exception.DatabaseException
// import _root_.liquibase.Liquibase
// import _root_.liquibase.resource.FileSystemResourceAccessor
import net.liftweb._
import util._
import Helpers._

import common._
import http._
import sitemap._
import Loc._
import net.liftmodules.JQueryModule
import net.liftweb.http.js.jquery._
import net.liftweb.squerylrecord.SquerylRecord
import org.squeryl.Session
import java.sql.{SQLException, DriverManager}
import org.squeryl.adapters.DB2Adapter
import javax.naming.InitialContext
import javax.sql.DataSource
import code.model.LiftBookSchema
import com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource



/**
 * A class that's instantiated early and run.  It allows the application
 * to modify lift's environment
 */
class Boot {
  // def runChangeLog(ds: DataSource) {
  //   val connection = ds.getConnection

  //   try {
  //     val database = DatabaseFactory.getInstance().
  //       findCorrectDatabaseImplementation(new JdbcConnection(connection))

  //     val liquibase = new Liquibase(
  //       "database/changelog/db.changelog-master.xml",
  //       new FileSystemResourceAccessor(),
  //       database
  //     )

  //     liquibase.update(null)
  //   } catch {
  //     case e: SQLException => {
  //       connection.rollback()
  //       throw new DatabaseException(e)
  //     }
  //   }
  // }

  def boot {

    // where to search snippet
    LiftRules.addToPackages("code")

    prepareDb()


    // Build SiteMap
    val entries = List(
      Menu.i("Home") / "index", // the simple way to declare a menu

      // more complex because this menu allows anything in the
      // /static path to be visible
      Menu(Loc("Static", Link(List("static"), true, "/static/index"),
        "Static Content")))

    // set the sitemap.  Note if you don't want access control for
    // each page, just comment this line out.
    LiftRules.setSiteMap(SiteMap(entries: _*))

    //Show the spinny image when an Ajax call starts
    LiftRules.ajaxStart =
      Full(() => LiftRules.jsArtifacts.show("ajax-loader").cmd)

    // Make the spinny image go away when it ends
    LiftRules.ajaxEnd =
      Full(() => LiftRules.jsArtifacts.hide("ajax-loader").cmd)

    // Force the request to be UTF-8
    LiftRules.early.append(_.setCharacterEncoding("UTF-8"))

    // Use HTML5 for rendering
    LiftRules.htmlProperties.default.set((r: Req) =>
      new Html5Properties(r.userAgent))

    //Init the jQuery module, see http://liftweb.net/jquery for more information.
    LiftRules.jsArtifacts = JQueryArtifacts
    JQueryModule.InitParam.JQuery = JQueryModule.JQuery172
    JQueryModule.init()

  }

  def prepareDb() {

    Class.forName("com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource")

    val ds = new InitialContext().lookup("java:/comp/env/jdbc/dsliftbook").asInstanceOf[DataSource]

    // runChangeLog(ds)

    SquerylRecord.initWithSquerylSession(Session.create(ds.getConnection, new DB2Adapter)
    )
  }
}

причал-env-xml

<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
    <New id="dsliftbook" class="org.eclipse.jetty.plus.jndi.Resource">
   <Arg></Arg>
   <Arg>jdbc/dsliftbook</Arg>
   <Arg>
      <New class="com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource">
         <Set name="serverName">www.[server].com</Set>
         <Set name="user">DBUSER</Set>
         <Set name="password">DBUSER</Set>
      </New>
   </Arg>
    </New>
</Configure>
person Bob Nicholson    schedule 17.12.2013
comment
Я также смог войти в систему как QUSER. Кажется, что-то отличалось от моего профиля, что мешало мне использовать его для входа в систему. - person Bob Nicholson; 18.12.2013