Java programming에 대한 질문 입니다.
글쓴이: hyper9 / 작성시간: 수, 2010/01/06 - 6:21오전
제목 부터 어떻게 쓰는게 좋을지 좀 애매하네요 ~
갑자기 Java code쪽을 보는 담당자가 휴가를 가서
제가 봐야하는 처지가 되어 버렸는데요..
Code를 보니, 어디가 문제인지는 알겠는데, 고치는게 어렵네요 ~
그동안 Java code를 한번도 본적이 없었거든요 ㅜㅜ
문제는 java application상에서, 현재 application이 실행되는
platform이 일반 system인지, VMware인지를 판별하는 문제인데요.
C program이나, shell program 처럼 , "dmesg | grep VMware"
을 이용해서 platform이 VMware인지 아닌지를 판별하려고 하거든요.
이럴때, JAVA code로는 어떻게 구현하면 되는지를 모르겠네요.
JAVA를 하시는 분들이 보기에는 어려운 문제가 아닐 것 같아서
질문 올립니다.
조언 주시면 감사하겠습니다.
Forums:
Write Once, Debug Everywhere
Write Once, Debug Everywhere 문제인가 보군요. 자바 프로그래밍은 안한지 오래되었지만, java operating system information 으로 구글링 해보니 답이라고 생각되는 것이 두번째로 나오네요.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html
VMWare만의 문제라면
VMWare만의 문제라면 java how to detect vmware로 구글링 하면 다음이 걸리네요.
http://stackoverflow.com/questions/154163/detect-virtualized-os-from-an-application
제가 설계했다면 Java property에서 뭔가 api를 제공했을 듯 한데, 그렇지가 않았네요. 그리 바람직한 방법이라고 생각하지 않지만, 방법이 없으면 그거라도 해보셔야 겠죠.
C 에서는
fp = popen("cat /proc/meminfo | grep MemTotal | awk '{print $2}' | cut -d'k' -f1", "r");
fgets(buff, 10, fp);
이런 방법으로 MemTotal값을 C program으로 읽어 들여서 사용했던적이 있는데요.
Java에서는 이런 경우에 어떻게 처리할까요?
이런 방법을 사용할 수 있다면, "dmesg | grep VMware"를 사용해서, VMware인지 아닌지를
Java program내에서 detect할 수 있다면 쉬울 것 같다는 생각이 들었는데,
이 생각이 Java에는 어울리지 않는 방법인가요?
조언 부탁 드립니다. ~
Runtime.getRuntime().exec() S
이것에 대해 알아보시면 될 것 같습니다.
별 상관은 없는데 시스템에 종속됩니다. 무슨 말인가하면
dmesg | grep 를 넣으면 MS 에서는 작동이 안 되겠죠.
아래처럼 코드를 작성하면 될 것 같네요.
아..그리고 보안상에 문제가 있을 수 있습니다.
감사합니다.
덕분에 일단은 시작을할 수는 있게 되었습니다 ^^
하지만, 아직도 뭔가 잘 안되네요 ㅜㅜ
제가 해본것은요 ~
이렇게 해보았는데요, string test에서 찍히는 게 아무것도 없는 것 같아요.
출력값은
Test in New Function #2 null
이렇게 되더라고요.
Test in New Function #1 은 아예 찍히지 않구요.
그럼 test가 null인 것 같은데, dmesg | grep mice 를 linux상에서 해보면
제 system에서는
mice: PS/2 mouse device common for all mice
라고 찍히거든요.
InputStreamReader()사용이 잘못된 걸까요?
이 내용이 위의 Java program에서도 찍히기를 기대한 거였는데,아직 뭔가 문제가
많이 있나보네요 ㅜㅜ
조언 주시면 감사하겠습니다.
p = rt.exec("dmesg | grem
grem으로 되어있는데 설마 테스트해본 소스도 grem으로 되어있는 건 아니겠죠? :)
잡설)
System.getProperties()로 가져올 수 있는 property를 vbox상의 os에서 하나씩 println으로 찍어보니 virtual환경이다라는 내용은 알기 어려울 것 같더군요.
다만 *.seperator, os.name 등으로 실행되고 있는 os의 이름과 종류 정도는 알 수 있겠더군요. 전에 있던 회사에서는 *.seperator로 구분했었습니다. 그닥 정확한 방법은 아닌 것 같지만요.
종속적이 되더라도 os상에서 실행가능한 커맨드로 취득하는 게 정확할 것 같습니다.
--
I think to myself...what a emerging world.
아..그건 실수네요 ^^
예,,Test해본 source는 grep으로 되어 있고요.
혹시나 pipe가 문제일까해서..
"dmesg | grep mice" 대신에
"pwd"를 해보았는데, 결과는 마찬가지 인 것 같습니다 ~ ㅜㅜ
음
음 이상하네요.
올려주신 테스트 코드를 main 메소드로 바꿔서 실행해보니 잘 나옵니다.
결과
일단 코드를 실행하고 있는 환경이 좀 궁금하네요.
그럴리는 없겠지만 dmseg를 실행할 권한이 없는 유저로 실행했다거나...(이 경우라면 아마 에러 메세지가 취득될 겁니다)
다른 원인이 있을 수 있겠죠.
그리고 아래 분이 적어주신 ProcessBuilder를 사용하는 편이 좀 더 나을 거라 생각합니다.
일전에 ProcessBuilder를 이용하는 편이 더 좋다는 문서를 읽었던 기억이 납니다. 일 할 때 필요해서 찾아본 문서였는데 회사를 관두는 바람에 문서도 백업 안해두었던 터라 내용이...
dmseg가 문제없이 취득된다면
1. java.util.regex
2. 별도의 쉘 스크립트 작성
두 가지로 필요한 문자열을 탐지해내면 되겠군요. 아마도... :)
--
I think to myself...what a emerging world.
음..그렇군요
감사합니다.
지금 이 문제가 기존에 있던 곳에 끼워넣기를 하는 중이라
저도 환경이 어떻다고 얘기해야 할지 잘 모르겠네요 ㅜㅜ
혹시 command가 어떤 권한을로 실행되는 건지, Java code
안에서 확인해 볼 방법은 있을까요?
다시 감사드리면서, 조언도 부탁드립니다 ~ ^^
유저권한의 경우 1.
유저권한의 경우
1. System.getProperties / System.getProperty로 취득이 가능할 것 같네요.
화면에 System.getProperty("user.name"); 을 찍어 보시면 실행 중인 유저명을 알 수 있겠네요.
2. $roles user_name 으로 root가 취득되는지 Process나 Runtime으로 exec해보시면 될 것 같습니다.
(리눅스에도 roles 커맨드가 있는지는 확인 안해봤습니다. 혹 비슷한 게 있으면 사용해 보시길 권합니다.)
3. System.getenv("");를 사용해 보세요.
시스템에 선언되어있는 환경변수를 읽어들일 수 있습니다. 단, Deprecated 이므로 테스트 이외에는 사용하시면 안될 것 같네요.
--
I think to myself...what a emerging world.
됩니다 .^^
앗..뭐가 잘못되었던건지 모르겠네요 ~
암튼 지금은 잘되는걸 확인했습니다.
그리고 pipe가 들어가면 안되는 것 같아요.
그것 때문에 착각을 했던건지도 모르겠습니다.
그리고, pipe를 쓸 수 없었기 때문에, 별도의 shell script를 linux상에서
만들어서 이 shell script가 VMware인지 아닌지를 판별해서 "VMware" 또는 "Linux"
라는 string을 return하도록 했고,
Java Code에서는 p = Runtime.getRuntime().exec("platfrom_check");라고
실행을 해봤습니다.
여기서의 platform_check는 platform이 VMware인지 아닌지를 판별해주는 script이고요.
그리고 아래와 같은 code를 덧붙였습니다.
그리고 platform_check가 VMware를 돌려주면
"This is VMware"가 찍히고, 만일 platform_check가 "Linux"라는
값을 돌려주면 "This is not VMware"가 찍히기를 기대했는데,
여기도 문제가 있나봐요.
둘다 안찍히네요 ...
혹시 p.getInputStream()으로 읽어들인 문자열의 끝부분에 \r이나 \n같은게
"VMware"와 같이 만들어낸 string과 달라서 그런걸까요?
아니면,,,어떤 이유에서인지,,조언 부탁드립니다.
감사합니다. ~
파이프가 안 먹히는
파이프가 안 먹히는 건 아마 이 내용 때문인 것 같습니다.
그리고 p.getInputStream 으로 값이 얻어지지 않는 것 같은데 이 부분에 대해선 다음 내용이 의심됩니다.
shell script에서 return시키는 값을 stdout으로 한 번 바꿔 보신 후 테스트 해보시면 되지 않을까 싶네요. println으로 user 정보와 stream에 들어온 정보도 찍어보시면서 어떤 과정으로 진행되는지 확인해 보시면 좋을 것 같습니다. :)
회사라서 코드를 못돌리는 게 좀 아쉽습니다. 이해를... :)
--
I think to myself...what a emerging world.
p.getErrorStream()으로
p.getErrorStream()으로 반환된 스트림도 찍어보시기 바랍니다.
이 외에도 p.exitValue()의 결과값도 찍어보시면 좋구요.
오래되서 가물가물 하긴 하지만..
Process나 Runtime을 이용해서 우리가 쉘 상에서 쓰는 파이프는 이용할 수 없었던 걸로 기억합니다.
해당 부분을 쉘 스크립트로 만들어서 실행했던 기억이 나는걸로 봐서는요.
오래된 경험이라 지금은 문제 없을수도 있습니다.
이와는 조금 반하는 내용이지만 Java API를 보면 아래와 같은 설명이 있네요.
The ProcessBuilder.start() and Runtime.exec methods create a native process and return an instance of a subclass of Process that can be used to control the process and obtain information about it. The class Process provides methods for performing input from the process, performing output to the process, waiting for the process to complete, checking the exit status of the process, and destroying (killing) the process.
The methods that create processes may not work well for special processes on certain native platforms, such as native windowing processes, daemon processes, Win16/DOS processes on Microsoft Windows, or shell scripts. The created subprocess does not have its own terminal or console. All its standard io (i.e. stdin, stdout, stderr) operations will be redirected to the parent process through three streams (getOutputStream(), getInputStream(), getErrorStream()). The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.
-- Signature --
青い空大好き。
蒼井ソラもっと好き。
파란 하늘 너무 좋아.
아오이 소라 더좋아.
댓글 달기