【问题标题】:System environment variables in Jetty applicationJetty 应用程序中的系统环境变量
【发布时间】:2015-02-23 12:38:04
【问题描述】:

如何在一个 Jetty 应用程序中配置系统环境变量?

例如对于数据库连接的详细信息,将其放在文件中并将其检入 cvs 是个坏主意。因此,使用系统环境是一种方法。虽然系统环境变量在 /etc/environments 文件或 .bashrc/.zshrc 文件中定义,但在 Jetty 应用程序中,执行 System.getenv("variable_name") 不会给出任何结果。这将导致 null。

我已经阅读了这个问题:Configuring a Jetty application with env variables,它得出的结论是,Jetty 不支持System.getenv(),甚至在start.ini 文件中也不支持。

还有jetty and etc environment on ubuntu 12.10,上面写着In the jetty.sh script you can source the /etc/environment file and they will be present.,我试过但没有得到预期的值,这意味着它只给了我null。

如果我不能使用默认的System.getenv() 或任何.ini 文件,那么如何指定数据库连接等凭据?

【问题讨论】:

    标签: java jetty environment-variables jetty-9


    【解决方案1】:

    不支持System.getenv()不是Jetty的事情,而是Java的事情。

    System.getenv() 和您的环境有很多限制,除了最幼稚和基本的测试用例外,它几乎毫无用处。 (例如:不支持多行值。多行条目可能会破坏解析。不支持没有值的键。在解析过程中,没有值的键通常可以与下一个键合并。不支持具有非 US-ASCII 字符的条目。具有控制字符的条目是不支持。)

    在 Java 程序中使用系统环境变量时的常用技术是使用特定于 shell 的技术来获取值并将它们注入命令行,或注入 ini 文件格式供 Jetty 使用。

    根据您的技术,这些值将显示为 Jetty 属性或 Java 系统属性。

    刚刚创建了一个项目来演示实现此目的的 4 种方法

    https://github.com/jetty-project/jetty-external-config

    Jetty 的外部配置属性

    演示如何配置可访问的简单属性 通过 Jetty 中的 Servlet。

    此演示展示了配置属性的 4 种不同方法 在运行时,然后可以由运行在其中的 Servlet 读取 码头。

    道具战争

    这是一个简单的war文件,有一个HttpServlet和一个WEB-INF/web.xml

    [jetty-external-config]$ jar -tvf target/props.war 
         0 Mon Feb 23 09:02:14 MST 2015 META-INF/
       131 Mon Feb 23 09:02:14 MST 2015 META-INF/MANIFEST.MF
         0 Mon Feb 23 09:02:14 MST 2015 WEB-INF/
         0 Mon Feb 23 09:02:14 MST 2015 WEB-INF/classes/
         0 Mon Feb 23 09:02:14 MST 2015 WEB-INF/classes/org/
         0 Mon Feb 23 09:02:14 MST 2015 WEB-INF/classes/org/eclipse/
         0 Mon Feb 23 09:02:14 MST 2015 WEB-INF/classes/org/eclipse/demo/
      2188 Mon Feb 23 09:02:12 MST 2015 WEB-INF/classes/org/eclipse/demo/PropsServlet.class
       572 Mon Feb 23 08:45:22 MST 2015 WEB-INF/web.xml
    

    有关行为的详细信息,请参阅 PropsServlet.java。

    只需编译顶层,war 文件将被构建并放置在该项目的所有演示 jetty.base 位置。

    示例 #1:基本命令行

    /base-command-line 项目包含一个简单的start.ini,它在端口 9090 上启动码头,并部署 webapp。磁盘配置没有额外的配置。

    如果你这样启动它......

    [base-command-line]$ java -jar /path/to/jetty-distribution-9.2.7.v20150116/start.jar
    2015-02-23 09:15:46.088:INFO::main: Logging initialized @290ms
    2015-02-23 09:15:46.222:INFO:oejs.Server:main: jetty-9.2.7.v20150116
    2015-02-23 09:15:46.235:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/home/joakim/code/stackoverflow/jetty-external-config/base-command-line/webapps/] at interval 1
    2015-02-23 09:15:46.325:INFO:oejw.StandardDescriptorProcessor:main: NO JSP Support for /props, did not find org.eclipse.jetty.jsp.JettyJspServlet
    2015-02-23 09:15:46.343:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@6e7f61a3{/props,file:/tmp/jetty-0.0.0.0-9090-props.war-_props-any-27537844855769703.dir/webapp/,AVAILABLE}{/props.war}
    2015-02-23 09:15:46.353:INFO:oejs.ServerConnector:main: Started ServerConnector@67cd35c5{HTTP/1.1}{0.0.0.0:9090}
    2015-02-23 09:15:46.353:INFO:oejs.Server:main: Started @555ms
    

    您会看到它已启动并部署到 /props 上下文路径。

    您可以在此处通过wgetcurl 等工具测试servlet 中的属性。

    例子:

    $ curl http://localhost:9090/props/props
    
    [java.runtime.name] = Java(TM) SE Runtime Environment
    [sun.boot.library.path] = /home/joakim/java/jvm/jdk-7u75-x64/jre/lib/amd64
    [java.vm.version] = 24.75-b04
    [java.vm.vendor] = Oracle Corporation
    [java.vendor.url] = http://java.oracle.com/
    ...
    [file.separator] = /
    [java.vendor.url.bug] = http://bugreport.sun.com/bugreport/
    [sun.io.unicode.encoding] = UnicodeLittle
    [sun.cpu.endian] = little
    [sun.desktop] = gnome
    [sun.cpu.isalist] = 
    

    您甚至可以请求特定的属性..

    $ curl http://localhost:9090/props/props/user.timezone
    [user.timezone] = America/Phoenix
    

    让我们停止服务器并使用我们选择的系统属性运行它。

    注意-Dfoo=bar

    [base-command-line]$ java -Dfoo=bar -jar /path/to/jetty-distribution-9.2.7.v20150116/start.jar
    2015-02-23 09:15:46.088:INFO::main: Logging initialized @290ms
    2015-02-23 09:15:46.222:INFO:oejs.Server:main: jetty-9.2.7.v20150116
    2015-02-23 09:15:46.235:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/home/joakim/code/stackoverflow/jetty-external-config/base-command-line/webapps/] at interval 1
    2015-02-23 09:15:46.325:INFO:oejw.StandardDescriptorProcessor:main: NO JSP Support for /props, did not find org.eclipse.jetty.jsp.JettyJspServlet
    2015-02-23 09:15:46.343:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@6e7f61a3{/props,file:/tmp/jetty-0.0.0.0-9090-props.war-_props-any-27537844855769703.dir/webapp/,AVAILABLE}{/props.war}
    2015-02-23 09:15:46.353:INFO:oejs.ServerConnector:main: Started ServerConnector@67cd35c5{HTTP/1.1}{0.0.0.0:9090}
    2015-02-23 09:15:46.353:INFO:oejs.Server:main: Started @555ms
    

    并通过 curl 查找它...

    $ curl http://localhost:9090/props/props/foo
    [foo] = bar
    

    这演示了对通过命令行指定的属性的访问,现在让我们看看其他选择。

    示例 #2:使用 start.ini

    /base-startini 项目包含一个简单的start.ini,它在端口 9090 上启动码头,并部署 webapp。

    这个start.ini 还包含一个foo.ish 属性。

    让我们启动 Jetty 并再次尝试我们的 props servlet 访问...

    [base-startini]$ java -jar /path/to/jetty-distribution-9.2.7.v20150116/start.jar
    2015-02-23 09:16:46.088:INFO::main: Logging initialized @290ms
    2015-02-23 09:16:46.222:INFO:oejs.Server:main: jetty-9.2.7.v20150116
    

    并通过 curl 请求它...

    $ curl http://localhost:9090/props/props/foo.ish
    [foo.ish] = bar
    

    示例 #3:使用 start.d 可选 ini

    /base-startd 项目包含一个简单的start.ini,它在端口 9090 上启动码头,并部署 webapp。

    这个start.ini 也不包含我们感兴趣的额外属性。

    start.d/myconf.ini 包含一个我们感兴趣的名为 foo.d 的属性。

    让我们启动 Jetty 并再次尝试我们的 props servlet 访问...

    [base-startd]$ java -jar /path/to/jetty-distribution-9.2.7.v20150116/start.jar
    2015-02-23 09:19:46.088:INFO::main: Logging initialized @290ms
    2015-02-23 09:19:46.222:INFO:oejs.Server:main: jetty-9.2.7.v20150116
    

    并通过 curl 请求它...

    $ curl http://localhost:9090/props/props/foo.d
    [foo.d] = over here
    

    示例 #4:使用 --include-jetty-dir 可选配置

    /base-jettyinclude 项目包含一个新的start.ini,它在端口 9090 上启动码头,并部署 webapp。

    这个start.ini 也不包含我们感兴趣的额外属性。

    但是,start.ini 使用指向全新临时 jetty.base 配置源的 --include-jetty-dir=../jettydir 可选配置。

    ../jettydir/start.ini 包含一个我们感兴趣的名为 foo.jetty.dir 的属性。

    让我们启动 Jetty 并再次尝试我们的 props servlet 访问...

    [base-jettyinclude]$ java -jar /path/to/jetty-distribution-9.2.7.v20150116/start.jar
    2015-02-23 09:24:46.088:INFO::main: Logging initialized @290ms
    2015-02-23 09:24:46.222:INFO:oejs.Server:main: jetty-9.2.7.v20150116
    

    并通过 curl 请求它...

    $ curl http://localhost:9090/props/props/foo.jetty.dir
    [foo.jetty.dir] = more of the same
    

    【讨论】:

    • 在这个问题中 stackoverflow.com/questions/27157904/… System.getProperties().contains("dbhost") - 但既不添加 dbhost="localhost" 也不 -Ddbhost="localhost"start.ini 文件工作`所以将它们提供给 start.ini 文件也无济于事,因为我已经从该评论中尝试过。您可以编辑您的答案并包含一个关于如何执行您建议的小脚本吗?
    • “不支持 System.getenv() 不是 Jetty 的东西,而是 Java 的东西”,我查看了 docs.oracle.com/javase/7/docs/api/java/lang/… 并没有看到任何证据表明环境变量是“Java 的东西”不支持?还是我误解了?它们是否是一个好主意与它们是否受到支持是不一样的。这似乎是 Jetty 特定的东西,它们不受支持。
    • getenv() 已经是removed, then added,然后再次删除,然后再次添加。它的问题由来已久,即使在今天仍然不稳定。
    • @JoakimErdfelt 很棒的帖子。感谢您提供详细指南和示例。
    猜你喜欢
    • 2014-11-06
    • 2015-08-20
    • 2015-09-16
    • 1970-01-01
    • 2012-08-09
    • 2012-03-29
    • 2019-01-19
    • 2017-07-16
    • 2015-09-12
    相关资源
    最近更新 更多