'java'에 해당되는 글 33건

  1. 2016.12.19 [웹 크롤러] crawler4j 링크
  2. 2016.11.09 [Java] String[] to List, List dedup. List to String comma
  3. 2016.04.11 [Java] Build Executable Jar + Local Dependency Jar on Intellij
  4. 2016.03.03 [Java] 외부 프라퍼티(XML) 파일 설정 정보 읽기
  5. 2015.12.05 [JAVA] executable jar 생성 시 pom.xml build 설정.
  6. 2013.04.09 [java] java.util.concurrent.* 링크
  7. 2013.04.05 java system properties...
  8. 2009.05.12 [펌] Java Annotation
  9. 2008.09.17 [세미나]Sun Tech Days 2008 Seoul - 10/15~10/17
  10. 2008.07.30 apache+tomcat+jdk 설치 및 연동 1

[웹 크롤러] crawler4j 링크

ITWeb/개발일반 2016. 12. 19. 13:17

웹 크롤러가 많이 있습니다.

그 중에서 그냥 java 로 쉽게 구현 할 수 있는 crawler4j 링크 공유해 봅니다.


https://github.com/yasserg/crawler4j


샘플 코드는 그냥 위 링크에 올라와 있는 코드 그대로 테스트 해보시면 동작 잘 합니다.

robots.txt 에러가 발생 하는 부분이 있을 경우 아래 설정 추가해 주시면 됩니다.


RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
robotstxtConfig.setEnabled(false);


다른 크롤러가 궁금하신 분들은 아래 구글링 링크 참고하세요.

https://www.google.co.kr/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#newwindow=1&q=web+crawler+open+source


:

[Java] String[] to List, List dedup. List to String comma

ITWeb/개발일반 2016. 11. 9. 12:42

이젠 뭘 해도 기억력이 따라오질 못합니다. ㅠ.ㅠ

복습을 위해서.


Stirng[] to List)

String[] keywords = {"기어", "s3", "기어"};

List<String> lists = Arrays.asList(keywords);


List DeDup)

HashSet<String> set = new HashSet<>(lists);

List<String> result = new ArrayList<>(set);


List to String comma)

StringUtils.join(result, ',');


:

[Java] Build Executable Jar + Local Dependency Jar on Intellij

ITWeb/개발일반 2016. 4. 11. 19:09

예전 글에 일부 설명이 있는데 오늘 삽질한 내용으로 기록해 봅니다.


local 에서 systemPath를 이용해서 dependency 를 설정해 준 경우 manifest 파일에 classpath 로 등록이 되지 않는 문제였습니다.

해결 방법은 아래 코드에 <manifestEntries />를 이용해서 추가해 주었습니다.


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<index>false</index>
<manifestEntries>
<Class-Path>lib/system-path-jar-0.0.1.jar</Class-Path>
</manifestEntries>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>


아래 글 참고해서 보세요.

  1. 2015.12.05 [JAVA] executable jar 생성 시 pom.xml build 설정.
  2. 2015.09.22 [Maven] Executable jar + Assembly 를 이용한 tar 묶기.


:

[Java] 외부 프라퍼티(XML) 파일 설정 정보 읽기

ITWeb/개발일반 2016. 3. 3. 16:30

외부에 존재하는 properties 파일이나 xml 파일에서 설정 정보를 읽고 싶을 경우가 있습니다.

그래서 기록해 봅니다.


import java.io.*;

import java.util.Properties;


Properties properties = new Properties();

InputStreamReader isr = null;


try {

  isr = new InputStreamReader(new FileInputStream("/server/config/config.properties"), "UTF-8");

  properties.load(isr);

} finally {

  if (null != isr) {

    try {

      isr.close();

    } catch (IOException ex) {}

  }

}


System.out.println(properties.getProperty("프라퍼티명"));


xml을 읽고 싶을 경우 

properties.loadFromXML(InputStream in);

을 이용하시면 됩니다.


:

[JAVA] executable jar 생성 시 pom.xml build 설정.

ITWeb/개발일반 2015. 12. 5. 20:40

맨날 잊어버리기 때문에 별거 아니지만 그냥 기록 합니다.


