'java'에 해당되는 글 28건

  1. 2011.11.13 Java Map 반복(Iteration)시키는 3가지 방법 5
  2. 2011.11.09 디폴트 패키지에 있는 자바 class 실행하기 ( Could not find the main class 에러날때 ) 1
  3. 2011.10.27 Windows 커맨드창 안띄우고 스크립트 실행하기
  4. 2011.10.13 maven package goal 로 war나 jar 파일 생성시 생성되는 파일명 설정하기
  5. 2011.10.10 Runtime 에 jar 파일 클래스패스에 추가 시키기 : RuntimeJarLoader 1

Java Map 반복(Iteration)시키는 3가지 방법


왠지 도움이 될것 같다면 추천을 *(-_-)*


이 세가지 방법 말고도 뭐 다른 방법이 있겠지만 대충 요 3가지 정도만 알고 있어도 충분하고도 넘칠것 같다.

이전까지는 제일 첫번째 방법으로만 Map 에 있는 것들을 꺼내서 썼었는데

세번째 방법도 꽤 간결하고 가독성도 좋은것 같아 앞으로 세번째 방법을 주로 써야 겠다는 생각을 해본다.


package com.tistory.stove99;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class MapIterationSample {
	public static void main(String[] agrs) {
		Map<String, String> map = new HashMap<String, String>();
		
		map.put("키1", "값1");
		map.put("키2", "값2");
		map.put("키3", "값3");
		map.put("키4", "값4");
		map.put("키5", "값5");
		map.put("키6", "값6");
		
		
		// 방법1
		Iterator<String> keys = map.keySet().iterator();
		while( keys.hasNext() ){
			String key = keys.next();
			System.out.println( String.format("키 : %s, 값 : %s", key, map.get(key)) );
		}
		
		// 방법2
		for( Map.Entry<String, String> elem : map.entrySet() ){
			System.out.println( String.format("키 : %s, 값 : %s", elem.getKey(), elem.getValue()) );
		}
		
		// 방법3
		for( String key : map.keySet() ){
			System.out.println( String.format("키 : %s, 값 : %s", key, map.get(key)) );
		}
	}
}

디폴트 패키지에 있는 자바 class 실행하기 ( Could not find the main class 에러날때 )



간만에 커맨드 창에서 실행해야 하는 자바예제를 작성해 볼 일이 있어서 맨들어 보았다.

그런데 다 맨든게 이클립스에서 run 을 하면 실행이 잘되는데 커맨드창에서 java 클래스명.class 로 실행을 하면

뒤져라 Could not find the main class 요러면서 main 함수를 찾을 수 없다는 에러만 뱉어 내고 실행이 잘 안됬다.


결국은 해결했는데 뭔가 많이 꾸리한 느낌을 받지 아니할 수가 없다.

예제로 맨들어본 아무 패키지 선언도 안된 디폴트 패키지에 있는 Test.java
public class Test {
	public static void main(String[] args) {
		System.out.println("Hello Everyone~");
	}
}

 컴파일
javac Test.java

 컴파일을 한 후 대부분 요래  실행을 할것이다. 아니면 나만 그런가-_-? 아무튼!
java Test.class

 하지만 죠래 실행하면 뒤져도 실행이 안된다. 해답은 요래 실행하는 것이다  -_-
java Test


지금와서 가만 생각해보니 java Test.class 라고 입력하면 Test 라는 패키지에 class 라는 클래스를 찾나 보다 -_-;;;




※ 패키지가 있는 java 파일 커맨드에서 컴파일하기

sample 패키지 Test.java
package sample;

public class Test {
	public static void main(String[] args) {
		System.out.println("Hello Everyone~");
	}
}

컴파일
javac -d . Test.java
요래 컴파일하면 현재 디렉토리 아래로 sample 디렉토리가 생성되고 거기에 Test.class 가 컴파일 된다.

실행
java sample.Test



Windows 커맨드창 안띄우고 스크립트 실행하기



Java 로 GUI 후로그램을 맹근후 필요에 따라 고걸 쉽게 실행시키기 위해서

javaw -jar xxxx.jar 를 실행시키는 간단한 스크립트.bat 파일을 맹글곤 한다.

그런데 문제는 그 스크립트 파일을 뽓 더블클릭하면 시커먼 커맨드창이 뜬 다음 나의 후로그램이 실행되는 바람에, 그 시꺼먼 커맨드 창이 딱 보기가 싫어진다.




고걸 방지하기 위해서 bat 파일을 맨드는 대신 vbs (비쥬얼베이직스크립트) 파일을 맨들어서 내용을 다음과 같이 해주면 깔쌈하게 GUI 후로그램만 깔꼼하게 실행된다.

※ vbs 파일도 따블클릭하면 bat 파일처럼 똑같이 실행된다.

run.vbs
Set WshShell = WScript.CreateObject("WScript.Shell")
wshShell.run "javaw -jar xxxxx.jar"
Set WshShell = nothing

