반응형

기본 웹 브라우저란, 기본적으로 HTML 파일등을 실행하였을 때 실행되는 프로그램이다.

단지, 브라우저에 웹 주소를 실행하기 위해서는 ShellExecute 를 이용한 간단한 코드로도 가능하지만, 이 방식은 몇가지 문제가 있다.


바로, 이미 실행되고 있는 인터넷 브라우저가 있는 경우, 이 브라우저를 사용하여 이동할수도있다는 것이다.

만약, 항상 새로운 창에 브라우저를 띄워야 한다면, 이러한 일은 매우 곤혹스러운 일이다.


그것을 해결하기 위해서 사용할 수 있는 한 방법이 바로 기본 웹 브라우저의 경로를 얻어와, 실행시키는 방법이다.


그렇다면, 기본 웹 브라우저의 정보는 어디에 저장되어 있을까?


간단히 생각해보면, 기본 웹 브라우저는 html 파일을 실행하면 동작하기 때문에, Windows 가 html 파일을 실행하고자 할 때 참조하는 ' 연결된 프로그램' 을 찾아보면 쉽게 알 수 있다.


이 연결 프로그램에 대한 정보는 HKEY_CLASSES_ROOT 에 있는데, 자세한 정보는 다음과 같다.


[HKEY_CLASSES_ROOT\htmlfile\shell\open\command]

기본값 : "E:\Program Files\Internet Explorer\iexplore.exe" -nohome


[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\http\shell\open\command]

기본값 : "E:\Program Files\Internet Explorer\iexplore.exe" -nohome

이 부분의 값을 읽어서 사용하면 기본 브라우저의 경로를 얻을 수 있다.


정리

레지스트리에서 기본 웹 브라우저의 정보를 얻어오는 방법을 알아보았다.

<출처: http://www.gosu.net/GosuWeb/Article-detail.aspx?ArticleCode=1385 >

반응형
자바웹스타트 응용 시스템을 만들다 보면 때로는 클레스와 함께 jar 화일에 묶여있는 이미지 화일이나 프로퍼티 화일, 자료 화일 등이 필요할 경우가 있다.  이러한 경우에는 java.lang.ClassLoader로 부터 해당 자원을 얻을 수 있다. 

다음은 jar화일에 묶여있는 이미지 화일로부터 Icon 객체를 생성해내는 예제이다.

ClassLoader loader = this.getClass().getClassLoader();
Icon myIcon = new ImageIcon(loader.getResource("imgs/myImg.gif"));

이 밖에도 java.lang.ClassLoader의 getResourceAsStream(String name) 메소드를 이용하면 다양한 자원을 InputStream을 통하여 얻을 수 있다.

  
  자바웹스타트 환경에서는 Java 2 SE API에서 제공하지 않는 추가적인 기능을 하는 API를 제공한다. 이것은 JNLP API라고 한다. JNLP API를 이용하여 개발할 경우는 jnlp.jar가 필요한데 이러한 파일은 JNLP Developer's Pack에 포함 되어 있다. 다음은 Developer's Pack을 다운로드 할 수 있는 URL이다.

http://java.sun.com/products/javawebstart/download-jnlp.html

  JNLP API가 추가적으로 제공하는 클레스는 javax.jnlp package로 묶여 있으며 BasicService, ClipboardService, DownloadService, FileOpenService, FileSaveService,  PrintService, PersistenceService 등이 있는데 이들은 ServiceManager 클레스를 통하여 사용할 수 있다. 각각의 기능은 다음과 같다.



- javax.jnlp.BasicService
BasicService는 웹스타트의 환경적인 면이나 브라우져를 통제하기 위한 API를 제공하는데 자바 애플릿의 경우 AppletContext와 비슷한 역할을 한다. 다음 예제는 웹스타트 환경에서 웹브라우져로하여금 특정 URL로 가도록 하는 것이다.

import javax.jnlp.*;
.....

BasicService bs = (BasicService)ServiceManager.lookup("javax.jnlp.BasicService");
bs.showDocument(new URL("http://www.javanuri.com"));

- javax.jnlp.ClipboardService
ClipboardService는 시스템에서 사용하는 클립보드에서 복사 객체를 가져오거나 클립보드로 복사하는 서비스를 제공한다. 자바웹스타트는 이 기능을 사용할 때 보안을 위하여 경고창을 보여준다. 다음은 간단한 스트링을 클립보드에 복사하는 예제이다.

import javax.jnlp.*;
.............

ClipboardService cs = (ClipboardService)ServiceManager.lookup("javax.jnlp.ClipboardService");
StringSelection ss = new StringSelection("Hello Web Start");
cs.setContents(ss);

- javax.jnlp.DownloadService
DownloadService는 자신의 자원을 Cache에 저장, 삭제등 Cache를 통제할 수 있는 서비스 API를 제공하는 클레스이다. 다음은 myapp.jar를 Cache에서 확인하고 있으면 삭제한후 다시 Cache에 저장하는 예제이다.

import javax.jnlp.*;
...........