아래 설정은 executable jar 를 만들때 필요한 dependency jar 와 classpath 를 함께 구성해 주기 위해서 사용을 합니다.

자세한 내용은 링크 참고 하시면 됩니다.


[Apache Maven Archiver Examples Classpath]


[build property example]

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>compile</includeScope>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<index>false</index>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!-- Ignore/Execute plugin execution -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<!-- copy-dependency plugin -->
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<versionRange>[1.0.0,)</versionRange>
<goals>
<goal>copy-dependencies</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>


:

[java] java.util.concurrent.* 링크

ITWeb/개발일반 2013. 4. 9. 10:28

[원본글] http://blog.naver.com/windziel?Redirect=Log&logNo=60058329824


java.util.concurrent 패키지는 자바 1.5에 추가된 패키지로서 concurrent 프로그래밍에 유용한 클래스들을 모아둔 것이다.

그중 유용한 것들을 몇가지 정리

참고 - 자바 언어로 배우는 디자인 패턴 입문 멀티 쓰레드 편 - 유키 히로시

 

java.util.concurrent.Semaphore  클래스

사용할 수 있는 리소스의 수가 최대 N개인데 N개보다 많은 수의 쓰레드가 그 리소스를 필요로 하는 경우 Semaphore를 이용하여 리소스 사용을 제어한다.

 

생서자에서 리소스의 수(permits)를 지정

acquire() - 리소스를 확보. 리소스에 빈자리가 생겼을 경우 바로 쓰레드가 acquire 메소드로부터 곧바로 돌아오게 되고 세마포어 내부에서는

                      리소스의 수가 하나 감소. 리소스에 빈자리가 없을 경우 쓰레드는 acquire 메소드 내부에서 블록.
release() - 리소스를 해제. 세마포어 내부에서는 리소스가 하나 증가. acquire 메소드 안에서 대기중인 쓰레드가 있으면

                      그 중 한 개가 깨어나 acquire 메소드로부터 돌아올 수 있다.

 

<예제>

import java.util.Random;

import java.util.concurrent.Semaphore;

/**
 * 수 제한이 있는 리소스
 */
class BoundedResource {
    private final Semaphore semaphore;
    private final int permits;
    private final static Random random = new Random(314159);
    
    public BoundedResource(int permits) {
        this.semaphore = new Semaphore(permits);
        this.permits = permits;
    }
    
    public void use() throws InterruptedException {
        semaphore.acquire();
        
        try {
            doUse();
        } finally {
            semaphore.release();
        }
    }
    
    protected void doUse() throws InterruptedException {
        System.out.println("BEGIN: used = " + (permits - semaphore.availablePermits()));
        Thread.sleep(random.nextInt(500));
        System.out.println("END: used = " + (permits - semaphore.availablePermits()));
    }
}


/**
 * 리소스를 사용하는 쓰레드
 */
class UserThread extends Thread {
    private final static Random random = new Random(26535);
    private final BoundedResource resource;
    
    public void run() {
        try {
            while (true) {
                resource.use();
                Thread.sleep(random.nextInt(3000));
            }
        } catch (InterruptedException e) {
        
        }
    }
}

public class Main {
    public static void main(String[] args) {
        // 3개의 리소스 준비
        BoundedResource resource = new BoundedResource(3);
        
        // 10개의 쓰레드가 사용
        for (int i = 0; i < 10; i++) {
            new UserThread(resource).start();
        }
    }
}

 

java.util.concurrent.locks 패키지의 ReadWriteLock 인터페이스와 ReentrantReadWriteLock 클래스

인스턴스 생성시 락의 취득 순서를 공평(fair)하게 할 것인지를 선택할 수 있다.
공평한 인스턴스를 만든 경우, 대기시간이 긴 쓰레드가 최우선적으로 락을 취득할 수 있도록 조정된다.
재입장 가능하다. 즉, 읽기 역할의 쓰레드가 쓰기 위한 락을 취하거나, 쓰기 역할의 쓰레드가 읽기 위한 락을 취하는 것이 가능하다.
쓰기 위한 락을 읽기 위한 락으로 다운그레이드 할 수 있다. 반대는 안된다.

 

