2012년 02월 23일
오른쪽 마우스 해제하기 URL
# by | 2012/02/23 10:05 | 개발 | 트랙백 | 덧글(0)
# by | 2012/02/23 10:05 | 개발 | 트랙백 | 덧글(0)
# by | 2012/01/17 13:57 | 개발 | 트랙백 | 덧글(0)
흔히 사용하는 SomethingMBean과는 달리
동적으로 MBean을 생성하는 방식이 Dynamic MBean이다.
Dynamic MBean은 애플리케이션 설정을 포함한 속성 파일을 사용하고,
이 내용를 관리를 위해 노출하고자 할 때 사용할 수 있다.
Dynamic MBean을 사용함으로써 원격에서 속성 파일의 정보를 확인하고,
애플리케이션이 실행 중에 속성 파일이 변경되더라도 이를 반영할 수 있다.
가장 큰 차이점은 동적으로 없던 속성을 추가하거나 있던 속성을 제거할 수 있다는 것이다.
다음은 Dynamic MBean을 사용하는 예제이다.
다음은 Dynamic MBean의 구현체이다.
package propertymanager;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Properties;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.ReflectionException;
public class PropertyManager implements DynamicMBean {
private final String propertyFileName;
private final Properties properties;
public PropertyManager(String propertyFileName) throws IOException {
this.propertyFileName = propertyFileName;
properties = new Properties();
load();
}
public synchronized String getAttribute(String name)
throws AttributeNotFoundException {
String value = properties.getProperty(name);
if (value != null)
return value;
else
throw new AttributeNotFoundException("No such property: " + name);
}
public synchronized void setAttribute(Attribute attribute)
throws InvalidAttributeValueException, MBeanException,
AttributeNotFoundException {
String name = attribute.getName();
if (properties.getProperty(name) == null)
throw new AttributeNotFoundException(name);
Object value = attribute.getValue();
if (!(value instanceof String)) {
throw new InvalidAttributeValueException(
"Attribute value not a string: " + value);
}
properties.setProperty(name, (String) value);
try {
save();
} catch (IOException e) {
throw new MBeanException(e);
}
}
public synchronized AttributeList getAttributes(String[] names) {
AttributeList list = new AttributeList();
for (String name : names) {
String value = properties.getProperty(name);
if (value != null)
list.add(new Attribute(name, value));
}
return list;
}
public synchronized AttributeList setAttributes(AttributeList list) {
Attribute[] attrs = (Attribute[]) list.toArray(new Attribute[0]);
AttributeList retlist = new AttributeList();
for (Attribute attr : attrs) {
String name = attr.getName();
Object value = attr.getValue();
if (properties.getProperty(name) != null && value instanceof String) {
properties.setProperty(name, (String) value);
retlist.add(new Attribute(name, value));
}
}
try {
save();
} catch (IOException e) {
return new AttributeList();
}
return retlist;
}
public Object invoke(String name, Object[] args, String[] sig)
throws MBeanException, ReflectionException {
if (name.equals("reload") && (args == null || args.length == 0)
&& (sig == null || sig.length == 0)) {
try {
load();
return null;
} catch (IOException e) {
throw new MBeanException(e);
}
}
throw new ReflectionException(new NoSuchMethodException(name));
}
public synchronized MBeanInfo getMBeanInfo() {
SortedSet<String> names = new TreeSet<String>();
for (Object name : properties.keySet())
names.add((String) name);
MBeanAttributeInfo[] attrs = new MBeanAttributeInfo[names.size()];
Iterator<String> it = names.iterator();
for (int i = 0; i < attrs.length; i++) {
String name = it.next();
attrs[i] = new MBeanAttributeInfo(name, "java.lang.String",
"Property " + name, true, // isReadable
true, // isWritable
false); // isIs
}
MBeanOperationInfo[] opers = { new MBeanOperationInfo("reload",
"Reload properties from file", null, // no parameters
"void", MBeanOperationInfo.ACTION) };
return new MBeanInfo(this.getClass().getName(),
"Property Manager MBean", attrs, null, // constructors
opers, null); // notifications
}
private void load() throws IOException {
InputStream input = new FileInputStream(propertyFileName);
properties.load(input);
input.close();
}
private void save() throws IOException {
String newPropertyFileName = propertyFileName + "$$new";
File file = new File(newPropertyFileName);
OutputStream output = new FileOutputStream(file);
String comment = "Written by " + this.getClass().getName();
properties.store(output, comment);
output.close();
if (!file.renameTo(new File(propertyFileName))) {
throw new IOException("Rename " + newPropertyFileName + " to "
+ propertyFileName + " failed");
}
}
}
다음은 Dynamic MBean 테스트 클래스이다.
package propertymanager;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
public class PropertyManagerTest {
public static void main(String[] args) {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name;
try {
name = new ObjectName("propertymanager:type=PropertyManager");
PropertyManager mbean = new PropertyManager("test.properties");
mbs.registerMBean(mbean, name);
System.out.println("Waiting forever...");
Thread.sleep(Long.MAX_VALUE);
} catch (MalformedObjectNameException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NullPointerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstanceAlreadyExistsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MBeanRegistrationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotCompliantMBeanException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
JConsole로 연결하여 MBeans 탭을 활용하면 간단히 테스트할 수 있다.
Reference:
http://weblogs.java.net/blog/emcmanus/archive/2006/11/a_real_example.html
# by | 2011/10/28 21:51 | 트랙백 | 덧글(0)
java [ options ] class [ argument ... ] java [ options ] -jar file.jar [ argument ... ] javaw [ options ] class [ argument ... ] javaw [ options ] -jar file.jar [ argument ... ]
The java tool launches a Java application. It does this by starting a Java runtime environment, loading a specified class, and invoking that class's main method.The method must be declared public and static, it must not return any value, and it must accept a
Stringarray as a para meter. The method declaration must look like the following:public static void main(String args[])By default, the first non-option argument is the name of the class to be invoked. A fully-qualified class name should be used. If the -jar option is specified, the first non-option argume nt is the name of aJAR archive containing class and resource f iles for the application, with the startup class indicated by the Main-Class manifest header.The Java runtime searches for the startup class, and other classes used, in three sets of locations: the bootstrap class path, the installed extensions, and the user class path.
Non-option arguments after the class name or JAR file name are passed to the main function.
The javaw command is identical to java, except that with javaw there is no associated console window. Use javaw when you don't want a command prompt window to appear. The javaw launcher will, however, display a dialog box with error information if a launch fails for some reason.
The launcher has a set of standard options that are supported on the current runtime environment and will be supported in future releases. In addition, the default Java HotSpot VMs provide a set of non-standard options that are subject to change in future releases.
- -client
- Select the Java HotSpot Client VM.
For more information, see Server-Class Machine Detection
- -server
- Select the Java HotSpot Server VM.
For more information, see Server-Class Machine Detection
- -agentlib:libname[=options]
- Load native agent library libname, e.g.
-agentlib:hprof
-agentlib:jdwp=help
-agentlib:hprof=help
For more information, see JVMTI Agent Command Line Options.
- -agentpath:pathname[=options]
- Load a native agent library by full pathname. For more information, see JVMTI Agent Command Line Options.
- -classpath classpath
- -cp classpath
- Specify a list of directories, JAR archives, and ZIP archives to search for class files. Class path entries are separated by semicolons (;). Specifying -classpath or -cp overrides any setting of theCLASSPATH environment variable.
If -classpath and -cp are not used and CLASSPATH is not set, the user class path consists of the current directory (
.).For more information on class paths, see Setting the Class Path.
- -Dproperty=value
- Set a system property value. If value is a string that contains spaces, you must enclose the string in double quotes:
java -Dfoo="some string" SomeClass- -enableassertions[:<package name>"..." | :<class name> ]
- -ea[:<package name>"..." | :<class name> ]
- Enable assertions. Assertions are disabled by default.
With no arguments, enableassertions or -ea enables assertions. With one argument ending in "...", the switch enables assertions in the specified package and any subpackages. If the argument is simply "...", the switch enables assertions in the unnamed package in the current working directory. With one argument not ending in "...", the switch enables assertions in the specified class.
If a single command line contains multiple instances of these switches, they are processed in order before loading any classes. So, for example, to run a program with assertions enabled only in package com.wombat.fruitbat (and any subpackages), the following command could be used:
java -ea:com.wombat.fruitbat... <Main Class>The -enableassertions and -ea switches apply to all s loaders and to system classes (which do not have a class loader). There is one exception to this rule: in their no-argument form, the switches do not apply to system. This makes it easy to turn on asserts in all classes except for system classes. A separate switch is provided to enable asserts in all system classes; see -enablesystemassertions below.
- -disableassertions[:<package name>"..." | :<class ; ]
- -da[:<package name>"..." | :<class name> ]
- Disable assertions. This is the default.
With no arguments, disableassertions or -da disables assertions. With one argument ending in "...", the switch disables assertions in the specified package and any subpackages. If the argument is simply "...", the switch disables assertions in the unnamed package in the rent working directory. With one argument not ending in "...", the switch disables assertions in the specified class.
To run a program with assertions enabled in package com.wombat.fruitbat but disabled in class com.wombat.fruitbat.Brickbat, the following command could be used:
java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat lt;Main Class>The -disableassertions and -da switches apply to all ss loaders and to system classes (which do not have a class loader). There is one exception to this rule: in their no-argument form, the switches do not apply to system. This makes it easy to turn on asserts in all classes except for system classes. A separate switch is provided to enable asserts in all system classes; see -disablesystemassertions below.
- -enablesystemassertions
- -esa
- Enable asserts in all system classes (sets the default assertion status for system classes to true).
- -disablesystemassertions
- -dsa
- Disables asserts in all system classes.
- -jar
- Execute a program encapsulated in a JAR file. The first argument is the name of a JAR file instead of a startup class name. In order for this option to work, the manifest of the JAR file must contain a line of the form Main-Class: classname. Here, classname identifies the class having the public static void main(String[] args) method that serves as your application's starting point. See the Jar tool reference page and the Jar trail of the Java Tutorial for information about working with Jar files and Jar-file manifests.
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
- -javaagent:jarpath[=options]
- Load a Java programming language agent, see java.lang.instrument.
- -verbose
- -verbose:class
- Display information about each class loaded.
- -verbose:gc
- Report on each garbage collection event.
- -verbose:jni
- Report information about use of native methods and other Java Native Interface activity.
- -version
- Display version information and exit.
- -showversion
- Display version information and continue.
- -?
- -help
- Display usage information and exit.
- -X
- Display information about non-standard options and exit.
- -Xint
- Operate in interpreted-only mode. Compilation to native code is disabled, and all bytecodes are executed by the interpreter. The performance benefits offered by the Java HotSpot Client VM's adaptive compiler will not be present in this mode.
- -Xbatch
- Disable background compilation. Normally the VM will compile the method as a background task, running the method in interpreter mode until the background compilation is finished. The -Xbatch flag disables background compilation so that compilation of all methods proceeds as a foreground task until completed.
- -Xdebug
- Start with support for JVMDI enabled. JVMDI has been deprecated and is not used for debugging in J2SE 5.0, so this option isn't needed for debugging in J2SE 5.0.
- -Xbootclasspath:bootclasspath
- Specify a semicolon-separated list of directories, JAR archives, and ZIP archives to search for boot class files. These are used in place of the boot class files included in the Java 2 SDK. Note: Applications that use this option for the purpose of overriding a class in rt.jar should not be deployed as doing so would contravene the Java 2 Runtime Environment binary code license.
- -Xbootclasspath/a:path
- Specify a semicolon-separated path of directires, JAR archives, and ZIP archives to append to the default bootstrap class path.
- -Xbootclasspath/p:path
- Specify a semicolon-separated path of directires, JAR archives, and ZIP archives to prepend in front of the default bootstrap class path. Note: Applications that use this option for the purpose of overriding a class in rt.jar should not be deployed as doing so would contravene the Java 2 Runtime Environment binary code license.
- -Xcheck:jni
- Perform additional checks for Java Native Interface (JNI) functions. Specifically, the Java Virtual Machine validates the parameters passed to the JNI function as well as the runtime environment data before processing the JNI request. Any invalid data encountered indicates a problem in the native code, and the Java Virtual Machine will terminate with a fatal error in such cases. Expect a performance degradation when this option is used.
- -Xfuture
- Perform strict class-file format checks. For purposes of backwards compatibility, the default format checks performed by the Java 2 SDK's virtual machine are no stricter than the checks performed by 1.1.x versions of the JDK software. The -Xfuture flag turns on stricter class-file format checks that enforce closer conformance to the class-file format specification. Developers are encouraged to use this flag when developing new code because the stricter checks will become the default in future releases of the Java application launcher.
- -Xnoclassgc
- Disable class garbage collection.
- -Xincgc
- Enable the incremental garbage collector. The incremental garbage collector, which is off by default, will reduce the occasional long garbage-collection pauses during program execution. The incremental garbage collector will at times execute concurrently with the program and during such times will reduce the processor capacity available to the program.
- -Xloggc:file
- Report on each garbage collection event, as with -verbose:gc, but log this data to file. In addition to the information -verbose:gc gives, each reported event will be preceeded by the time (in seconds) since the first garbage-collection event.
Always use a local file system for storage of this file to avoid stalling the JVM due to network latency. The file may be truncated in the case of a full file system and logging will continue on the truncated file. This option overrides -verbose:gc if both are given on the command line.
- -Xmsn
- Specify the initial size, in bytes, of the memory allocation pool. This value must be a multiple of 1024 greater than 1MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is 2MB. Examples:
-Xms6291456 -Xms6144k -Xms6m- -Xmxn
- Specify the maximum size, in bytes, of the memory allocation pool. This value must a multiple of 1024 greater than 2MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is 64MB. Examples:
-Xmx83886080 -Xmx81920k -Xmx80m- -Xprof
- Profiles the running program, and sends profiling data to standard output. This option is provided as a utility that is useful in program development and is not intended to be be used in production systems.
- -Xrunhprof[:help][:<suboption>=<value>,...]
- Enables cpu, heap, or monitor profiling. This option is typically followed by a list of comma-separated "<suboption>=<value>" pairs . Run the command java -Xrunhprof:help to obtain a list of suboptions and their default values.
- -Xrs
- Reduces usage of operating-system signals by the Java virtual machine (JVM). This option is available beginning with J2SE 1.3.1.
In J2SE 1.3.0, the Shutdown Hooks facility was added to allow orderly shutdown of a Java application. The intent was to allow user cleanup code (such as closing database connections) to run at shutdown, even if the JVM terminates abruptly.
The JVM watches for console control events to implement shutdown hooks for abnormal JVM termination. Specifically, the JVM registers a console control handler which begins shutdown-hook processing and returns TRUE for CTRL_C_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT.
The JVM uses a similar mechanism to implement the pre-1.2 feature of dumping thread stacks for debugging purposes. Sun's JVM uses CTRL_BREAK_EVENT to perform thread dumps.
If the JVM is run as a service (for example, the servlet engine for a web server), it can receive CTRL_LOGOFF_EVENT but should not initiate shutdown since the operating system will not actually terminate the process. To avoid possible interference such as this, the -Xrs command-line option has been added beginning with J2SE 1.3.1. When the -Xrs option is used on Sun's JVM, the JVM does not install a console control handler, implying that it does not watch for or process CTRL_C_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, or CTRL_SHUTDOWN_EVENT.
There are two consequences of specifying -Xrs:
- Ctrl-Break thread dumps are not available.
- User code is responsible for causing shutdown hooks to run, for example by calling System.exit() when the JVM is to be terminated.
- -Xssn
- Set thread stack size.
Copyright © 2004, 2010 Oracle and/or its affiliates. All rights reserved. | |
# by | 2011/10/26 14:51 | 트랙백 | 덧글(0)
> jmap -dump:<dump-options> pid-dump 옵션을 사용할 때는 보통 -dump:format=b,file=heap.hprof 정도의 옵션만으로 충분하다.
또는
> jmap -histo[:live] pid
여기서는 Memory 상태를 추적할 수 있는 공짜 Tool 을 하나 소개하겠다.
Sun JDK, HP JDK 에 포함되어있는 것으로 jstat 라는 것이다.
현재 JVM 의 Heap Memory 상태를 실시간으로 추적하는 매우 효율적인 Tool 이다.
다음은 jstat 에 사용할 수 있는 파라미터들이다.
[ngwas1:/NGI/agreeDomain]jstat
invalid argument count
Usage: jstat -help|-options
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
Definitions:
<option> An option reported by the -options option
<vmid> Virtual Machine Identifier. A vmid takes the following form:
<lvmid>[@<hostname>[:<port>]]
Where <lvmid> is the local vm identifier for the target
Java virtual machine, typically a process id; <hostname> is
the name of the host running the target Java virtual machine;
and <port> is the port number for the rmiregistry on the
target host. See the jvmstat documentation for a more complete
description of the Virtual Machine Identifier.
<lines> Number of samples between header lines.
<interval> Sampling interval. The following forms are allowed:
<n>["ms"|"s"]
Where <n> is an integer and the suffix specifies the units as
milliseconds("ms") or seconds("s"). The default units are "ms".
<count> Number of samples to take before terminating.
-J<flag> Pass <flag> directly to the runtime system.
위에 있는 <option> 을 보겠다.
[ngwas1:/NGI/wily601]jstat -options
-class
-compiler
-gc
-gccapacity
-gccause
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-printcompilation
위와같이 여러개의 옵션이 있는데 여기서 우리는 GC 관련 옵션을 선택하여 Heap Memory Area 를 추적해보겠다.
[ngwas1:/NGI/wily601]jstat -gc -h20 6637 3000
위의 명령을 해석해보면...
-gc : GC 되는 것을 보겠다는 의미
-h20 : 아래 데이터를 보면 알겠지만 숫자에 대한 헤더가 있는데 그 헤더를 20 라인마다 찍겠다는 의미이다.
6637 : Process PID 이다. 이건 항상 변하겠죠?
3000 : 시간이다. ms 단위라서 3000 이면 3초마다 한번씩 데이터를 추출하겠다는 얘기다.
위와같이 명령을 실행하면 아래와 같은 내용이 추출되며 각 줄마다 3초에 한번씩 추출된다.
그럼 아래의 데이터를 보는 법을 알려주겠다.
첫번째 파마리터 부터 설명을 붙여주겠다.
SOC : Servivor 0 Area Capacity
S1C : Servivor 1 Area Capacity
SOU : Servior 0 Area Used
S1U : Servivor 1 Area Used
EC : Eden Capacity
EU : Eden Used
OC : Old Capacity (Tenured Capacity)
OU : Old Used (Tenured Used)
PC : Permanent Capacity
PU : Permanent Used
YGC : Young GC Count
YGCT : Young GC Count Time (Young GC 시간이다. 누적시간이므로 아래서 위의 시간을 빼면 Young GC Time 을 알수있다)
FGC : Full GC Count
FGCT : Full GC Count Time
GCT : GC Time (YGCT + FGCT)
어려운가 ?
http://blog.naver.com/salsu0/30000025219 <== 요기를 읽고나서 보면 안어렵다.
그럼 아래 데이터를 한번 분석해 봅시다.
S0 Area 는 34 메가 정도가 할당되었다.
S1 Area 역시 동일하게 할당되었다.
Eden Area 는 72 메가 정도가 할당되었고
Old Area (Tenured Area) 는 700 메가 정도가 할당되었다.
Permanent Area 는 130 메가 정도 할당되었다.
Young GC 가 마지막줄을 봤을때 40 번 실행되었고,
Full GC 는 실행된적이 없다.
Young GC 가 40 번 실행되는 동안 걸린 시간은 7초 정도이며
맨 밑에 세번째 줄과 다음 줄을 비교해봤을때 Young GC 가 일어난 시간은 0.17 초 정도이다.
알다시피 GC 할때는 전혀 일을 하지 않는다.
물론 Default GC Option 일 경우이다. (다음번에는 GC Option 의 종류를 설명하겠다.)
그럼 다들 한번 테스트를 해보기를 바란다.
잼있죠 ?
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
34944.0 34944.0 0.0 17142.6 279616.0 72110.9 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 72110.9 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 72110.9 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 72110.9 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 72110.9 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 72110.9 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 72110.9 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 72110.9 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 72110.9 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 72110.9 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 72110.9 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 72110.9 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 73802.8 699072.0 86240.1 131072.0 69871.3 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 76141.1 699072.0 86240.1 131072.0 69871.4 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 102379.9 699072.0 86240.1 131072.0 69871.7 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 159719.5 699072.0 86240.1 131072.0 69875.0 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 207689.5 699072.0 86240.1 131072.0 69946.6 39 7.006 0 0.000 7.006
34944.0 34944.0 0.0 17142.6 279616.0 259934.1 699072.0 86240.1 131072.0 69948.0 39 7.006 0 0.000 7.006
34944.0 34944.0 17625.0 0.0 279616.0 50821.6 699072.0 86240.1 131072.0 69950.3 40 7.176 0 0.000 7.176
34944.0 34944.0 17625.0 0.0 279616.0 83850.1 699072.0 86240.1 131072.0 69950.9 40 7.176 0 0.000 7.176
# by | 2011/10/26 14:24 | Java - 자바 | 트랙백 | 덧글(0)
# by | 2011/10/23 10:45 | 트랙백 | 덧글(0)
| Features | MongoDB | Riak | HyperTable | HBase |
|---|---|---|---|---|
| Logical Data Model | Rich Document with support for Nested Document | Rich Document | Column Family | Column Family |
| Support for CAP | CA | AP | CA | CA |
| Dynamic Addition /Removal of Node | Supported | Supported | Supported | Supported |
| Multi DC support | Supported | Not Supported | Supported | Supported |
| Interface | Variety of APIs (Java, Python, Perl, C#) | JSON over HTTP | REST, Thrift, Java | C++,Thrift |
| Persistence Model | Disk | Disk | Memory + Desk (Tunable) | Memory + Desk (Tunable) |
| Comparative Performance | Better (C++) | Best (Erlang) | Better (C++) | Good (Java) |
| Commercial Support | 10gen.com | Basho Technologies | Hypertable Inc | Cloudera |
# by | 2011/10/20 15:10 | 트랙백 | 덧글(0)
NoSQL은 관계형 데이터베이스의 한계를 극복하기 위한 데이터 저장소의 새로운 형태로 수평적 확장성을 특징으로 한다.
관계형이 아니기 때문에 join이 없고 고정된 스키마를 갖지 않는다.
대표적인 NoSQL 제품은 Google의 BigTable, Amazon의 Dynamo이 있고, 이외에 비롯해 다양한 오픈소스 제품이 소개되어 있다.
BigTable, Dynamo, Cassandra, CouchDB, MongoDB, Hbase, Riak, Voldemort 등 20개 이상의 NoSQL 제품이 있고,
자신의 목적에 맞는 NoSQL 제품을 선택하기 위해서는 각각의 특징을 정확히 파악해야 한다.
Availability와 Partition tolerance가 추상적 정의만으로 이해가 힘들 수 있어서 설명을 추가합니다. (용어 때문에 오히려 이해가 어려울 수 있는데 둘 다 파티션에 대한 특성으로 접근해야 합니다.) Availability and Partition Tolerance 글과 댓글을 참고하면 A, P에 대한 정의 및 기능이 좀 더 이해가 쉬울 수 있습니다.
데이터 저장소는 CAP 중에서 2가지만 선택할 수 있다. 예를 들어 RDB는 CA에 특화되어 있기 때문에 분산 환경에 적용이 어렵다.
NoSQL 제품은 CAP 중에서 C 또는 A를 일부 포기함으로써 분산 확장이 가능하다. 일반적으로 NoSQL 시스템은 관계형을 포기하거나 트랜잭션 구조를 느슨하게 함으로써 수평 확장이 가능하도록 한다.

RDB 대안에 NoSQL만 있는 것은 아니다.
# by | 2011/10/20 15:09 | 트랙백 | 덧글(0)
{
"zzzzz" : "woot",
"xyz" : "hello",
"aaaab" : "world",
"1" : "x",
"aaaaa" : "y"
}영구적이다 (Persistence){
"1" : {
"A" : "x",
"B" : "z" },
"aaaaa" : {
"A" : "y",
"B" : "w"
},
"aaaab" : {
"A" : "world",
"B" : "ocean"
},
"xyz" : {
"A" : "hello",
"B" : "there"
},
"zzzzz" : {
"A" : "woot",
"B" : "1337"
}
}위의 코드와 같이 Map의 Map의 형태로 데이터를 저장하는 것이 가능하다. 이 특성을 이용해서 "1"이나 "aaaa"를 row에 대한 키로 정의하고 "A"나 "B"를 column의 키로 정의하는 것이 가능하고 전체를 하나의 테이블로 정의할수도 있겠다.{ // ...
"zzzzz" :
{ "A" :
{
"catch_phrase" : "woot",
}
}
}위의 예처럼, "zzzz" Row의 "A"칼럼은 이제까지 없었던 "catch_phrase"라는 키를 가지고 있다. 이처럼 noSQL은 데이타 모델에 대해 훨씬 더 유연한 특성을 가지고 있다.# by | 2011/10/20 15:04 | 트랙백(1) | 덧글(0)
[Drools 5.1 다운로드 + Eclipse 설정]
Hello World
Goodbye cruel world
# by | 2011/09/21 09:48 | 개발 | 트랙백 | 덧글(0)
이미 35개 이상의 Accenture 고객사에 Spring batch가 적용되고 있다
스프링배치 연재(2) 대용량 처리 배치 프로그램을 만들 때 유의할 점
스프링배치 연재(3) 스프링배치 프로젝트와 주요 기능들
스프링배치 연재(5) ItemReader와 ItemWriter
스프링배치 연재(8) JDBC를 이용한 Cursor 기반의 DB 조회
스프링배치 연재(10) JobLauncher와 Job, Step
스프링배치 연재(12) 이벤트 처리, 유효성 검사, 변환, 기존 클래스 활용
스프링배치 연재(14) 드라이빙 쿼리와 iBatis의 활용
스프링배치 연재(15) 하이버네이트 활용과 여러파일 읽기
스프링배치 연재(16) DB to XML 파일 만들기 예제
[Beta 1.0]Spring Batch 프레임웍 레퍼런스 한글 편역 버전.
[Beta 2.0] Spring Batch 프레임웍 레퍼런스 한글 편역 버전.
[Beta 3.0] Spring Batch 프레임웍 레퍼런스 한글 편역 버전.
제 1부. 스프링 배치 기본 아키텍처와 잡(Job) 직접 실행해보기
제 2부. FlatFileItemReader와 그 친구들(파트1)
제 2부. FlatFileItemReader와 그 친구들(파트2) (소스 및 PPT)
제 3부. FlatFileItemWriter와 아이템 변환하기 (소스 및 PPT)
제 4부. StAX 기반 아이템 처리 (소스 및 PPT)
제 5부. 데이터베이스에 아이템 쓰고, 읽고~ (소스 및 PPT)
Spring Batch 쓰임새 분석 - 단순한 배치 반복하기
Spring Batch 쓰임새 분석 - 자동적인 재시작
Batch Processing Strategies at Spring Batch
Spring Batch 1.0에서 2.0으로 진화하기- 1. ItemReader/ItemWriter(1)
Spring Batch 1.0에서 2.0으로 진화하기- 1. ItemReader/ItemWriter(2)
Spring Batch 1.0에서 2.0으로 진화하기- 3. JobExecutionLisneter & 4. ItemProcessor
Spring Batch 1.0에서 2.0으로 진화하기- 5. Configuration
The Domain Language of Batch - Spring Batch Chapter 2
ItemReader - Spring Batch Chapter 3
- [Spring batch]차세대 배치시스템 구축 성공전략 - JCO컨퍼런스
# by | 2011/08/17 12:10 | Java - 자바 | 트랙백(1) | 덧글(0)
# by | 2010/12/21 12:16 | Java - 자바 | 트랙백 | 덧글(0)
# by | 2010/11/18 10:45 | Java - 자바 | 트랙백 | 덧글(0)
web.xml
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webapp.root</param-value>
</context-param>
log4j.xml
<appender name="DAILY" class="org.apache.log4j.DailyRollingFileAppender">
<param name="datePattern" value="'.'yyyy-MM-dd" />
<param name="file" value="${webapp.root}/WEB-INF/logs/epms.log" />
<param name="append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%t> [%d{yyyy-MM-dd HH:mm:ss}] [%c{1}] [%L] [%p] %m %n"/>
</layout>
</appender>
webapp1
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>first.webapp.root</param-value>
</context-param>
<appender name="DAILY" class="org.apache.log4j.DailyRollingFileAppender">
<param name="datePattern" value="'.'yyyy-MM-dd" />
<param name="file" value="${first.webapp.root}/WEB-INF/logs/epms.log" />
<param name="append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%t> [%d{yyyy-MM-dd HH:mm:ss}] [%c{1}] [%L] [%p] %m %n"/>
</layout>
</appender>
webapp2
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>second.webapp.root</param-value>
</context-param>
<appender name="DAILY" class="org.apache.log4j.DailyRollingFileAppender">
<param name="datePattern" value="'.'yyyy-MM-dd" />
<param name="file" value="${second.webapp.root}/WEB-INF/logs/epms.log" />
<param name="append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%t> [%d{yyyy-MM-dd HH:mm:ss}] [%c{1}] [%L] [%p] %m %n"/>
</layout>
</appender>
# by | 2010/11/17 10:44 | 트랙백 | 덧글(0)
# by | 2010/11/02 10:43 | 트랙백 | 덧글(0)
# by | 2010/11/02 10:14 | Java - 자바 | 트랙백 | 덧글(0)
java -Drunlevel=[real | test | staging ]
applicationContext.xml 파일에 PropertyPlaceholderConfigurer 설정
xxx.properties를 생성하고 덮어쓸 속성을 선언해줌.
-Drunlevel 설정을 해주면 해당 설정을 읽어들여서 덮어쓰고, 안해주면 그냥 무시하고 넘어간다.
runlevel
applicationContext.xml
-Drunlevel=xxx 설정을 해주지 않으면 옵션에 의해 ${runlevel}이 있는 설정을 무시하고 넘어감.
참조 : Oracle의..;;.. java launcher 공식 문서
Set a system property value. Ifvalueis a string that contains spaces, you must enclose the string in double quotes:
java -Dfoo="some string" SomeClass
web.xml 파일에서도 읽혀진다.
applicationContext.xml 파일에서의 확인방법
spring-servlet.xml
# by | 2010/10/01 15:52 | Java - 자바 | 트랙백 | 덧글(0)
# by | 2010/09/01 10:16 | 이클립스-Eclipse | 트랙백 | 덧글(0)
# by | 2010/08/30 09:13 | 트랙백 | 덧글(0)
개발자들이 Application에 도입하는 대부분의 캐싱은 오랜 시간동안 변경되지 않는 데이터를 위한 것이다. 그러나 의외로 캐싱된 데이터가 쓰기에 의해 변경되는 경우도 있다.
개발자들은 나름대로 캐싱모델을 정의하고, 구현하여 사용한다. 그러나 캐싱 될 데이터를 추가하고, 더 이상 사용되지 않는 데이터는 삭제하고, 정해진 시간별로 캐싱 된 데이터를 삭제하는 등의 많은 기능들을 정의하고 구현하여 사용하려고 하는 솔직히 쉬운 일도 아니고, "노력 대비 성능" 또한 보장할 수가 없다.
그래서 요즘 많은 ORM 솔루션들이 데이터 캐싱을 지원한다. iBatis 또한 여타 ORM 솔루션과 같이 데이터 캐싱을 지원한다. 그러나 iBatis의 데이터 캐싱은 다른 ORM 솔루션의 데이터 캐싱과는 조금 개념이 다르다. 여타의 ORM 솔루션들은 주로 DataBase Table 객체에 매핑하는 데 중점을 두고, iBatis는 SQL 구문을 객체에 매핑하도록 되어 있다.
-- CacheModel 이해하기
CacheModel은 iBatis의 모든 캐시 구현체를 정의하는 기반이 되는 곳이다. SQL Maps 설정 안에서 캐시 모델 설정을 정의하고 하나 이상의 쿼리 매핑 구문이 이를 사용할 수 있다.
* CacheModel 속성들 *
id (필수) : 유일한 ID를 지정. CacheModel에 설정 된 캐시를 사용하고 하는 쿼리 매핑 구문에서 ID를 참조한다.
type (필수) : 이 값은 CacheModel이 설정하는 캐시의 타입을 의미한다. 사용 가능한 값으로 MEMORY, LRU, FIFO, OSCACHE가 있다. 이 속성은 사용자 정의 CacheController 구현체의 완전한 클래스 이름으로 지정해도 된다.
readOnly (선택) : 읽기전용 여부. 이 값을 true로 지정하면 캐시가 읽기 전용 캐시로 사용될 것임을 의미한다. 읽기 전용 캐시에서 가져온 객체는 객체의 Property들을 변경할 수 없다.
serialize (선택) : 캐시의 내용을 가져올 때 객체의 모든 값을 복사하여 새로운 객체를 생성하여 전달할지 여부를 지정한다.
여기서 readOnly 속성 값에 대해 좀더 알아보면 readOnly 속성은 단순히 CcheModel에게 캐시된 객체를 어떻게 가져와서 저장할지 알려주는 지시자이다. 이 속성값이 true이면 가져온 내용을 변경해도 CacheModel은 변경되지 않는다. 만약 false로 지정되면 주의해야 하는데 두 명 이상의 사용자가 캐시된 참조의 동일한 인스턴스를 가져갈 수 없음을 의미한다.
* 내장 CacheModel 타입들 *
MEMORY : 단순하게 캐시된 데이터를 가비지 컬렉터가 삭제할 때까지 메모리에 저장한다.
FIFO : 고정 된 크기의 모델로 "first in first out (먼저 들어간 값을 먼저 삭제)" 알고리즘을 사용하여 메모리에서 캐시 항목들을 삭제한다.
LRU : FIFO와 다른 고정 된 크기의 모델로 "least recently used (최근에 가장 오랜동안 사용하지 않은 값을 캐시에서 먼저 삭제)" 알고리즘을 사용하여 메모리에서 캐시 항목들을 삭제한다.
OSCACHE : OpenSymphony Cache를 사용한다. (OSCashe Lib와 설정이 함께해야 한다.)
* readOnly와 serialize 속성의 조합에 대한 요약 *
readOnly (true) / serialize(false) : 성능 좋음. 캐시 된 객체를 가장 빠르게 가져온다. 캐시 된 객체의 공유 인스턴스를 반환하며, 잘못 사용하면 문제를 일으킬 수도 있다.
readOnly (false) / serialize(true) : 성능 좋음. 캐시 된 객체를 빠르게 가져온다. 캐시 된 객체를 깊은 복사 작업을 통해 가져온다.
readOnly (false) / serialize(false) : 주의요망! 캐시는 오직 호출하는 스레드의 세션이 살아있는 동안에만 관련되고, 다른 쓰레드는 사용할 수 없다.
readOnly (true) / serialize(true) : 성능 나쁨. 무의미한 설정이라는 점을 제외하면 readOnly (true) / serialize(true)와 동일하게 작동한다.
readOnly=true이고 serialize=false이면 캐시 된 객체가 전역적으로 공유되기 때문에 모든 사용자는 다른 세션에서 부적절하게 변경 된 객체를 가져오게 될 수 있는 문제의 소지가 있다. readOnly=false이고 serialze=true를 사용하면 캐시에서 가져온 객체의 깊은 복사작업의 결과를 가져오기 때문에 캐시에서 가져온 객체가 값은 비록 같지만 동일한 인스턴스가 아니라는 의미이다. 이것은 캐시에서 가져온 객체의 변경사항이 호출한 세션 안에서만 작용된다.
-- 캐시 비우기 (Cache Flushing)
사용자가 정의 한 CacheModel은 캐시된 데이터를 모두 비울때 사용하는 공통적인 요소를 가지고 있다. 이것은 이전에 캐시된 모든 데이터를 비우고 새롭게 데이터를 캐시하게 된다.
* 캐시를 비우는 flush 요소들 *
<flushOnExecute> : 지정 된 쿼리 매핑 구문이 실행되면 캐시의 모든 데이터를 비운다.
<flushInterval> : 캐시를 비우는 시간 간격을 정의한다.
<flushOnExecute>
속성으로 statement 하나만을 가지며, 이 속성에 지정된 매핑 구문이 실행이 될 때 자동으로 캐시의 데이터를 모두 비운다. 예를 들어 상품카테고리의 카테고리가 추가, 수정, 삭제 될면 이전에 캐시된 신빙성이 떨어지는 데이터를 모두 비우게 할 수 있다.
그러나, 이 속성은 캐시된 데이터를 모두 비우고 새롭게 캐시를 하게 되므로 데이터를 자주 변경하는 매핑 구문에 의존하게 되면 캐시의 효율성이 떨어지게 된다.
<SqlMap namespace="category">
<cacheModel id="categoryCache" type="MEMORY">
...
<flushOnExecute statement="category.insert" />
</cacheModel>
...
<insert id="insert" parameterClass="java.util.Map">
...
</insert>
<flushInterval>
<flushOnExecute> 보다 좀더 간편하게 사용할 수 있는 요소로 시간에 의존하여 지정한 시간이 경과되면 반복적으로 캐시된 데이터를 모두 비운다. 가격은 시(hours),분(minutes),초(seconds) 또는 밀리초(milliseconds)로 지정할 수 있다. <flushInterval>은 하나의 속성만을 허용하기 때문에 5시간 13분 40초와 같이 지정하고 싶다면 초로 계산하여 지정해야 한다. 그리고, 특정 시간을 지정할 수는 없다.
<cacheModel id="categoryCache" type="MEMORY">
...
<flushInterval hours="12" />
</cacheModel>
-- CacheModel Properties 설정하기
CacheModel은 플러그인의 형태로 제공되기 때문에 임의의 설정 값을 제공할 수 있는 방법이 필요한데 <property>를 이용하여 처리한다.
* <property> 요소의 속성들 *
name : 필수입력으로 설정할 프로퍼티의 이름
value : 필수입력으로 설정할 프로퍼티의 값
-- CacheModel Type
앞에서 언급했듯이 iBatis에서 사용할 수 있는 CacheModel Type은 MEMORY, LRU, FIFO, OSCACHE 4가지가 있다.
MEMORY
객체 참조를 기반으로 한 캐시이다. 캐시 내의 각 객체의 참조 타입(<reference-type>) 속성을 갖고 있다. 객체의 참조 타입은 가비지 켈렉터에게 객체를 어떻게 다룰지에 대한 힌트를 제공한다. MEMORY CacheModel은 객체에 접근하는 방식보다는 메모리 관리에 중점을 둔 Application에 적합하다.
* MEMORY CacheModel 참조 타입 *
WEAK : 캐시된 데이터를 빨리 비운다. 기본설정 값이며 가비지 켈렉터에 의해 수거되는 것을 막지않고 놔둔다. 이 방식은 일관성 있게 객체에 접근하는 캐시를 사용할 때 잘 적동한다. 캐시를 비우는 비율이 빠른편이기 때문에 메모리 제한을 넘기지 못하도록 보장은 하나 DataBase 접근확률이 높아진다.
SOFT : 메모리 용량이 허락하는 한 캐시된 객체를 보관한다. 가비지 켈렉터는 더 많은 메모리가 필요하다고 판단되기 전까지는 이 객체들을 수거하지 않는다. 메모리 제한을 넘기지 못하도록 보장하며, WEAK 참조보다 DataBase 접근확률은 적은 편이다.
STRONG : 메모리의 한계가 얼마든지 관계없이 객체를 계속 보관한다. 가비지 켈렉터에 의한 수거는 없다. 이 참조타입은 정적이고 작고 장기적으로 사용할 객체를 캐시할 때 유용하다. DataBase 접근확률은 최소할 수 있으나, 캐시되는 객체의 용량이 너무 커져서 메모리 부족이 발생될 수 있다.
<cacheModel id="categoryCache" type="MEMORY">
<flushInterval hours="12" />
<flushOnExecute statement="insert" />
<property name="reference-type" value="WEAK" />
</cacheModel>
LRU
가장 최근에 가장 오랫동안 사용되자 않은 것을 제거하는 방식으로 캐시를 관리한다. 캐시의 객체를 제거하는 것은 오직 캐시의 용량이 제한을 넘겼을 때 한번만 발생된다. 특정 객체에 아주 빈번하게 접근하는 캐시를 관리할 때 매우 적합하다. <property> 요소를 사용하여 지정할 수 있는 프로퍼티는 size 하나로 캐시에 저장될 수 있는 최대 개수를 지정한다.
<cacheModel id="categoryCache" type="LRU">
<flushInterval hours="12" />
<flushOnExecute statement="insert" />
<property name="size" value="200" />
</cacheModel>
FIFO
먼저 캐시 된 객체를 먼저 삭제한다. 캐시의 객체를 제거하는 것은 오직 캐시의 용량이 제한을 넘겼을 때 한번만 발생된다. 생존기간에 기반을 두고 있기 때문에 초기에 캐시에 저장되는 그 순간에 더 많이 사용되는 객체를 캐싱할때 효과적이다. <property> 요소를 사용하여 지정할 수 있는 프로퍼티는 size 하나로 캐시에 저장될 수 있는 최대 개수를 지정한다.
<cacheModel id="categoryCache" type="FIFO">
<flushInterval hours="12" />
<flushOnExecute statement="insert" />
<property name="size" value="200" />
</cacheModel>
OSCACHE
Open Symphoy(http://www.opensymphony.com/oscache)의 OSCache를 사용한다.OSCACHE를 사용하기 위해서는 OSCache 라이브러리와 설정정보가 필요하다.
<cacheModel id="categoryCache" type="OSCACHE">
<flushInterval hours="12" />
<flushOnExecute statement="insert" />
</cacheModel>
사용자가 만든 캐시 모델
앞에서 언급했듯이 iBatis의 캐시 모델은 플러그인되는 형태여서 사용자가 캐시모델을 만들어서 사용할 수 있다. 사용자가 자신의 캐시모델을 만들기 위해서는 com.ibatis.sqlmap.engine.cache.CacheController 인터페이스를 구현하면 되고, 이름은 alias를 사용하면 된다.
# by | 2010/08/27 10:59 | Java - 자바 | 트랙백 | 덧글(0)
<nature>org.eclipse.wst.common.project.facet.core.nature</nature> <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
그리고 이클립스로 가서 프로젝트 설정 - properties - Project Facets로 가서
Java 와 Dynamic Web Module facets 를 선택하면 끝
# by | 2010/08/27 09:46 | 이클립스-Eclipse | 트랙백 | 덧글(0)
# by | 2010/08/19 11:59 | Java - 자바 | 트랙백 | 덧글(0)
# by | 2010/08/03 15:34 | 개발 | 트랙백 | 덧글(0)
# by | 2010/08/02 10:20 | 트랙백 | 덧글(0)
request.getSession().getServletContext().getRealPath("")
이렇게 써야 합니다...
# by | 2010/08/02 09:58 | Java - 자바 | 트랙백 | 덧글(0)
Certificate
First we need to make certificate, this is done by using keytool that is part of J2SE SDK (program will ask for certificate owner information and password, enter 123456 as
password, or you can enter your password, but notice that you have to change it in other commands listen in this tutorial):keytool -genkey -keystore mySrvKeystore -keyalg RSA
After this command you will have certificate file in working directory of issuing keytool command.
Server source code (EchoServer.java)
import javax.net.ssl.SSLServerSocket;import javax.net.ssl.SSLServerSocketFactory;import javax.net.ssl.SSLSocket;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;publicclass EchoServer { public static void main(String[] arstring) { try { SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(9999); SSLSocket sslsocket = (SSLSocket) sslserversocket.accept(); InputStream inputstream = sslsocket.getInputStream(); InputStreamReader inputstreamreader = new InputStreamReader(inputstream); BufferedReader bufferedreader = new BufferedReader(inputstreamreader); String string = null; while ((string = bufferedreader.readLine()) != null) { System.out.println(string); System.out.flush(); } } catch (Exception exception) { exception.printStackTrace(); } }} Compile it by using simple command:
javac EchoServer.java
Client source code (EchoClient.java)
import javax.net.ssl.SSLSocket;import javax.net.ssl.SSLSocketFactory;import java.io.*;publicclass EchoClient { public static void main(String[] arstring) { try { SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("localhost", 9999); InputStream inputstream = System.in; InputStreamReader inputstreamreader = new InputStreamReader(inputstream); BufferedReader bufferedreader = new BufferedReader(inputstreamreader); OutputStream outputstream = sslsocket.getOutputStream(); OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream); BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter); String string = null; while ((string = bufferedreader.readLine()) != null) { bufferedwriter.write(string + '\n'); bufferedwriter.flush(); } } catch (Exception exception) { exception.printStackTrace(); } }} Compile it by using simple command:
javac EchoClient.java
Running server and client using SSL
First copy certificate file that you created before into working directory and run server with these parameters (notice that you have to change keyStore name and/or trustStrorePassword if you specified different options creating certificate:
java -Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=123456 EchoServer
And now again copy certificate file that you created before into working directory and run client with these parameters (notice that you have to change keyStore name and/or trustStrorePassword if you specified different options creating certificate:
java -Djavax.net.ssl.trustStore=mySrvKeystore -Djavax.net.ssl.trustStorePassword=123456
EchoClientIf you want SSL debug information just add these parameters when running server and/or client:
-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol -Djavax.net.debug=ssl
Playing with server and client
Now just type any string on client console and press return. The same string has to appear on server console.
Copyright
This document is copyrighted to Tomas Vilda. You can use it in all ways, but don't change this section and allways include it.
# by | 2010/07/30 18:12 | Java - 자바 | 트랙백 | 덧글(0)
◀ 이전 페이지다음 페이지 ▶