요렇게 run.vbs 파일을 작성한후 뽓뽓 따블클릭을 하면 원하던 바가 이루어진다.


※ jar 파일은 executable jar 로 맨들어야 된다.





maven package goal 로 war나 jar 파일 생성시 생성되는 파일명 설정하기


아무것도 설정하지 않고 maven package 골로 빌드를 하면 artifactId-version.war 로 war 파일이 생성된다.

이 war 파일로 배포를 하는데  배포를 할때마다 ROOT.war 나 컨텍스트명.war 로 파일명을 변경해야 되서 귀찮기 그지없다.

mvn package 를 했을때 ROOT.war 나 project.war 같이 생성될 war 파일명을 설정해 보자.

<project 
	xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

	<modelVersion>4.0.0</modelVersion>
	<groupId>com.tistory.stove99</groupId>
	<artifactId>MyProject</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<build>
		<!-- ROOT.war 가 생성된다. -->
		<finalName>ROOT</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.1.1</version>

				<configuration>
					<warSourceDirectory>WebContent</warSourceDirectory>
					<webXml>WebContent/WEB-INF/web.xml</webXml>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>
build 태그 아래에 finalName 태그를 추가한 다음 원하는 이름을 설정하면 설정한이름.war 로 war 파일이 생성된다.

Runtime 에 jar 파일 클래스패스에 추가 시키기 : RuntimeJarLoader

자바로 만든 프로그램을 실행시킬때 java -classpath "jar 파일들 목록" "실행할 자바클래스" 요런식으로 프로그램에서 사용하는 jar 파일을

클래스패스에 추가시켜 줘야 된다.


그런데 톰캣같은 WAS 를 보면 WEB-INF\lib 폴더 아래에 있는 jar 파일들을 딱히 클래스패스에 추가시켜 주지 않아도 지가 알아서 클래스 패스에 추가시켜준다.


요런 기능과 비슷한일을 하는 클래스를 맨들어 보았다.
import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * 
 * @author stove99.tistory.com
 *
 */
public class RuntimeJarLoader {
	public static void loadJarIndDir(String dir){
		try{
			final URLClassLoader loader = (URLClassLoader)ClassLoader.getSystemClassLoader();
			final Method method = URLClassLoader.class
                                       .getDeclaredMethod("addURL", new Class[]{URL.class});
			method.setAccessible(true);
			
			new File(dir).listFiles(new FileFilter() {
				public boolean accept(File jar) {
					// jar 파일인 경우만 로딩
					if( jar.toString().toLowerCase().contains(".jar") ){
						try{
							// URLClassLoader.addURL(URL url) 메소드 호출
							method.invoke(loader, new Object[]{jar.toURI().toURL()});
							System.out.println(jar.getName()+ " is loaded.");
						}catch(Exception e){
							System.out.println(jar.getName()+ " can't load.");
						}
					}
					return false;
				}
			});
		}catch(Exception e){
			throw new RuntimeException(e);
		}
	}
}

RuntimeJarLoader.java



※ 코드 설명

일단 현재 실행중인 JVM 에 동적으로 jar 파일을 클래스 패스에 추가 시킬려면
요 코드로 시스템의 클래스 로더를 가져와야 한다.
URLClassLoader loader = (URLClassLoader)ClassLoader.getSystemClassLoader();

가져온 현재 JVM 의 클래스 로더를 이용하여 jar 파일을 로딩시켜 주면 되는데

문제는 jar 파일을 로딩시켜주는 일을 하는 메소드( URLClassLoader.addURL(URL url) )가 protected 라는 것이다.

그래서 loader.addURL("jar 파일"); 요런식으로 외부에서 직접 호출이 불가능 하다.



뭔가 이유가 있어서 protected 로 만들어 놨겠지만 나의 목표를 위해서는 꼭 저 addURL 메소드를 호출해야 할 필요가 있다.

아무튼 저 addURL 메소드를 호출하기 위한 방법으로 Java reflection 을 이용했다.

요코드로 호출할 메소드를 정의하고
Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});


핵심은 요부분이 되겠다. protected 로 선언된 메소드를 public 이로 바꿔주는 일을 한다. 요렇게 public 으로 바꿔준다음
method.setAccessible(true);


요런 Java reflection 코드를 이용해서 addURL() 을 호출해 주면, 바라던 Runtime 에 jar 파일을 클래스 패스에 추가시킬수 있다.
method.invoke(loader, new Object[]{jar.toURI().toURL()});



※ 참고 RuntimeJarLoader 사용법
// c:\lib 폴더 아래에 있는 jar 파일들 로딩
RuntimeJarLoader.loadJarInDir("c:/lib");

// 현재 실행중인 경로의 하위에 있는 lib 폴더 로딩
RuntimeJarLoader.loadJarInDir("./lib");

요렇게 쓰면 된다~
prev 1 2 3 4 5 6 next