<예제>

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Data {
    private final char[] buffer;
    private final ReadWriteLock lock = new ReentrantReadWriteLock(ture /* fair */);
    private final Lock readLock = lock.readLock();
    private final Lock writeLock = lock.writeLock();
    
    public Data(int size) {
        this.buffer = new char[size];
        
        for (int i = 0; i < buffer.length; i++) {
            buffer[i] = '*';
        }
    }
    
    public char[] read() throws InterruptedException {
        readLock.lock();
        try {
            return doRead();
        } finally {
            readLock.unlock();
        }
    }
    
    public void write(char c) throws InterruptedException {
        writeLock.lock();
        try {
            return doWrite(c);
        } finally {
            writeLock.unlock();
        }
    }
    
    private char[] doRead() {
        char[] newbuf = new char[buffer.length];
        
        for (int i = 0; i < buffer.length; i++) {
            newbuf[i] = buffer[i];
        }
        slowly();
        return newbuf;
    }
    
    private void doWrite(char c) {
        for (int i = 0; i < buffer.length; i++) {
            buffer[i] = c;
            slowly();
        }
    }
    
    private void slowly() {
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
        }
    }
}

import java.util.Random;

public class WriterThread extends Thread {
    private static final Random random = new Random();
    private final Data data;
    private final String filter;
    private int index = 0;
    
    public WriterThread(Data data, String filter) {
        this.data = data;
        this.filter = filter;
    }
    
    public void run() {
        try {
            while (true) {
                char c = nextchar();
                data.write(c);
                Thread.sleep(random.nextInt(3000));
            }
        } catch (InterruptedException e) {
        
        }
    }
    
    private char nextchar() {
        char c = filter.charAt(index);
        index++;
        if (index >= filter.length()) {
            index = 0;
        }
        
        return c;
    }
}

public class ReaderThread extends Thread {
    private final Data data;
    
    public ReaderThread(Data data) {
        this.data = data;
    }
    