DownloadServicd ds = (DownloadService)ServiceManager.lookup("javax.jnlp.DownloadService");
URL url = new URL("http://www.javanuri.com/jws/myapp.jar");
boolean isCached = ds.isResourceCached(url, "1.0");
if(isCached) {
ds.removeResource(url, "1.0");
}

DownloadServiceListener dsl = ds.getDefaultProgressWindow();
ds.loadResource(url, "1.0", dsl);

- javax.jnlp.FileOpenService
FileOpenService는 권한이 제약된 환경에서도 이를 사용자에게 알리고 화일을 열 수 있는 다이얼로그 윈도우를 열어주는 서비스이다.  다음 예제는 FileOpenService를 이용하여 화일을 여는 예제이다.

import javax.jnlp.*;
..............

FileOpenService fo = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
FileContents fc = fo.openFileDialog(null, null);

- javax.jnlp.FileSaveService
FileSaveService는 권한이 제약된 환경에서도 local disk에 화일을 저장할 수 있는 기능을 제공하는 서비스 클레스이다. 이는 FileOpenService의 경우와 반대인 기능을 제공하는 클레스이다.  다음은 FileOpenService를 이용하여 화일을 연 후에 FileSaveService를 이용하여 화일을 저장하는 예제이다.

import javax.jnlp.*;
...................
..

FileOpenService fo = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
FileContents fc = fo.openFileDialog(null, null);
FileContents newfc =
fss.saveFileDialog(null, null, fc.getInputStream(), "newfile.txt");

- javax.jnlp.PrintService

PrintService는 권한이 제약된 웹스타트 환경에서도 프린트를 가능하게 해주는 API 를 갖고 있는 서비스 클레스이다.  이 API를 이용하여 프린트를 요청하면 사용자에게 허가할 것인가를 묻는 다이얼로그가 나타난다. 다음은 PrintService를 이용한 프린트 요청 예제이다.

import javax.jnlp.*;
.....................

PrintService ps = (PrintService)ServiceManager.lookup("javax.jnlp.PrintService");

// default page format
PageFormat pf = ps.getDefaultPage();

// customizing page format
PageFormat npf = ps.showPageFormatDialog(pf);

// print
ps.print(new Doc());


// printable class
class Doc implements Printable {
....
public int print(Graphics g, PageFormat fm, int idx) {
....
}
}
}

- javax.jnlp.PersistenceService

PersistenceService는 브라우져의 쿠키와 마찬가지고 사용자의 클라이언트에 간단한 자료를 저장할 때 사용된다. 저장되는 형태는 url형태로 자장된다.
다음은 간단한 url을 저장하고 내용을 읽어들이는 예제이다.

import javax.jnlp.*;
.....................

PersistenceService ps = (PersistenceService)ServiceManager.lookup("javax.jnlp.PersistenceService");

String addr = "www.javanuri.com/some.txt";
java.net.URL = new URL(addr);

// create
ps.create(url, 1024);
FileContents fc = ps.get(url);
OutputStream os = fc.getOutputStream(false);
os.write(...);

// read
fc = ps.get(url);
InputStream in = fc.getInputStream();

in.read(...);

.......

- javax.jnlp.FileContents

FileContents 는 FileOpenService, FileSaveService, PersistenceService와 같은 서비스에서  input과 output을 처리할 수 있도록 만들어진 클레스이다. 일반적인 File 클레스와 비슷하게 생각하면 된다.  보안과 자료 저장 형태 등이 일반 File 클레스와는 다르다.
반응형

1. JNI (Java Native Interface) 란 ?

- 자바가 다른 언어로 만들어진 어플리케이션과 상호 작용할 수 있는 인터페이스를 제공한다.

- 자바가상머신(JVM)이 원시 메소드(native method)를 적재(locate)하고 수행(invoke)할 수 있도록 한다

- JNI가 자바가상머신내에 포함됨으로써, 자바가상머신이 호스트 운영체제상의 입출력, 그래픽스, 네트워킹, 그리고 스레드와 같은 기능들을 작동하기 위한 로컬시스템호출(local system calls)을 수행할 수 있도록 한다.

* 쉽게 말해 Java와 다른 언어를 연동하는 솔루션입니다.

[그림1] C로 만들어진 Library와 JAVA를 연결해주는 JNI

2. Why do you need JNI ?

자바 네이티브 메쏘드(Java Native method, 이하 JNI)는 다른 언어로 작성된 코드를 자바에서 호출하도록 만들어진 규약이다. 현재는 C/C++에 대한 호출만을 정확하게 지원한다. 어떻게 보면 JNI는 자바가 만들어진 철학과 정반대되는 것이다.

그러나. Java에도 한계가 있다.

1. 속도 문제가 있는 계산 루틴
 > 자바가 Native Code(플랫폼에 종속적인 기계어 코드)에 비해 느리다.

2. 자바에서 하드웨어 제어

3. 자바에서 지원되지 않은 특정 운영체제 서비스
 > 자바의 클래스 라이브러리는 방대하고 다양한 서비스를 제공하지만, 특정 플랫폼에서 제공하는 고유의 서비스의 기능을 모두 포함할 수는 없다. 특히, 특수한 목적으로 제작된 하드웨어를 자바에서 제어해야 할 필요가 있다고 한다면, 자바만으로 해결하기는 힘들다.

