`

Read environment variables from an application[转]

    博客分类:
  • Java
阅读更多

从应用程序获取环境变量Read environment variables from an application

 

NOTE: JDK1.5 or better provides a simpler way to achieve this, see this HowTo .

JDK up to 1.4
Start the JVM with the "-D" switch to pass properties to the application and read them with the System.getProperty() method.

SET myvar=Hello world
SET myothervar=nothing
java -Dmyvar="%myvar%" -Dmyothervar="%myothervar%" myClass

then in myClass

String myvar = System.getProperty("myvar");
String myothervar = System.getProperty("myothervar");

If you don't know in advance, the name of the variable to be passed to the JVM, then there is no 100% Java way to retrieve them.


One approach (not the easiest one), is to use a JNI call to fetch the variables, see this HowTo .


A more low-tech way, is to launch the appropriate call to the operating system and capture the output. The following snippet puts all environment variables in a Properties class and display the value the TEMP variable.

import java.io.*;
import java.util.*;

public class ReadEnv {
 public static Properties getEnvVars() throws Throwable {
  Process p = null;
  Properties envVars = new Properties();
  Runtime r = Runtime.getRuntime();
  String OS = System.getProperty("os.name").toLowerCase();
  // System.out.println(OS);
  if (OS.indexOf("windows 9") > -1) {
    p = r.exec( "command.com /c set" );
    }
  else if ( (OS.indexOf("nt") > -1)
         || (OS.indexOf("windows 2000") > -1 )
         || (OS.indexOf("windows xp") > -1) ) {
    // thanks to JuanFran for the xp fix!
    p = r.exec( "cmd.exe /c set" );
    }
  else {
    // our last hope, we assume Unix (thanks to H. Ware for the fix)
    p = r.exec( "env" );
    }
  BufferedReader br = new BufferedReader
     ( new InputStreamReader( p.getInputStream() ) );
  String line;
  while( (line = br.readLine()) != null ) {
   int idx = line.indexOf( '=' );
   String key = line.substring( 0, idx );
   String value = line.substring( idx+1 );
   envVars.setProperty( key, value );
   // System.out.println( key + " = " + value );
   }
  return envVars;
  }

  public static void main(String args[]) {
   try {
     Properties p = ReadEnv.getEnvVars();
     System.out.println("the current value of TEMP is : " +
        p.getProperty("TEMP"));
     }
   catch (Throwable e) {
     e.printStackTrace();
     }
   }
}

thanks to w.rijnders for the w2k fix.


An update from Van Ly :

I found that, on Windows 2003 server, the property value for "os.name" is actually "windows 2003." So either that has to be added to the bunch of tests or just relax the comparison strings a bit:

  
else if ( (OS.indexOf("nt") > -1)
  || (OS.indexOf("windows 2000") > -1 )
  || (OS.indexOf("windows 2003") > -1 )  // ok 
                                         // but specific to 2003
  || (OS.indexOf("windows xp") > -1) ) {
 
  
else if ( (OS.indexOf("nt") > -1)
  || (OS.indexOf("windows 20") > -1 )  // better, 
                                       // since no other OS would 
                                       // return "windows"
  || (OS.indexOf("windows xp") > -1) ) {

I started with "windows 200" but thought "what the hell" and made it "windows 20" to lengthen its longivity. You could push it further and use "windows 2," I suppose. The only thing to watch out for is to not overlap with "windows 9."


On Windows, pre-JDK 1.2 JVM has trouble reading the Output stream directly from the SET command, it never returns. Here 2 ways to bypass this behaviour.

First, instead of calling directly the SET command, we use a BAT file, after the SET command we print a known string. Then, in Java, when we read this known string, we exit from loop.

[env.bat]
@set
@echo **end

[java]
...
  if (OS.indexOf("windows") > -1) {
    p = r.exec( "env.bat" );
    }
...

  while( (line = br.readLine()) != null ) {
   if (line.indexOf("**end")>-1) break;
   int idx = line.indexOf( '=' );
   String key = line.substring( 0, idx );
   String value = line.substring( idx+1 );
   hash.put( key, value );
   System.out.println( key + " = " + value );
   }

The other solution is to send the result of the SET command to file and then read the file from Java.

...
if (OS.indexOf("windows 9") > -1) {
    p = r.exec( "command.com /c set > envvar.txt" );
    }
else if ( (OS.indexOf("nt") > -1)
       || (OS.indexOf("windows 2000") > -1
       || (OS.indexOf("windows xp") > -1) ) {
    // thanks to JuanFran for the xp fix!
    p = r.exec( "cmd.exe /c set > envvar.txt" );
    }
...

// then read back the file
Properties p = new Properties();
      p.load(new FileInputStream("envvar.txt"));

Thanks to JP Daviau


 

// UNIX
public Properties getEnvironment() throws java.io.IOException {
    Properties env = new Properties();
    env.load(Runtime.getRuntime().exec("env").getInputStream());
    return env;
    }

Properties env = getEnvironment();
String myEnvVar = env.get("MYENV_VAR");

To read only one variable :

// NT version , adaptation for other OS is left as an exercise...
Process p = Runtime.getRuntime().exec("cmd.exe /c echo %MYVAR%");
BufferedReader br = new BufferedReader
     ( new InputStreamReader( p.getInputStream() ) );
String myvar = br.readLine();
System.out.println(myvar);

Java's System properties contains some useful informations about the environment, for example, the TEMP and PATH environment variables (on Windows).

public class ShowSome {
  public static void main(String args[]){
    System.out.println("TEMP : " 
      + System.getProperty("java.io.tmpdir"));
    System.out.println("PATH : " 
      + System.getProperty("java.library.path"));
    System.out.println("CLASSPATH : " 
      + System.getProperty("java.class.path"));
    System.out.println("SYSTEM DIR : " +
       System.getProperty("user.home")); // ex. c:\windows on Win9x
    System.out.println("CURRENT DIR: "  
      + System.getProperty("user.dir"));
    }
  }

Here some tips from H. Ware about the PATH on different OS.

PATH is not quite the same as library path. In unixes, they are completely different---the libraries typically have their own directories.

System.out.println("the current value of PATH is:  {" +
    p.getProperty("PATH")+"}");

System.out.println("LIBPATH:  {" +
   System.getProperty("java.library.path")+"}");

gives

the current value of PATH is:
{/home/hware/bin:/usr/local/bin:/usr/xpg4/bin:/opt/SUNWspro/bin:
 /usr/ucb:/bin:/usr/bin:/home/hware/linux-bin:/usr/openwin/bin/:
 /usr/local/games:/usr/ccs/lib/:/usr/new:/usr/sbin/:/sbin/:
 /usr/openwin/lib:/usr/X11/bin:/usr/bin/X11/:/usr/local/bin/X11:
 /usr/bin/pbmplus:/usr/etc/:/usr/dt/bin/:/usr/lib:
 /usr/lib/nis:/usr/share/bin:/usr/share/bin/X11:
 /home/hware/work/cdk/main/cdk/../bin:.}
LIBPATH:
{/usr/lib/j2re1.3/lib/i386:/usr/lib/j2re1.3/lib/i386/native_threads:
/usr/lib/j2re1.3/lib/i386/client:/usr/lib/j2sdk1.3/lib/i386:/usr/lib:/lib}

on my linux workstation. (java added all those except /lib and /usr/lib). But these two lines aren't the same on window either:

This system is windows nt

the current value of PATH is:
{d:\OrbixWeb3.2\bin;D:\jdk1.3\bin;c:\depot\cdk\main\cdk\bin;c:\depot\
cdk\main\cdk\..\bin;d:\OrbixWeb3.2\bin;D:\Program
Files\IBM\GSK\lib;H:\pvcs65\VM\win32\bin;c:\cygnus
\cygwin-b20\H-i586-cygwin32\bin;d:\cfn\bin;D:\orant\bin;
C:\WINNT\system32;C:\WINNT;
d:\Program Files\Symantec\pcAnywhere;
C:\Program Files\Executive Software\DiskeeperServer\;}
LIBPATH:
{D:\jdk1.3\bin;.;C:\WINNT\System32;C:\WINNT;D:\jdk1.3\bin;
c:\depot\cdk\main\cdk\bin;c:\depot\cdk\main\cdk\..\bin;
d:\OrbixWeb3.2\bin;D:\Program Files\IBM\GSK\lib;
H:\pvcs65\VM\win32\bin;c:\cygnus\cygwin-b20\H-i586-cygwin32\bin;d:\cfn\bin;
D:\orant\bin;C:\WINNT\system32;
C:\WINNT;C:\Program Files\Dell\OpenManage\ResolutionAssistant\Common\bin;
d:\Program Files\Symantec\pcAnywhere;
C:\Program Files\Executive Software\DiskeeperServer\;}

Java is prepending itself! That confused me--- and broke my exec from ant.

分享到:
评论

相关推荐

    Fast Data Exchange(FDX) with CANoe(C#)示例文档

    This application note is a step by step guide for setting up an easy FDX client application in C# .NET that interfaces to CANoe via FDX. CANoe FDX (Fast Data eXchange) is a UDP-based protocol for ...

    JIDE Desktop Application Framework(桌面应用框架) 开发员技术手册

    Environment Variables - capture and access environment variables, single 1.4.2+ solution FileFormat API marshals data to/from application - default support for common formats Map file formats to ...

    与西门子PLC通讯的Labview库,还不错

    When you change the mappings, you must calculate the size of the variables to be read from the PLC in order to use the correct Read Length parameter. The read length parameter is in transport size ...

    uipath-Level 1最终测试答案.docx

    5. How can we make sure that an app is in a certain state in a Citrix environment? 6. What happens if you send “123[k(enter)]” by using Type Into activity with the SimulateType property selected? ...

    Learning.PHP.7.1785880543

    Create a web application from scratch using MVC Add tests to your web application and write testable code Use an existing PHP framework to build and manage your applications Build REST APIs for your ...

    Beginning Python (2005).pdf

    xvii Contents Finishing Your Modules 154 Defining Module-Specific Errors 154 Choosing What to Export ...CGI’s Special Environment Variables 471 Accepting User Input through HTML Forms 473 The cgi ...

    Sybex - Mastering Visual Basic .NET (VBL).pdf

    Visual Basic .NET is an extremely rich programming environment, and I’ve had to choose between superficial coverage of many topics and in-depth coverage of fewer topics. To make room for more topics...

    PLSQL.Developer v11.0.0.1762 主程序+ v10中文包+keygen

    Tools/Recall Statement: Directory name now supports environment variables General IDE enhancements Full screen mode will now show minimized docking tools so that they can still be accessed ...

    EurekaLog_7.5.0.0_Enterprise

    17)..Added: Support for relative file paths and environment variables for events and various module paths 18)..Added: Logging in Manage tool 19)..Added: Windows 10 version detection 20)..Added: Stack ...

    UE(官方下载)

    We are often asked if it is possible to run an UltraEdit macro or script on a file from the command line. The answer is yes - and it's not only possible, it's extremely simple! Using find/replace ...

    Bloodshed Dev-C++

    * Allow user to specify an alternate configuration file in Environment Options (still can be overriden by using "-c" command line parameter). * Lots of bug fixes. Version 4.9.8.1 * When creating a ...

    微软内部资料-SQL性能优化2

    The user address space is where application code, global variables, per-thread stacks, and DLL code would reside. The system address space is where the kernel, executive, HAL, boot drivers, page ...

    mastering.java

    First, let me thank you for taking the time to purchase and read my guide, “Mastering Java: An Effective Project-Based Approach including Web Development, Data Structures, GUI Programming and Object ...

    Javascript.Object.Oriented.Programming.pdf

    Work with a combination of access modifiers, prefixes, properties, fields, attributes, and local variables to encapsulate and hide data Master DOM manipulation, cross-browser strategies, and ES6 ...

    计算机网络第六版答案

    24. Application-layer message: data which an application wants to send and passed onto the transport layer; transport-layer segment: generated by the transport layer and encapsulates application-layer...

    Swift.iOS.24-Hour.Trainer.111907355

    and presenting best practices for setting up a development environment and using variables, statements, expressions, operators, functions, and closures. Next, you explore common tasks, such as alert ...

    php.ini-development

    The PHPRC environment variable. (As of PHP 5.2.0) ; 3. A number of predefined registry keys on Windows (As of PHP 5.2.0) ; 4. Current working directory (except CLI) ; 5. The web server's directory ...

    Turbo C++ 3.0[DISK]

    DPMI-hosted executables, an environment variable called DPMIMEM can be set to do so. For instance, the command set DPMIMEM=MAXMEM 2000 reserves about 2 Mb of memory for DPMIRES. The number after ...

    Turbo C++ 3.00[DISK]

    DPMI-hosted executables, an environment variable called DPMIMEM can be set to do so. For instance, the command set DPMIMEM=MAXMEM 2000 reserves about 2 Mb of memory for DPMIRES. The number after ...

    python3.6.5参考手册 chm

    PYTHONMALLOC environment variable DTrace and SystemTap probing support Other Language Changes New Modules secrets Improved Modules array ast asyncio binascii cmath collections concurrent....

Global site tag (gtag.js) - Google Analytics