    public void run() {
        try {
            while (true) {
                char[] readbuf = data.read();
                System.out.println(Thread.currentThread().getName() + " reads "
                    + String.valueOf(readbuf));
            }
        } catch (InterruptedException e) {
        
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Data data = new Data(10);
        new ReaderThread(data).start();
        new ReaderThread(data).start();
        new ReaderThread(data).start();
        new ReaderThread(data).start();
        new ReaderThread(data).start();
        new WriterThread(data, "ABCDEFGHIJKLMNOPQRSTUVWXYZ").start();
        new WriterThread(data, "abcdefghijklmnopqrstuvwxyz").start();
    }
}

 

 

java.util.concurrent.ThreadFactory 인터페이스

쓰레드 생성을 추상화한 인터페이스

Thread newThread(Runnable r);

ThreadFactory 인터페이스를 구현한 객체를 바꾸는 것 만으로 쓰레드의 생성을 제어
간단한 구현에서는 이것을 사용할 필요없이 Executors.defaultThreadFactory()를 사용하여 기본 ThreadFactory를 구할수 있다.

 

java.util.concurrent.Executor 인터페이스

void execute(Runnable r);

어떤 "처리를 실행"하는 것을 추상화한 인터페이스이며 인수로 부여되는 Runnable 객체는 "실행하는 처리"의 내용을 나타낸다.

 

java.util.concurrent.ExecutorService 인터페이스

반복하여 execute할 수 있는 서비스를 추상화
배후에서 쓰레드가 항상 동작하고 있고 execute 메소드를 호출하면 Runnable 객체를 실행해 주는 것이라고 생각하면 됨.
서비스 종료용으로 shutdown() 메소드 제공

Executor의 서브 인터페이스임

보통 Executors 클래스의 유틸리티 메소드중 ExecutorService 타입을 리턴하는 메소드들을 이용하여 ExecutorService를 얻어 사용

 

java.util.concurrent.ScheduledExecutorService 인터페이스

ExecutorService의 서브 인터페이스이며 처리의 실행을 지연시키는 기능

schedule(Runnable r, long delay, TimeUnit unit);

delay는 지연시간의 수치이며, unit는 delay수치의 단위(NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS)를 지정
Executors.newScheduledThreadPool() 메소드에 의해 ScheduledExecutorService 객체를 생성하여 사용.

 

java.util.concurrent.Executors 클래스

위의 인터페이스 등을 생성시 사용하는 유틸리티 클래스

 

java.util.concurrent.ThreadPoolExecutor 클래스

쓰레드 풀에 대해 아래와 같은 설정을 할 수 있다.
 - 쓰레드풀의 크기
 - 쓰레드를 미리 생성할 것인지 필요에 따라 생성할 것인지
 - 쓰레드를 생성할 때의 팩토리(java.util.concurrent.ThreadFactory)
 - 필요 없어진 워커 쓰레드를 종료시키기까지의 시간
 - 실행하는 일을 건넬 때의 큐인 방법
 - 실행을 거부하는 방법
 - 실행의 전처리, 후처리
 
이 클래스는 ExecutorService를 구현한 것으로 보통은 Executors 클래스에 준비되어 있는 메소드를 사용하는 것이 편리.

Executors.newCachedThreadPool(), Executors.newFixedThreadPool() 등

세세한 설정이 필요한 경우 직접 생성

 

java.util.concurrent.Callable 인터페이스

반환값이 있는 처리의 호출을 추상화
Runnable 인터페이스의 run 메소드와 비슷하지만 반환값이 있다.
Callable<String>라고 기술하면 call 메소드의 반환값의 형이 String인 Callable 인터페이스를 나타낸다.


java.util.concurrent.Future 인터페이스

값을 취득하는 get 메소드가 선언
Future<String>라고 기술하면 get 메소드의 반환값이 String인 Future 인터페이스를 나타낸다.


java.util.concurrent.FutureTask 클래스

Future 인터페이스를 구현한 표준적인 클래스
값을 취득하는 get()
실행을 중단하는 cancel()
값을 설정하는 set()
예외를 설정하는 setException()
Runnable 인터페이스를 구현하고 있으므로 run()

생성자의 인수에 Callable 객체를 건내고 FutureTask의 run 메소드를 호출하면 생성자의 인수로 건넨 Callable 객체의 call 메소드가 실행된다. call 메소드를 호출한 쓰레드는 call 메소드의 반환값을 동기적으로 구하고 그 반환값을 FutureTask의 set 메소드롤 설정한다. 만약 call 메소드에서 예외가 발생하면 FutureTask의 setException 메소드를 사용하여 예외를 설정한다. 필요에 따라 get 메소드로 값을 취하러 가면 call 메소드의 반환값을 구할 수 있다.

 

java.util.concurrent.CountDownLatch 클래스

지정한 회수만큼 countdown 메소드가 호출되기를 기다린다.

 

<예제>

import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.CountDownLatch;

public class Main {
    private static final int TASKS = 10;
    
    public static void main(String[] args) {
        System.out.println("BEGIN");
        ExecutorService service = Executors.newFixedThreadPool(5);
        CountDownLatch doneLatch = new CountDownLatch(TASKS);
        
        try {
            for (int i = 0; i < TASKS; i++) {
                service.execute(new MyTask(doneLatch, i));
            }
            System.out.println("AWAIT");
            
            doneLatch.await();
        } catch (InterruptedException e) {
        
        } finally {
            service.shutdown();
            System.out.println("END");
        }
    }
}


import java.util.Random;

import java.util.concurrent.CountDownLatch;

public class MyTask implements Runnable {

    private final CountDownLatch donLatch;
    private final int context;
    private static final Random random = new Random(314159);
    
    public MyTask(CountDownLatch doneLatch, int context) {
        this.doneLatch = doneLatch;
        this.context = context;
    }
    
    public void run() {
        doTask();
        doneLatch.countDown();
    }
    