4. 기존의 프로그램에서 자바가 제공하는 서비스를 이용
 > 기존에 작성된 프로그램이나 기존의 시스템(legacy)과의 연계 문제

∴ JNI를 써서 해결해보자.

3. C를 이용한 JNI 예제

VC++을 이용해 C문법으로 작성되어 만들어진 DLL을 로딩하여 Java에서 사용해보겠습니다.

1단계 : Native Method를 선언하는 자바 클래스 작성
2단계 : 1단계에서 작성한 클래스 컴파일
3단계 : javah를 사용해서 Native Method가 사용할 헤더 파일 생성
4단계 : C언어로 Native Method 실제 구현
5단계 : C 코드와 헤더 파일을 컴파일
6단계 : 자바 프로그램 실행

1단계 : Native Method를 선언하는 자바 클래스 작성

Java 소스 파일 : HelloJni_Jsource.java

import java.util.*;

class HelloJniClass {
   native void Hello();

  static {  System.loadLibrary("Hello_DLL");   }

  public static void main(String args[]) {   
      HelloJniClass myJNI=new HelloJniClass();
      myJNI.Hello();
   }
}

// 아래는 좀 위의 내용 보충 그림



2단계 : 1단계에서 작성한 클래스 컴파일



* 컴파일시에는 일반 java 컴파일때와 마찬가지로 환경변수 셋팅이 되어 있어야 합니다.
 -> Path가 JDK의 Javac.exe가 있는 폴더에 설정되어 있어야 합니다.

3단계 : javah를 사용해서 Native Method가 사용할 헤더 파일 생성

<참고: eclipse 사용시 컴파일된 클래스 파일 위치에서 javah 실행. 패키지 최상위에서
          패키지명까지 명시    ex) c:\>javah com.pmguda.HelloJniClass                 >

HelloJniClass.h을 열어보면

JNIEXPORT void JNICALL Java_HelloJniClass_Hello  (JNIEnv *, jobject);
위의 함수를 Implement만 해서 DLL을 만들면 됩니다. (4단계)


4단계 : C언어로 Native Method 실제 구현(1)

1) VC++ 프로젝트 만들기 : Win32용 DLL 프로젝트로 만듭니다.
New - Projects : Win32 Dynamic-Link Library

2) Add Files Projects : HelloJniClass.h 파일 추가

3) Projects Setings(Alt+F7)
   - Link탭에 Output file Name : 1단계의 2. 라이브러리 적재시 작성한 DLL파일명(Hello_DLL.dll)
   - C/C++탭 Preprocessor 카테고리의 Additional Include directories
       JDK의 Include폴더와 Include폴더 밑의 win32폴더

          예) C:\Program Files\Java\jdk1.5.0_03\include\,
             C:\Program Files\Java\jdk1.5.0_03\include\win32

4. 값의 전달과 리턴

1단계 : Java 소스 파일 StringPass_Jsource.java
* 일반 자바 메쏘드 선언과 동일합니다.

class JNI_Message {
   native byte[] Message(String input);

  // 라이브러리 적재(Load the library) 

  static {
    System.loadLibrary("Msg_DLL");
  }


  public static void main(String args[]) {   
 byte buf[];

    // 클래스 인스턴스 생성(Create class instance)
    JNI_Message myJNI=new JNI_Message();

    // 원시 메소드에 값을 주고 받음
    buf = myJNI.Message("Apple");
 
 System.out.print(buf); // 받은값 출력
 }
}

2단계 : 컴파일
 javac StringPass_Jsource.java

3단계 : header파일 생성
 javah JNI_Message

4단계 : method구현 : StringJNIDLLSource.c

#include <stdio.h>
#include <jni.h>
#include <string.h>
#include "JNI_Message.h"

JNIEXPORT jbyteArray JNICALL Java_JNI_1Message_Message (JNIEnv * env, jobject jobj, jstring input)
{
    jbyteArray jb;
    jboolean iscopy;
    char* buf;
    static char outputbuf[20];

    buf=(*env)->GetStringUTFChars(env, input, &iscopy);  // 입력 String 읽어오는 함수
    printf ("\nDLL receive Data from JAVA : %s\n",buf);   // 입력받은 내용을 출력
    strcpy(outputbuf,"Delicious !!\n");
    jb=(*env)->NewStringUTF(env, outputbuf);  // 출력할 내용의 java버퍼에 output버퍼값을 셋팅

   return(jb); // java버퍼 리턴
}

(*env)->함수명 형태로, JAVA의 메쏘드를 C에서 이용할수 있습니다.
* JAVA는 C로 문자열을 넘겨줄때 UTF-8형태를 사용합니다.

5단계 : 실행

C:\test\C_JNI\Paramerter Pass>java JNI_Message

DLL receive Data from JAVA : Apple
Delicious !!

5. KVM ? KNI ?

KVM은 J2ME의 일부로서 작고 자원이 한정된 기계장치를 위해 설계된 소형 JVM.
JVM에서는 JNI가 KVM의 KNI가 있다.

<출처: http://sinuk.egloos.com/2676307>

+ Recent posts