从 Jenkins 管道查询 MS Sql 服务器
Querying MS Sql Server from a Jenkins Pipeline
我一直在 docker 容器 (https://hub.docker.com/r/jenkins/jenkins) 中使用 Jenkins (2.289.3)。 Jenkins 2.312 的下一次更新将 docker 容器从 Java 8 迁移到 Java 11。
我有一些管道使用 sourceforge jdbc 驱动程序来查询 SQL 服务器 (http://jtds.sourceforge.net/)
示例:
import java.sql.DriverManager
import groovy.sql.Sql
con = DriverManager.getConnection('jdbc:jtds:sqlserver://servername', 'user', 'password');
stmt = con.createStatement();
为了使这个工作,在 Java 8 上的 Docker 容器中,我在 docker 容器
上 运行
cp jtds-1.3.1.jar ${JAVA_HOME}/jre/lib/ext
加载 jar 以在 Jenkins 中使用。此方法不再存在 Java 11.
管道似乎添加了@Grab 语法,例如
@Grab(group='net.sourceforge.jtds', module='jtds', version='1.3.1')
如果我将它添加到我的管道中,我可以看到 Jars 下载到 /var/jenkins_home/.groovy/grapes/ 但它似乎并没有真正加载 jar
java.lang.ClassNotFoundException: net.sourceforge.jtds.jdbc.Driver
要么
java.sql.SQLException: No suitable driver found for jdbc:jtds:sqlserver://servername
取决于我 运行 的命令。无论哪种方式,这似乎是由于未加载 jar。
所有 groovy 示例都使用
@GrabConfig(systemClassLoader=true)
但这似乎在管道中不受支持。
我考虑过使用命令行客户端,但我需要解析查询结果,但我还没有看到适合此操作的工具(即可以将结果加载到 json 文件或类似文件)
我也试过在 docker 容器中设置 -classpath 参数,例如
ENV JAVA_OPTS=-classpath /var/jenkins_home/test/jtds-1.3.1.jar
运行 ps
在 docker 容器中,我可以看到 java 进程 运行 指定了类路径命令行选项,但是它似乎并没有实际加载 jar 以供使用。
我对如何让它工作有点迷茫,有人可以帮忙吗?谢谢。
好吧,我找到了解决方法。看起来不太理想,但确实有效
原代码
import java.sql.DriverManager
import groovy.sql.Sql
con = DriverManager.getConnection('jdbc:jtds:sqlserver://servername', 'user', 'password');
stmt = con.createStatement();
假设我们将 jar 保存在 /var/jenkins_home/test/jtds-1.3.1.jar
中,它可以更新为:
import java.sql.DriverManager
import groovy.sql.Sql
def classLoader = this.class.classLoader
while (classLoader.parent) {
classLoader = classLoader.parent
if(classLoader.getClass() == java.net.URLClassLoader)
{
// load our jar into the urlclassloader
classLoader.addURL(new File("/var/jenkins_home/test/jtds-1.3.1.jar").toURI().toURL())
break;
}
}
// register the class
Class.forName("net.sourceforge.jtds.jdbc.Driver")
con = DriverManager.getConnection('jdbc:jtds:sqlserver://servername', 'user', 'password');
stmt = con.createStatement();
一旦此代码 运行 一次,jar 似乎就可以全局访问(即使在其他不加载 jar 的管道中)。
基于此,处理此问题的好方法似乎是在 Jenkins 初始化上,而不是在脚本中。我用这些内容创建了 /var/jenkins_home/init.groovy
:
def classLoader = this.class.classLoader
while (classLoader.parent) {
classLoader = classLoader.parent
if(classLoader.getClass() == java.net.URLClassLoader)
{
classLoader.addURL(new File("/var/jenkins_home/jars/jtds-1.3.1.jar").toURI().toURL())
break;
}
}
Class.forName("net.sourceforge.jtds.jdbc.Driver")
在那之后,脚本的行为似乎与我认为它应该如何与类路径中的 Jar 一起工作相似。
我一直在 docker 容器 (https://hub.docker.com/r/jenkins/jenkins) 中使用 Jenkins (2.289.3)。 Jenkins 2.312 的下一次更新将 docker 容器从 Java 8 迁移到 Java 11。
我有一些管道使用 sourceforge jdbc 驱动程序来查询 SQL 服务器 (http://jtds.sourceforge.net/)
示例:
import java.sql.DriverManager
import groovy.sql.Sql
con = DriverManager.getConnection('jdbc:jtds:sqlserver://servername', 'user', 'password');
stmt = con.createStatement();
为了使这个工作,在 Java 8 上的 Docker 容器中,我在 docker 容器
上 运行cp jtds-1.3.1.jar ${JAVA_HOME}/jre/lib/ext
加载 jar 以在 Jenkins 中使用。此方法不再存在 Java 11.
管道似乎添加了@Grab 语法,例如
@Grab(group='net.sourceforge.jtds', module='jtds', version='1.3.1')
如果我将它添加到我的管道中,我可以看到 Jars 下载到 /var/jenkins_home/.groovy/grapes/ 但它似乎并没有真正加载 jar
java.lang.ClassNotFoundException: net.sourceforge.jtds.jdbc.Driver
要么
java.sql.SQLException: No suitable driver found for jdbc:jtds:sqlserver://servername
取决于我 运行 的命令。无论哪种方式,这似乎是由于未加载 jar。
所有 groovy 示例都使用
@GrabConfig(systemClassLoader=true)
但这似乎在管道中不受支持。
我考虑过使用命令行客户端,但我需要解析查询结果,但我还没有看到适合此操作的工具(即可以将结果加载到 json 文件或类似文件)
我也试过在 docker 容器中设置 -classpath 参数,例如
ENV JAVA_OPTS=-classpath /var/jenkins_home/test/jtds-1.3.1.jar
运行 ps
在 docker 容器中,我可以看到 java 进程 运行 指定了类路径命令行选项,但是它似乎并没有实际加载 jar 以供使用。
我对如何让它工作有点迷茫,有人可以帮忙吗?谢谢。
好吧,我找到了解决方法。看起来不太理想,但确实有效
原代码
import java.sql.DriverManager
import groovy.sql.Sql
con = DriverManager.getConnection('jdbc:jtds:sqlserver://servername', 'user', 'password');
stmt = con.createStatement();
假设我们将 jar 保存在 /var/jenkins_home/test/jtds-1.3.1.jar
中,它可以更新为:
import java.sql.DriverManager
import groovy.sql.Sql
def classLoader = this.class.classLoader
while (classLoader.parent) {
classLoader = classLoader.parent
if(classLoader.getClass() == java.net.URLClassLoader)
{
// load our jar into the urlclassloader
classLoader.addURL(new File("/var/jenkins_home/test/jtds-1.3.1.jar").toURI().toURL())
break;
}
}
// register the class
Class.forName("net.sourceforge.jtds.jdbc.Driver")
con = DriverManager.getConnection('jdbc:jtds:sqlserver://servername', 'user', 'password');
stmt = con.createStatement();
一旦此代码 运行 一次,jar 似乎就可以全局访问(即使在其他不加载 jar 的管道中)。
基于此,处理此问题的好方法似乎是在 Jenkins 初始化上,而不是在脚本中。我用这些内容创建了 /var/jenkins_home/init.groovy
:
def classLoader = this.class.classLoader
while (classLoader.parent) {
classLoader = classLoader.parent
if(classLoader.getClass() == java.net.URLClassLoader)
{
classLoader.addURL(new File("/var/jenkins_home/jars/jtds-1.3.1.jar").toURI().toURL())
break;
}
}
Class.forName("net.sourceforge.jtds.jdbc.Driver")
在那之后,脚本的行为似乎与我认为它应该如何与类路径中的 Jar 一起工作相似。