    protected void doTask() {
        String name = Thread.currentThread().getName();
        System.out.println(name + ":MyTask:BEGIN:context = " + context);
        try {
            Thread.sleep(random.nextInt(3000));
        } catch (InterruptedException e) {
        
        } finally {
            System.out.println(name + ":MyTask:END:context = " + context);
        }
    }
}

 

위의 인터페이스, 클래스들 외에도 멀티 쓰레드 프로그램에서 안전하게 사용할 수 있는 자료구조에 대한 인터페이스 및 이를 구현한 클래스들이 있다.

BlockingQueue, BlockingDeque ConcurrentMap 등의 인터페이스를 구현한 클래스들이 있으므로 필요에 따라 가져다 사용하면 된다.

 

장황하게 많은 인터페이스, 클래스들을 설명했지만 자주 사용할 만한 것은

Executors 유틸리티 클래스를 이용해서 단일 쓰레드의 경우 newSingleThreadExecutor(), 쓰레드풀의 경우 newFixedThreadPool() 또는 newCachedThreadPool() 메소드를 이용하여 ExecutorService의 인스턴스를 획득한 후 Runnable을 구현한 클래스를 execute() 메소드에 넘겨주어 시작하고, shutdown() 또는 shutdownNow() 메소드를 사용하여 중지시키는 정도로 사용하면 될 듯하다.

 

<예제 - from JDK API Document>

class NetworkService implements Runnable {
   private final ServerSocket serverSocket;
   private final ExecutorService pool;

   public NetworkService(int port, int poolSize)
       throws IOException {
     serverSocket = new ServerSocket(port);
     pool = Executors.newFixedThreadPool(poolSize);
   }

   public void run() { // run the service
     try {
       for (;;) {
         pool.execute(new Handler(serverSocket.accept()));
       }
     } catch (IOException ex) {
       pool.shutdown();
     }
   }
 }

 class Handler implements Runnable {
   private final Socket socket;
   Handler(Socket socket) { this.socket = socket; }
   public void run() {
     // read and service request on socket
   }
 }

 void shutdownAndAwaitTermination(ExecutorService pool) {
   pool.shutdown(); // Disable new tasks from being submitted
   try {
     // Wait a while for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
 }

:

java system properties...

ITWeb/개발일반 2013. 4. 5. 10:42

http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html


KeyMeaning
"file.separator"Character that separates components of a file path. This is "/" on UNIX and "\" on Windows.
"java.class.path"Path used to find directories and JAR archives containing class files. Elements of the class path are separated by a platform-specific character specified in the path.separator property.
"java.home"Installation directory for Java Runtime Environment (JRE)
"java.vendor"JRE vendor name
"java.vendor.url"JRE vendor URL
"java.version"JRE version number
"line.separator"Sequence used by operating system to separate lines in text files
"os.arch"Operating system architecture
"os.name"Operating system name
"os.version"Operating system version
"path.separator"Path separator character used in java.class.path
"user.dir"User working directory
"user.home"User home directory
"user.name"User account name

:

[펌] Java Annotation

ITWeb/개발일반 2009. 5. 12. 20:08

[원본 글]
http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
http://java.sun.com/docs/books/tutorial/java/javaOO/annotations.html

기본적으로 알고 계셔야 하는 annotation 이지요... :)

@Deprecated

The @Deprecated (in the API reference documentation) annotation indicates that the marked method should no longer be used. The compiler generates a warning whenever a program uses a deprecated method, class, or variable. When an element is deprecated, it should be documented using the corresponding @deprecated tag, as shown in the preceding example. Notice that the tag starts with a lowercase "d" and the annotation starts with an uppercase "D". In general, you should avoid using deprecated methods — consult the documentation to see what to use instead.

@Override

The @Override (in the API reference documentation) annotation informs the compiler that the element is meant to override an element declared in a superclass. In the preceding example, the override annotation is used to indicate that the getPreferredFood method in the Horse class overrides the same method in the Animal class. If a method marked with @Override fails to override a method in one of its superclasses, the compiler generates an error.

While it's not required to use this annotation when overriding a method, it can be useful to call the fact out explicitly, especially when the method returns a subtype of the return type of the overridden method. This practice, called covariant return types, is used in the previous example: Animal.getPreferredFood returns a Food instance. Horse.getPreferredFood (Horse is a subclass of Animal) returns an instance of Hay (a subclass of Food). For more information, see Overriding and Hiding Methods (in the Learning the Java Language trail).

@SuppressWarnings

The @SuppressWarnings (in the API reference documentation) annotation tells the compiler to suppress specific warnings that it would otherwise generate. In the previous example, the useDeprecatedMethod calls a deprecated method of Animal. Normally, the compiler generates a warning but, in this case, it is suppressed.

Every compiler warning belongs to a category. The Java Language Specification lists two categories: "deprecation" and "unchecked". The "unchecked" warning can occur when interfacing with legacy code written before the advent of generics. To suppress more than one category of warnings, use the following syntax:

@SuppressWarnings({"unchecked", "deprecation"})

위 원문에 대한 번역이 잘된 글 링크 넣습니다.
원본 글 : http://decoder.tistory.com/21

 

:

[세미나]Sun Tech Days 2008 Seoul - 10/15~10/17

ITWeb/스크랩 2008. 9. 17. 13:31

홈페이지 : http://www.suntechdays2008.com/


 

무료세미나만 올려 봅니다.

시 간 내 용
12:30 ~ 13:30 등록
13:30 ~ 13:40 환영사
13:40 ~ 14:30 넷빈즈 최신 동향 소개
14:30 ~ 16:00 NetBeans 6.5를 통해 더욱 쉬워진 스크립트 언어 구현
16:00 ~ 16:20 BREAK
16:20 ~ 17:50 데스크탑 개발자를 위한 넷빈즈 사용법:스윙 애플리케이션 프레임워크 및 데이터 바인딩
17:00 ~ 17:30 경품 추첨

:

apache+tomcat+jdk 설치 및 연동

ITWeb/서버관리 2008. 7. 30. 12:38

Download
* http://java.sun.com/javase/downloads/index_jdk5.jsp
JDK 5.0 Update 16 다운로드 받음
http://java.sun.com/j2se/1.5.0/install-linux.html

* http://httpd.apache.org/download.cgi
httpd-2.2.9.tar.gz

* http://tomcat.apache.org/
apache-tomcat-6.0.16.tar.gz

* http://tomcat.apache.org/connectors-doc/
tomcat-connectors-1.2.26-src.tar.gz
mod_jk-1.2.26-httpd-2.2.6.so

Installation
* JDK 설치
download 경로 및 설치 시작 위치 : /home/app/download/
설치 경로 : /home/app/java/jdk
설치하기
파일권한변경
$ /home/app/download/]chmod 744 jdk-1_5_0_16-linux-i586.bin
$ /home/app/download/]./jdk-1_5_0_16-linux-i586.bin
약관같은 내용 스킵(q 누르고 빠져 나옴)
yes 입력후 설치 시작
$ /home/app/download/]cd jdk1.5.xxx
$ /home/app/download/]mv -f * /home/app/java/jdk
$ /home/app/download/]cd ..
$ /home/app/download/]rm -rf ./jdk1.5.xxx
JAVA_HOME 과 path 설정
.cshrc 기준
setenv JAVA_HOME "/home/app/java/jdk"
set path=( $path $JAVA_HOME/bin )

