在 Python Flask Cloud Foundry/IBM Cloud 应用程序中添加 Java/JRE/JVM

Posted

技术标签:

【中文标题】在 Python Flask Cloud Foundry/IBM Cloud 应用程序中添加 Java/JRE/JVM【英文标题】:Add Java/JRE/JVM in Python Flask Cloud Foundry/IBM Cloud application 【发布时间】:2018-01-20 12:43:13 【问题描述】:

我在 Cloud Foundry/IBM Cloud 环境中运行 python 烧瓶应用程序。在我的应用程序中,我尝试使用 IBMDBPY 包连接到 DB2 Warehouse on Cloud。这个包需要一个名为 jaydebeapi 的包才能运行。为了让 jaydebeapi 工作,我想我需要以某种方式在服务器上安装 JRE/JVM。我尝试为基于 Linux 的操作系统添加 Server JRE,但它也不起作用。我在尝试上传 Sever JRE 之前遇到的错误是:

idadb = IdaDataBase(dsn=jdbc) #Establish a connection to our DB2-service
1/20/2018 12:05:45 PM   ERR undefined   File "/home/vcap/deps/0/python./lib/python2.7/site-packages/ibmdbpy/base.py", line 282, in __init__
1/20/2018 12:05:45 PM   ERR undefined jpype.startJVM(jpype.getDefaultJVMPath(), '-Djava.class.path=%s' % jarpath)
1/20/2018 12:05:45 PM   ERR undefined   File "/home/vcap/deps/0/python/lib/python2.7/site-packages/jpype/_core.py", line 114, in get_default_jvm_path
1/20/2018 12:05:45 PM   ERR undefined   return finder.get_jvm_path()
1/20/2018 12:05:45 PM   ERR undefined   File "/home/vcap/deps/0/python/lib/python2.7/site-packages/jpype/_jvmfinder.py", line 121, in get_jvm_path
1/20/2018 12:05:45 PM   ERR undefined   jvm = method()
1/20/2018 12:05:45 PM   ERR undefined   File "/home/vcap/deps/0/python/lib/python2.7/site-packages/jpype/_jvmfinder.py", line 164, in _get_from_known_locations
1/20/2018 12:05:45 PM   ERR undefined   for home in self.find_possible_homes(self._locations):
1/20/2018 12:05:45 PM   ERR undefined   File "/home/vcap/deps/0/python/lib/python2.7/site-packages/jpype/_jvmfinder.py", line 95, in find_possible_homes
1/20/2018 12:05:45 PM   ERR undefined   for childname in sorted(os.listdir(parent)):
1/20/2018 12:05:45 PM   ERR undefined   OSError: [Errno 2] No such file or directory: '/usr/lib/jvm'
1/20/2018 12:05:46 PM   OUT undefined   Exit status 1

有谁知道我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

经过多次试验和错误,对我有用的解决方案是多构建包部署,如下所述:

cf push -b https://github.com/cloudfoundry/multi-buildpack

并在项目的根目录中包含 multi-buildpack.yml 和以下内容

buildpacks:
  - https://github.com/cloudfoundry/apt-buildpack
  - https://github.com/cloudfoundry/python-buildpack

还有一个apt.yml,内容如下:

--- 
packages: openjdk-8-jre
repos: deb http://ppa.launchpad.net/openjdk-r/ppa/ubuntu trusty main
keys: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xEB9B1D8886F44E2A

runtime.txt文件中,(也在项目的根目录下)是python的版本 python-3.6.6

不幸的是,JAVA 安装在您的home deps 目录中,因此您必须在manifest.yml 中创建一个JAVA_HOME 环境变量。

JAVA_HOME: /home/vcap/deps/0/apt/usr/lib/jvm/java-8-openjdk-amd64/jre/

我也试过以这种方式将 jre/bin 添加到路径中

PATH: /bin:/usr/bin:/home/vcap/deps/0/apt/usr/lib/jvm/java-8-openjdk-amd64/jre/bin

但是,推送将其清除并仅安装默认路径 /bin;/usr/bin,幸运的是,JAVA_HOME 足以让 jaydebapi 与我拥有的 jar 文件的数据库驱动程序一起使用。如果你需要这个环境变量, 也许尝试使用python os 包发出命令来修改路径作为启动的一部分。

【讨论】:

我也有类似的情况。该应用程序使用的是 tabula-py,它是 tabula-java 的包装器,需要在 python 子进程中调用 java。我尝试了各种使用 JAVA_HOME、PYTHONPATH、附加到 sys.path、os.join 的选项,但都没有奏效。将 .profile 文件添加到应用程序并使用 jre 安装路径导出 PATH 的简单解决方案解决了该问题。【参考方案2】:

包括一个更现代的答案。在我写这篇文章时,您遇到的大多数(所有值得使用的)Cloud Foundry 版本都将支持多个开箱即用的构建包。因此,您不再需要 multi-buildpack buildpack。

相反,您可以简单地cf push 并指定多个构建包。

https://docs.cloudfoundry.org/buildpacks/use-multiple-buildpacks.html

这可以通过将多个-b 标志设置为cf push 或使用manifest.yml 文件并执行以下操作来完成:

...
buildpacks:
  - buildpack_1
  - buildpack_2
...

无论哪种情况,都按照您列出的顺序执行。

https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#buildpack

其余答案与@lamonaki 的答案相同。

按顺序调用 apt-buildpack 和 Python buildpack。

添加apt.yml 文件并在其中指明您要安装的Java 包。

来自@lamonaki 的回答:

--- 
packages: openjdk-8-jre
repos: deb http://ppa.launchpad.net/openjdk-r/ppa/ubuntu trusty main
keys: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xEB9B1D8886F44E2A

添加runtime.txt 设置您要安装的 Python 版本

.profile 文件添加到项目的根目录,就像apt.ymlruntime.txt。如果您需要在 Java 或 Python 代码中引用任何自定义共享库,请在其中添加 export JAVA_HOME=/home/vcap/deps/0/apt/usr/lib/jvm/java-8-openjdk-amd64/jre/export PATH=$PATH:$JAVA_HOME/bin 以及可能的 LD_LIBRARY_PATH 行。

您可能会想,为什么使用 apt-buildpack 而不是 Java buildpack。不幸的是,当前版本的 Java buildpack 仅支持作为最终 buildpack(即 buildpack 列表中的最后一个 buildpack)运行。这排除了它作为一个很好的候选者,因为你希望 Python buildpack 是最后的。 Java Cloud Native Buildpacks 将解决这个问题,但在我写这篇文章时,没有在 CF 上本地运行的 Cloud Native Buildpacks。

【讨论】:

以上是关于在 Python Flask Cloud Foundry/IBM Cloud 应用程序中添加 Java/JRE/JVM的主要内容,如果未能解决你的问题,请参考以下文章

重复的日志 Flask - Google Cloud Logging

Google App Engine - 大查询 - Python 找不到库 google.cloud

使用 Google Cloud Endpoints 时如何重启 Flask 服务器?

Cloud Run Flask API 容器运行 shutit 进入休眠循环

Google Cloud Run (GCR) 的 Gunicorn (with Flask) 参数 - 在 Dockerfile 中放置啥? [关闭]

如何从不具有BlobStore的Flask表单直接将视频文件上传到Cloud Storage?