기 설치된 java 삭제 (rpm 설치)
설치 pkg 확인 (root 로 실행)
삭제 및 java version 확인
$ /home/app/download/]rpm -qif /usr/lib/jvm/jre-1.4.2-gcj/bin/java
$ /home/app/download/]rpm -e java-1.4.2-gcj-compat
$ /home/app/download/]java -version

* tomcat 설치
$ /home/app/download/] tar -xvzf apache-tomcat-6.0.16.tar.gz
$ /home/app/download/]mv -f ./apache-tomcat-6.0.16 ../tomcat

.cshrc 기준
setenv CATALINA_HOME "/home/app/tomcat"
set path=( $path $CATALINA_HOME/bin )

tomcat 설치 테스트
$ /home/app/tomcat/bin]startup.sh

http://localhost:8080/

* apache 설치
# jsp 를 사용하기 땜시 기본 설치 합니다.
$ /home/app/download/httpd-2.2.9]./configure --prefix=/home1/irteam/naver/apache-2.2.9 --enable-so --with-mpm=worker
$ /home/app/download/httpd-2.2.9]make clean
$ /home/app/download/httpd-2.2.9]make
$ /home/app/download/httpd-2.2.9]make install

* apache tomcat connector
apache 와 tomcat 을 연동하기 위해서 설치
ref. ttp://tomcat.apache.org/connectors-doc/webserver_howto/apache.html
ref. http://www.akadia.com/download/soug/tomcat/html/tomcat_apache.html

    • source build 하기
      tar -xvzf tomcat-connectors-1.2.26-src.tar.gz
      cd tomcat-connectors-1.2.26-src/native
      ./buildconf.sh
      ./configure --with-apxs=/home/app/apache-2.2.9/bin/apxs ## <-- apxs 가 설치된 위치 지정
      make
      make install
      cd apache-2.0 ## <-- 들어가 보시면 mod_jk.so 가 생성되어 있습니다. apache 설치 경로의 ~/modules/ 아래 보시면 mod_jk.so 가 복사되어 있지 않으면 복사해서 넣기
    • httpd.conf 수정하기
      # tomcat.conf 설정은 LoadModule 설정 최상단에 위치
      # apache module load 순서와 연관
      include conf/tomcat.conf
      include extra/httpd-vhost.conf
    • tomcat.conf 수정하기
      # JkMount 와 같은 option 들은 virtualhost 설정에서 잡아주고 
      # 아래는 공통 설정
      LoadModule jk_module modules/mod_jk.so
      
      JkWorkersFile           conf/workers.properties
      JkShmFile               /home/app/logs/apache/mod_jk.shm
      JkLogFile               /home1/app/logs/apache/mod_jk.log
      JkLogLevel              debug
      JkLogStampFormat        "[%a %b %d %H:%M:%S %Y] "
      JkRequestLogFormat  "%w %V %T"
    • workers.properties 수정하기
      workers.tomcat_home=/home/app/tomcat
      workers.java_home=/home/app/java/jdk
      
      ps=/
      worker.list=tebs ## <-- tebs 는 property 또는 서비스 명
      
      worker.tebs.port=8009
      worker.tebs.host=localhost
      worker.tebs.type=ajp13
      worker.tebs.lbfactor=1
    • extra/httpd-vhost.conf 수정하기
      NameVirtualHost *
      
      #
      # VirtualHost example:
      # Almost any Apache directive may go into a VirtualHost container.
      # The first VirtualHost section is used for all requests that do not
      # match a ServerName or ServerAlias in any <VirtualHost> block.
      #
      <VirtualHost *>
          ServerName localhost
          ServerAlias localhost
          ServerAdmin admin@localhost
          DocumentRoot "/home/app/docs/tebs/web"
      
          ErrorLog "/home/app/logs/apache/error"
          CustomLog "/home/app/logs/apache/access" common
      
          JkMount             /*.jsp  tebs # 또는 /* tebs
      
      # htdocs 위치는 아래와 같음.
          <Directory "/home/app/docs/tebs/web">
              AllowOverride None
              Order deny,allow
              Allow from all
          </Directory>
      # 접근 금지
          <Directory "/home/app/docs/tebs/web/WEB-INF">
              AllowOverride None
              Order deny,allow
              Deny from all
              Allow from none
          </Directory>
      # 접근 금지
          <Directory "/home/app/docs/tebs/web/META-INF">
              AllowOverride None
              Order deny,allow
              Deny from all
              Allow from none
          </Directory>
      </VirtualHost>
    • server.xml 수정
      # 위치는 tomcat 설치 위치의 /home/app/tomcat/conf/server.xml
      # 기본 tomcat context root 변경을 위해서 아래와 같이 apache htdocs 설정한 경로로 변경
      <Host name="localhost"  appBase="/home/app/docs/tebs/web"
                  unpackWARs="true" autoDeploy="true"
                  xmlValidation="false" xmlNamespaceAware="false">
              <Context path="" docBase="." debug="0" reloadable="true"></Context>
      </Host>
    • jsp 파일 테스트

      아래 apache 와 tomcat 의 실행 순서 매우 중요
      tomcat daemon 이 먼저 떠 있어야 mod_jk 가 apache 모듈로 load 될때 정상적으로 connect 할 수 있음
      아파치설치경로/bin/apachectl stop
      톰켓설치경로/bin/shutdown.sh
      톰켓설치경로/bin/startup.sh
      아파치설치경로/bin/apachectl start
      # htdocs 로 이동
      cd /home/app/tomcat/webapps/ROOT // 또는 /home/app/tomcat/webapps서비스명 또는 프로젝트명/
      vi index.jsp
      # 브라우저에서 접속 테스트




 






 

: