달력

5

« 2024/5 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
2008. 11. 12. 13:31

lsof - LiSt Open Files Enjoy/etc2008. 11. 12. 13:31

lsof (LiSt Open Files) version 4  (revision 4.49)

출처 : http://www.javaservice.net/~java/bbs/read.cgi?m=etc&b=unix&c=r_p&n=959319048


javaservice:/usr/src/# ftp ftp.cert.dfn.de
Connected to concert.cert.dfn.de.
220- \ \ \
220-  ) ) )      The DFN-CERT  / DFN-PCA AnonFtp Archive
220- / / /
220- \ \ \       --------------------------------------------
220- | | |
220- | | |       If you want to contact the DFN-CERT directly
220- | | |       send electronic mail to:
220- | | |
220- | | |            dfncert@cert.dfn.de  (Incidents)
220- | | |       or
220- | | |            ftp@cert.dfn.de      (AnonFtp Server)
220- | | |       or
220- | | |            dfnpca@pca.dfn.de    (DFN-PCA)
220- | | |
220- | | |       The information and tools on this server are
220- | | |       provided "as is". No responsibility is taken
220-   | |       by neither DFN-CERT nor DFN-PCA.
220-   | |
220-     |       All traffic is logged and analysed, if you
220-     |       do not accept this policy, do not log in!
220-
220-Local time in Hamburg, Germany, is Fri Jun 23 09:06:09 2000
220-
220 concert.cert.dfn.de FTP server (Version wu-2.6.0-dfncert(2) Wed May 17 16:33:20
MET DST 2000) ready.
Name (ftp.cert.dfn.de:root): guest
331 Guest login ok, send your complete e-mail address as password.
Password:
230-The response 'guest' is not valid
230-Next time please use your e-mail address as your password
230-        for example: joe@210.220.251.96
230-
230-If you have comments or recommendations concerning this server please
230-contact the local administrators by email: ftp@cert.dfn.de
230-
230-Check also our WWW server:
230-
230-      German language:     http://www.cert.dfn.de/
230-      English language:    http://www.cert.dfn.de/eng/
230-
230 Guest login ok, access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd pub/tools/admin/lsof
250 CWD command successful.
ftp> bin
ha200 Type set to I.
ftp> ha
Hash mark printing on (1024 bytes/hash mark).
ftp> asc
200 Type set to A.
ftp> get README
local: README remote: README
200 PORT command successful.
150 Opening ASCII mode data connection for README (13251 bytes).
##############
226 Transfer complete.
13597 bytes received in 1.15 secs (12 Kbytes/sec)
ftp> bin
200 Type set to I.
ftp> dir
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
total 1572
-rw-rw-r--   1 infosys    28540 Jun  1 23:19 .mirror
-rw-rw-r--   1 infosys    13251 Apr  3 18:28 README
lrwxrwxrwx   1 infosys       18 May  1 23:10 lsof.tar.gz -> lsof_4.49_W.tar.gz
-rw-rw-r--   1 infosys   751995 Apr  3 10:56 lsof_4.49_W.tar.gz
226 Transfer complete.
ftp> get lsof_4.49_W.tar.gz
local: lsof_4.49_W.tar.gz remote: lsof_4.49_W.tar.gz
200 PORT command successful.
150 Opening BINARY mode data connection for lsof_4.49_W.tar.gz (751995 bytes).
####################################################################################
####################################################################################
####################################################################################
####################################################################################
####################################################################################
####################################################################################
####################################################################################
####################################################################################
##############################################################
226 Transfer complete.
751995 bytes received in 496 secs (1.5 Kbytes/sec)
ftp> quit
221-You have transferred 765592 bytes in 2 files.
221-Total traffic for this session was 768123 bytes in 3 transfers.
221-Thank you for using the FTP service on concert.cert.dfn.de.
221 Goodbye.
javaservice:/usr/src/# dir
total 764
   4 drwxr-xr-x   2 root     root         4096 Jun 23 16:10 ./
   4 drwxr-xr-x   5 guest    users        4096 Jun 23 16:09 ../
  16 -rw-r--r--   1 root     root        13251 Jun 23 16:10 README
740 -rw-r--r--   1 root     root       751995 Jun 23 16:19 lsof_4.49_W.tar.gz
javaservice:/usr/src/# mkdir lsof
javaservice:/usr/src/# cd lsof
javaservice:/usr/src/lsof# tar xvfz ../lsof_4.49_W.tar.gz

RELEASE.SUMMARY_4.49
README.lsof_4.49
00.README.FIRST_4.49
lsof_4.49.tar
lsof_4.49.tar.asc
javaservice:/usr/src/lsof# dir
total 3044
   4 drwxr-xr-x   2 root     root         4096 Jun 23 16:21 ./
   4 drwxr-xr-x  10 root     root         4096 Jun 23 16:21 ../
   4 -rw-r--r--   1 701      1233          700 Apr  4 00:55 00.README.FIRST_4.49
   8 -rw-r--r--   1 701      1233         4132 Apr  4 00:55 README.lsof_4.49
  16 -r--r--r--   1 701      1233        13251 Apr  4 00:55 RELEASE.SUMMARY_4.49
3004 -rw-r--r--   1 701      1233      3072000 Apr  4 00:54 lsof_4.49.tar
   4 -rw-r--r--   1 701      1233          284 Apr  4 00:55 lsof_4.49.tar.asc
javaservice:/usr/src/lsof# tar xvf lsof_4.49.tar
lsof_4.49/
lsof_4.49/00.README.FIRST
lsof_4.49/00CREDITS
lsof_4.49/00DCACHE
lsof_4.49/00DIALECTS
lsof_4.49/00DIST
lsof_4.49/00FAQ
lsof_4.49/00LSOF-L
lsof_4.49/00MANIFEST
lsof_4.49/00PORTING
lsof_4.49/00QUICKSTART
lsof_4.49/00README
lsof_4.49/00XCONFIG
lsof_4.49/AFSConfig
lsof_4.49/Configure
lsof_4.49/Customize
lsof_4.49/Inventory
lsof_4.49/dialects/
lsof_4.49/dialects/n+os/
lsof_4.49/dialects/n+os/dproc.c
lsof_4.49/dialects/n+os/Mksrc
lsof_4.49/dialects/n+os/dnode.c
lsof_4.49/dialects/n+os/dlsof.h
lsof_4.49/dialects/n+os/Makefile
lsof_4.49/dialects/n+os/dsock.c
lsof_4.49/dialects/n+os/machine.h
lsof_4.49/dialects/n+os/dproto.h
lsof_4.49/dialects/n+os/dnode1.c
lsof_4.49/dialects/n+os/dstore.c
lsof_4.49/dialects/ultrix/
lsof_4.49/dialects/ultrix/Makefile
lsof_4.49/dialects/ultrix/dlsof.h
lsof_4.49/dialects/ultrix/dmnt.c
lsof_4.49/dialects/ultrix/dnode.c
lsof_4.49/dialects/ultrix/dproc.c
lsof_4.49/dialects/ultrix/dproto.h
lsof_4.49/dialects/ultrix/dsock.c
lsof_4.49/dialects/ultrix/dstore.c
lsof_4.49/dialects/ultrix/machine.h
lsof_4.49/dialects/ultrix/Mksrc
lsof_4.49/dialects/aix/
lsof_4.49/dialects/aix/dnode1.c
lsof_4.49/dialects/aix/dlsof.h
lsof_4.49/dialects/aix/Mksrc
lsof_4.49/dialects/aix/ddev.c
lsof_4.49/dialects/aix/dproto.h
lsof_4.49/dialects/aix/machine.h
lsof_4.49/dialects/aix/Makefile
lsof_4.49/dialects/aix/dfile.c
lsof_4.49/dialects/aix/dnode.c
lsof_4.49/dialects/aix/dmnt.c
lsof_4.49/dialects/aix/dproc.c
lsof_4.49/dialects/aix/dsock.c
lsof_4.49/dialects/aix/dstore.c
lsof_4.49/dialects/sun/
lsof_4.49/dialects/sun/machine.h
lsof_4.49/dialects/sun/dproc.c
lsof_4.49/dialects/sun/Mksrc
lsof_4.49/dialects/sun/dsock.c
lsof_4.49/dialects/sun/include/
lsof_4.49/dialects/sun/include/sys/
lsof_4.49/dialects/sun/include/sys/auxv.h
lsof_4.49/dialects/sun/dnode2.c
lsof_4.49/dialects/sun/dfile.c
lsof_4.49/dialects/sun/dnode.c
lsof_4.49/dialects/sun/ddev.c
lsof_4.49/dialects/sun/dstore.c
lsof_4.49/dialects/sun/Makefile
lsof_4.49/dialects/sun/dproto.h
lsof_4.49/dialects/sun/dmnt.c
lsof_4.49/dialects/sun/dnode1.c
lsof_4.49/dialects/sun/dlsof.h
lsof_4.49/dialects/freebsd/
lsof_4.49/dialects/freebsd/Mksrc
lsof_4.49/dialects/freebsd/dnode.c
lsof_4.49/dialects/freebsd/dlsof.h
lsof_4.49/dialects/freebsd/dmnt.c
lsof_4.49/dialects/freebsd/dnode1.c
lsof_4.49/dialects/freebsd/include/
lsof_4.49/dialects/freebsd/include/procfs/
lsof_4.49/dialects/freebsd/include/procfs/pfsnode.h
lsof_4.49/dialects/freebsd/Makefile
lsof_4.49/dialects/freebsd/dsock.c
lsof_4.49/dialects/freebsd/dstore.c
lsof_4.49/dialects/freebsd/machine.h
lsof_4.49/dialects/freebsd/dproc.c
lsof_4.49/dialects/freebsd/dproto.h
lsof_4.49/dialects/hpux/
lsof_4.49/dialects/hpux/kmem/
lsof_4.49/dialects/hpux/kmem/Makefile
lsof_4.49/dialects/hpux/kmem/Mksrc
lsof_4.49/dialects/hpux/kmem/dfile.c
lsof_4.49/dialects/hpux/kmem/dlsof.h
lsof_4.49/dialects/hpux/kmem/dmnt.c
lsof_4.49/dialects/hpux/kmem/dnode.c
lsof_4.49/dialects/hpux/kmem/dnode1.c
lsof_4.49/dialects/hpux/kmem/dnode2.c
lsof_4.49/dialects/hpux/kmem/dproc.c
lsof_4.49/dialects/hpux/kmem/dproto.h
lsof_4.49/dialects/hpux/kmem/dsock.c
lsof_4.49/dialects/hpux/kmem/dstore.c
lsof_4.49/dialects/hpux/kmem/machine.h
lsof_4.49/dialects/hpux/kmem/hpux11/
lsof_4.49/dialects/hpux/kmem/hpux11/rnode.h
lsof_4.49/dialects/hpux/kmem/hpux11/vnode.h
lsof_4.49/dialects/hpux/kmem/hpux11/kernbits.h
lsof_4.49/dialects/hpux/kmem/hpux11/proc.h
lsof_4.49/dialects/hpux/kmem/hpux11/nfs_clnt.h
lsof_4.49/dialects/hpux/kmem/hpux11/lla.h
lsof_4.49/dialects/hpux/kmem/hpux11/sth.h
lsof_4.49/dialects/hpux/kmem/hpux11/ipc_s.h
lsof_4.49/dialects/hpux/kmem/hpux11/udp_s.h
lsof_4.49/dialects/hpux/kmem/hpux11/tcp_s.h
lsof_4.49/dialects/linux/
lsof_4.49/dialects/linux/kmem/
lsof_4.49/dialects/linux/kmem/patches/
lsof_4.49/dialects/linux/kmem/patches/Linux-mouse-module.patch
lsof_4.49/dialects/linux/kmem/Makefile
lsof_4.49/dialects/linux/kmem/Makefile.lseek
lsof_4.49/dialects/linux/kmem/Mksrc
lsof_4.49/dialects/linux/kmem/__lseek.s
lsof_4.49/dialects/linux/kmem/dfile.c
lsof_4.49/dialects/linux/kmem/dlsof.h
lsof_4.49/dialects/linux/kmem/dmnt.c
lsof_4.49/dialects/linux/kmem/dnode.c
lsof_4.49/dialects/linux/kmem/dproc.c
lsof_4.49/dialects/linux/kmem/dproto.h
lsof_4.49/dialects/linux/kmem/dsock.c
lsof_4.49/dialects/linux/kmem/dstore.c
lsof_4.49/dialects/linux/kmem/machine.h
lsof_4.49/dialects/linux/proc/
lsof_4.49/dialects/linux/proc/Makefile
lsof_4.49/dialects/linux/proc/machine.h
lsof_4.49/dialects/linux/proc/Mksrc
lsof_4.49/dialects/linux/proc/dfile.c
lsof_4.49/dialects/linux/proc/dlsof.h
lsof_4.49/dialects/linux/proc/dmnt.c
lsof_4.49/dialects/linux/proc/dnode.c
lsof_4.49/dialects/linux/proc/dproc.c
lsof_4.49/dialects/linux/proc/dproto.h
lsof_4.49/dialects/linux/proc/dsock.c
lsof_4.49/dialects/linux/proc/dstore.c
lsof_4.49/dialects/linux/proc/patches/
lsof_4.49/dialects/linux/proc/patches/net_ipx_af_ipx.c.patch
lsof_4.49/dialects/linux/proc/patches/README
lsof_4.49/dialects/n+obsd/
lsof_4.49/dialects/n+obsd/dnode.c
lsof_4.49/dialects/n+obsd/dsock.c
lsof_4.49/dialects/n+obsd/Mksrc
lsof_4.49/dialects/n+obsd/dlsof.h
lsof_4.49/dialects/n+obsd/dmnt.c
lsof_4.49/dialects/n+obsd/dproc.c
lsof_4.49/dialects/n+obsd/dstore.c
lsof_4.49/dialects/n+obsd/dnode1.c
lsof_4.49/dialects/n+obsd/machine.h
lsof_4.49/dialects/n+obsd/Makefile
lsof_4.49/dialects/n+obsd/dproto.h
lsof_4.49/dialects/du/
lsof_4.49/dialects/du/dlsof.h
lsof_4.49/dialects/du/Mksrc
lsof_4.49/dialects/du/dnode.c
lsof_4.49/dialects/du/ddev.c
lsof_4.49/dialects/du/dmnt.c
lsof_4.49/dialects/du/dproc.c
lsof_4.49/dialects/du/dstore.c
lsof_4.49/dialects/du/dproto.h
lsof_4.49/dialects/du/dsock.c
lsof_4.49/dialects/du/dfile.c
lsof_4.49/dialects/du/machine.h
lsof_4.49/dialects/du/Makefile
lsof_4.49/dialects/osr/
lsof_4.49/dialects/osr/include/
lsof_4.49/dialects/osr/include/sys/
lsof_4.49/dialects/osr/include/sys/cdefs.h
lsof_4.49/dialects/osr/include/netdb.h
lsof_4.49/dialects/osr/dproc.c
lsof_4.49/dialects/osr/Mksrc
lsof_4.49/dialects/osr/dlsof.h
lsof_4.49/dialects/osr/dmnt.c
lsof_4.49/dialects/osr/dsock.c
lsof_4.49/dialects/osr/dstore.c
lsof_4.49/dialects/osr/dfile.c
lsof_4.49/dialects/osr/dnode.c
lsof_4.49/dialects/osr/machine.h
lsof_4.49/dialects/osr/Makefile
lsof_4.49/dialects/osr/dproto.h
lsof_4.49/dialects/bsdi/
lsof_4.49/dialects/bsdi/Mksrc
lsof_4.49/dialects/bsdi/dfile.c
lsof_4.49/dialects/bsdi/Makefile
lsof_4.49/dialects/bsdi/dproc.c
lsof_4.49/dialects/bsdi/dproto.h
lsof_4.49/dialects/bsdi/dsock.c
lsof_4.49/dialects/bsdi/dstore.c
lsof_4.49/dialects/bsdi/machine.h
lsof_4.49/dialects/bsdi/dlsof.h
lsof_4.49/dialects/bsdi/dmnt.c
lsof_4.49/dialects/bsdi/dnode.c
lsof_4.49/dialects/uw/
lsof_4.49/dialects/uw/uw21/
lsof_4.49/dialects/uw/uw21/fs/
lsof_4.49/dialects/uw/uw21/fs/proc/
lsof_4.49/dialects/uw/uw21/fs/proc/prdata.h
lsof_4.49/dialects/uw/uw21/fs/proc/README
lsof_4.49/dialects/uw/uw21/fs/procfs/
lsof_4.49/dialects/uw/uw21/fs/procfs/prdata.h
lsof_4.49/dialects/uw/uw21/fs/procfs/README
lsof_4.49/dialects/uw/uw21/sys/
lsof_4.49/dialects/uw/uw21/sys/fs/
lsof_4.49/dialects/uw/uw21/sys/fs/fifonode.h
lsof_4.49/dialects/uw/uw21/sys/fs/namenode.h
lsof_4.49/dialects/uw/uw21/vm/
lsof_4.49/dialects/uw/Makefile
lsof_4.49/dialects/uw/Mksrc
lsof_4.49/dialects/uw/dfile.c
lsof_4.49/dialects/uw/dlsof.h
lsof_4.49/dialects/uw/dmnt.c
lsof_4.49/dialects/uw/dnode.c
lsof_4.49/dialects/uw/dnode1.c
lsof_4.49/dialects/uw/dnode2.c
lsof_4.49/dialects/uw/machine.h
lsof_4.49/dialects/uw/dsock.c
lsof_4.49/dialects/uw/uw7/
lsof_4.49/dialects/uw/uw7/vm/
lsof_4.49/dialects/uw/uw7/sys/
lsof_4.49/dialects/uw/uw7/sys/fs/
lsof_4.49/dialects/uw/uw7/sys/fs/namenode.h
lsof_4.49/dialects/uw/uw7/sys/fs/fifonode.h
lsof_4.49/dialects/uw/uw7/fs/
lsof_4.49/dialects/uw/uw7/fs/procfs/
lsof_4.49/dialects/uw/uw7/fs/procfs/prdata.h
lsof_4.49/dialects/uw/uw7/fs/procfs/README
lsof_4.49/dialects/uw/dstore.c
lsof_4.49/dialects/uw/dproc.c
lsof_4.49/dialects/uw/dproto.h
lsof_4.49/dialects/uw/dnode3.c
lsof_4.49/dialects/ptx/
lsof_4.49/dialects/ptx/Makefile
lsof_4.49/dialects/ptx/Mksrc
lsof_4.49/dialects/ptx/dfile.c
lsof_4.49/dialects/ptx/dlsof.h
lsof_4.49/dialects/ptx/dmnt.c
lsof_4.49/dialects/ptx/dnode.c
lsof_4.49/dialects/ptx/dproc.c
lsof_4.49/dialects/ptx/dproto.h
lsof_4.49/dialects/ptx/dsock.c
lsof_4.49/dialects/ptx/dstore.c
lsof_4.49/dialects/ptx/machine.h
lsof_4.49/dialects/ptx/dnode2.c
lsof_4.49/dialects/ptx/dnode1.c
lsof_4.49/dialects/ptx/ddev.c
lsof_4.49/dialects/pyramid/
lsof_4.49/dialects/pyramid/Mksrc
lsof_4.49/dialects/pyramid/dfile.c
lsof_4.49/dialects/pyramid/dproc.c
lsof_4.49/dialects/pyramid/dlsof.h
lsof_4.49/dialects/pyramid/dmnt.c
lsof_4.49/dialects/pyramid/dnode.c
lsof_4.49/dialects/pyramid/dnode1.c
lsof_4.49/dialects/pyramid/dnode2.c
lsof_4.49/dialects/pyramid/dsock.c
lsof_4.49/dialects/pyramid/dproto.h
lsof_4.49/dialects/pyramid/dstore.c
lsof_4.49/dialects/pyramid/machine.h
lsof_4.49/dialects/pyramid/MkKernOpts
lsof_4.49/dialects/pyramid/Makefile
lsof_4.49/dialects/pyramid/dnode3.c
lsof_4.49/arg.c
lsof_4.49/lib/
lsof_4.49/lib/cvfs.c
lsof_4.49/lib/dvch.c
lsof_4.49/lib/fino.c
lsof_4.49/lib/isfn.c
lsof_4.49/lib/lkud.c
lsof_4.49/lib/prfp.c
lsof_4.49/lib/rdev.c
lsof_4.49/lib/rmnt.c
lsof_4.49/lib/rnam.c
lsof_4.49/lib/rnch.c
lsof_4.49/lib/pdvn.c
lsof_4.49/lib/Makefile.skel
lsof_4.49/lib/rnmh.c
lsof_4.49/lib/ckkv.c
lsof_4.49/lib/ptti.c
lsof_4.49/lsof.h
lsof_4.49/lsof_fields.h
lsof_4.49/main.c
lsof_4.49/misc.c
lsof_4.49/node.c
lsof_4.49/print.c
lsof_4.49/proc.c
lsof_4.49/proto.h
lsof_4.49/scripts/
lsof_4.49/scripts/idrlogin.perl5
lsof_4.49/scripts/list_fields.awk
lsof_4.49/scripts/idrlogin.perl
lsof_4.49/scripts/00README
lsof_4.49/scripts/count_pf.perl5
lsof_4.49/scripts/watch_a_file.perl
lsof_4.49/scripts/big_brother.perl5
lsof_4.49/scripts/00MANIFEST
lsof_4.49/scripts/list_NULf.perl5
lsof_4.49/scripts/list_fields.perl
lsof_4.49/scripts/count_pf.perl
lsof_4.49/scripts/xusers.awk
lsof_4.49/scripts/identd.perl5
lsof_4.49/scripts/shared.perl5
lsof_4.49/store.c
lsof_4.49/usage.c
lsof_4.49/version
lsof_4.49/lsof.8
lsof_4.49/lsof.man
javaservice:/usr/src/lsof# cd lsof_4.49
javaservice:/usr/src/lsof/lsof_4.49# ls

total 1080
   4 00.README.FIRST    36 00QUICKSTART     4 lib/             24 proc.c
   8 00CREDITS          56 00README        96 lsof.8           12 proto.h
  32 00DCACHE           20 00XCONFIG       20 lsof.h            4 scripts/
   4 00DIALECTS          8 AFSConfig*     112 lsof.man         16 store.c
  88 00DIST             92 Configure*       8 lsof_fields.h    16 usage.c
156 00FAQ              24 Customize*      24 main.c            4 version
   4 00LSOF-L            8 Inventory*      28 misc.c
   4 00MANIFEST         40 arg.c            8 node.c
  56 00PORTING           4 dialects/       60 print.c
javaservice:/usr/src/lsof/lsof_4.49# ./Configure
No target dialect was specified.
Usage: Configure <options> <target-dialect>
  <options>:  -clean        : clean up previous configuration
              -d|-dialects  : display a list of supported dialect versions
              -h|-help      : display help information
              -n            : avoid AFS, customization, and inventory checks
  <target-dialect> (****USE -d TO GET TESTED DIALECT VERSION NUMBERS****):
    aix|aixgcc              : IBM AIX xlc (aix) or gcc (aixgcc)
    bsdi                    : BSDI BSD/OS
    decosf                  : DEC OSF/1
    digital_unix|du         : Digital UNIX
    freebsd                 : FreeBSD
    hpux|hpuxgcc            : HP-UX cc (hpux) or gcc (hpuxgcc)
    linux                   : Linux
    netbsd                  : NetBSD
    nextstep|next|ns|nxt    : NEXTSTEP
    openbsd                 : OpenBSD
    openstep|os             : OpenStep
    osr|sco                 : SCO OpenServer, SCO devloper's compiler
    osrgcc|scogcc           : SCO OpenServer, gcc compiler
    pyramid|pyr             : Pyramid DC/OSx and Reliant UNIX
    ptx                     : Sequent PTX
    solaris|solariscc       : Solaris gcc (solaris) or cc (solariscc)
    sunos|sunoscc           : SunOS gcc (sunos) or cc (sunoscc)
    tru64                   : Tru64 UNIX
    ultrix                  : Ultrix
    unixware|uw             : SCO UnixWare
javaservice:/usr/src/lsof/lsof_4.49# ./Configure linux
Testing C library type with cc ... done
The C library type is glibc, version "-DGLIBCV=201".
Configuring /proc-based Linux lsof

This configuration step (the Inventory script) takes inventory of
the lsof distribution.  The script runs for a minute or two while
it checks that all the subdirectories, information files, scripts,
header files and source files that should be present really are.

It's not absolutely necessary that you take inventory, but it's a
good idea to do it right after the lsof distribution has been
unpacked.  Once the inventory has been taken, this script creates
the file ./.ck00MAN as a signal that the inventory step has been
done.

You can call the Inventory script directly at any time to take
inventory.  You can inhibit the inventory step permanently by
creating the file ./.neverInv, and you can tell the Configure script
to skip the inventory and customization steps with the -n option.

Do you want to take inventory (y|n) [y]?

Conducting an inventory of the lsof distribution; this will take a while.

Examining /usr/src/lsof/lsof_4.49: OK
Examining dialects: OK
Examining dialects/aix: OK
Examining dialects/bsdi: OK
Examining dialects/du: OK
Examining dialects/freebsd: OK
Examining dialects/freebsd/include: OK
Examining dialects/freebsd/include/procfs: OK
Examining dialects/hpux: OK
Examining dialects/hpux/kmem: OK
Examining dialects/hpux/kmem/hpux11: OK
Examining dialects/linux: OK
Examining dialects/linux/kmem: OK
Examining dialects/linux/kmem/patches: OK
Examining dialects/linux/proc: OK
Examining dialects/linux/proc/patches: OK
Examining dialects/n+obsd: OK
Examining dialects/n+os: OK
Examining dialects/osr: OK
Examining dialects/osr/include: OK
Examining dialects/osr/include/sys: OK
Examining dialects/ptx: OK
Examining dialects/pyramid: OK
Examining dialects/sun: OK
Examining dialects/sun/include: OK
Examining dialects/sun/include/sys: OK
Examining dialects/ultrix: OK
Examining dialects/uw: OK
Examining dialects/uw/uw21: OK
Examining dialects/uw/uw21/fs: OK
Examining dialects/uw/uw21/fs/proc: OK
Examining dialects/uw/uw21/fs/procfs: OK
Examining dialects/uw/uw21/sys: OK
Examining dialects/uw/uw21/sys/fs: OK
Examining dialects/uw/uw21/vm: OK
Examining dialects/uw/uw7: OK
Examining dialects/uw/uw7/fs: OK
Examining dialects/uw/uw7/fs/procfs: OK
Examining dialects/uw/uw7/sys: OK
Examining dialects/uw/uw7/sys/fs: OK
Examining dialects/uw/uw7/vm: OK
Examining lib: OK
Examining scripts: OK

This lsof distribution seems to be complete.

rm -f ddev.c dfile.c dlsof.h dmnt.c dnode*.c dproc.c dproto.h dsock.c dstore.c kerne
lbase.h machine.h machine.h.old new_machine.h __lseek.s Makefile
ln -s dialects/linux/proc/dfile.c dfile.c
ln -s dialects/linux/proc/dlsof.h dlsof.h
ln -s dialects/linux/proc/dmnt.c dmnt.c
ln -s dialects/linux/proc/dnode.c dnode.c
ln -s dialects/linux/proc/dproc.c dproc.c
ln -s dialects/linux/proc/dproto.h dproto.h
ln -s dialects/linux/proc/dsock.c dsock.c
ln -s dialects/linux/proc/dstore.c dstore.c
ln -s dialects/linux/proc/machine.h machine.h
Makefile and lib/Makefile created.

You may now customize the machine.h header file for this UNIX
dialect.  The customizations will take effect when you compile
lsof.  You may also choose to skip customization and proceed to
the compilation of lsof.

If you don't know if you need to customize or want to know more
about what you can customize, consult the 00DCACHE, 00FAQ, 00PORTING,
and 00README files of the lsof distribution.  You might also find
it helpful to examine the machine.h header file for the dialect
you're customizing.

You don't need to use this procedure to customize lsof; you can
edit the machine.h header file directly.  If you later decide you
want to use this procedure to customize machine.h, execute the
./Customize script.

Do you want to customize (y|n) [y]?

Customizing ...

=====================================================================

When HASSECURITY is enabled, only the root user may use lsof to
examine all open files; other users may examine only the files
belonging to the real user ID of their lsof process.

When HASSECURITY is disabled, anyone may use lsof to examine all
open files.

HASSECURITY is disabled.

Enable HASSECURITY (y|n) [n]?

HASSECURITY will not be changed.

=====================================================================

When WARNINGSTATE is enabled, lsof will will issue whatever warning
messages it finds necessary.  When WARNINGSTATE is disabled, lsof
will issue no warning messages.  For individual uses of lsof, -w
disables warning state and +w enables it.

WARNINGSTATE is enabled.

Disable WARNINGSTATE? (y|n) [n]?

WARNINGSTATE will not be changed.

=====================================================================

A new machine.h file has been created in "new_machine.h".

Do you want to rename machine.h to machine.h.old and replace it with
new_machine.h (y|n) [y]?

You may now run the make command -- e.g.,

        $ make

javaservice:/usr/src/lsof/lsof_4.49#
javaservice:/usr/src/lsof/lsof_4.49# make
(cd lib; make DEBUG="-O" CFGF="-DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2
.2.12-20kr\"")
make[1]: Entering directory `/usr/src/lsof/lsof_4.49/lib'
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c ckkv.c
-o ckkv.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c cvfs.c
-o cvfs.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c dvch.c
-o dvch.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c fino.c
-o fino.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c isfn.c
-o isfn.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c lkud.c
-o lkud.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c pdvn.c
-o pdvn.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c prfp.c
-o prfp.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c ptti.c
-o ptti.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c rdev.c
-o rdev.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c rmnt.c
-o rmnt.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c rnam.c
-o rnam.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c rnch.c
-o rnch.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR="2.2.12-20kr"  -O   -c rnmh.c
-o rnmh.o
ar cr liblsof.a ckkv.o cvfs.o dvch.o fino.o isfn.o lkud.o pdvn.o prfp.o ptti.o rdev.
o rmnt.o rnam.o rnch.o rnmh.o
ranlib liblsof.a
make[1]: Leaving directory `/usr/src/lsof/lsof_4.49/lib'
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c dfi
le.c -o dfile.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c dmn
t.c -o dmnt.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c dno
de.c -o dnode.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c dpr
oc.c -o dproc.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c dso
ck.c -o dsock.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c dst
ore.c -o dstore.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c arg
.c -o arg.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c mai
n.c -o main.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c mis
c.c -o misc.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c nod
e.c -o node.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c pri
nt.c -o print.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c pro
c.c -o proc.o
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c sto
re.c -o store.o
Constructing version.h
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c usa
ge.c -o usage.o
cc -o lsof dfile.o dmnt.o dnode.o dproc.o dsock.o dstore.o arg.o main.o misc.o node.
o print.o proc.o store.o usage.o -L./lib -llsof
javaservice:/usr/src/lsof/lsof_4.49# make install
(cd lib; make DEBUG="-O" CFGF="-DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2
.2.12-20kr\"")
make[1]: Entering directory `/usr/src/lsof/lsof_4.49/lib'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/usr/src/lsof/lsof_4.49/lib'
Constructing version.h
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c usa
ge.c -o usage.o
cc -o lsof dfile.o dmnt.o dnode.o dproc.o dsock.o dstore.o arg.o main.o misc.o node.
o print.o proc.o store.o usage.o -L./lib -llsof

Please write your own install rule.  Lsof should be installed
setuid to root if you wish any lsof user to be able to examine
all open files.  Your install rule actions might look something
like this:

    install -m 4xxx -o root -g <group> ${PROG} ${BIN}
    install -m 444 ${MAN} ${DOC}

You will have to complete the 4xxx modes, the <group> value,
and the skeletons for the BIN and DOC strings, given at the
beginning of this Makefile, e.g.,

    BIN= ${DESTDIR}/usr/local/etc
    DOC= ${DESTDIR}/usr/man/man8
    GRP= sys

javaservice:/usr/src/lsof/lsof_4.49# ls
total 1364
   4 00.README.FIRST     8 Inventory*     0 dsock.c@          12 misc.o
   8 00CREDITS           4 Makefile      24 dsock.o            8 node.c
  32 00DCACHE           40 arg.c          0 dstore.c@          4 node.o
   4 00DIALECTS         16 arg.o          4 dstore.o          60 print.c
  88 00DIST              0 dfile.c@       4 lib/              20 print.o
156 00FAQ               4 dfile.o      104 lsof*             24 proc.c
   4 00LSOF-L            4 dialects/     96 lsof.8            12 proc.o
   4 00MANIFEST          0 dlsof.h@      20 lsof.h            12 proto.h
  56 00PORTING           0 dmnt.c@      112 lsof.man           4 scripts/
  36 00QUICKSTART        4 dmnt.o         8 lsof_fields.h     16 store.c
  56 00README            0 dnode.c@      16 machine.h          8 store.o
  20 00XCONFIG           8 dnode.o        0 machine.h.old@    16 usage.c
   8 AFSConfig*          0 dproc.c@      24 main.c            12 usage.o
  92 Configure*         12 dproc.o       16 main.o             4 version
  24 Customize*          0 dproto.h@     28 misc.c             4 version.h
javaservice:/usr/src/lsof/lsof_4.49# make install
(cd lib; make DEBUG="-O" CFGF="-DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2
.2.12-20kr\"")
make[1]: Entering directory `/usr/src/lsof/lsof_4.49/lib'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/usr/src/lsof/lsof_4.49/lib'
Constructing version.h
cc  -DLINUXV=22012 -DGLIBCV=201 -DHASIPv6 -DLSOF_VSTR=\"2.2.12-20kr\"    -O   -c usa
ge.c -o usage.o
cc -o lsof dfile.o dmnt.o dnode.o dproc.o dsock.o dstore.o arg.o main.o misc.o node.
o print.o proc.o store.o usage.o -L./lib -llsof

Please write your own install rule.  Lsof should be installed
setuid to root if you wish any lsof user to be able to examine
all open files.  Your install rule actions might look something
like this:

    install -m 4xxx -o root -g <group> ${PROG} ${BIN}
    install -m 444 ${MAN} ${DOC}

You will have to complete the 4xxx modes, the <group> value,
and the skeletons for the BIN and DOC strings, given at the
beginning of this Makefile, e.g.,

    BIN= ${DESTDIR}/usr/local/etc
    DOC= ${DESTDIR}/usr/man/man8
    GRP= sys

javaservice:/usr/src/lsof/lsof_4.49# install -m 4755 -o root -g root lsof /usr/local/bin
javaservice:/usr/src/lsof/lsof_4.49# mkdir /usr/local/man/man8
javaservice:/usr/src/lsof/lsof_4.49# cp lsof.8 /usr/local/man/man8/
javaservice:/usr/src/lsof/lsof_4.49#
javaservice:/usr/src/lsof/lsof_4.49#



PS: solaris 용 lsof 는 아래 문서를 참조하세요.
http://www.javaservice.net/~java/bbs/read.cgi?m=unix&b=unix&c=r_p&n=991922524

PS: AIX용 binary 파일 첨부합니다. (lsof_aix_binary.tar)
   그러나 가급적, 소스를(lsof_4.56_W.tar.gz) 다운받아 직접 컴파일하세요




:
Posted by 라면스프

출처 : http://kwon37xi.egloos.com/3666564

OKJSP에 자주 가서 요즘 자바 개발자들이 어떻게 살아가나를 보는 편인데, 아주 많이 반복적으로 올라오는 질문이 "대체 뭘 공부해야 하나요? 프레임워크는 Spring을 해야 할까요? iBATIS를 해야 할까요?" 하는 식의 질문들이다(이 질문은 사실 말이 안된다. 왜 그런지 읽다보면 나온다).

Java는 웹 관련 프레임워크들이 너무 다양하고, Ruby나 Python 같은 경우에는 RubyOnRailsDjango 처럼 하나의 프레임워크 안에 기능별 프레임워크들도 모두 다 All in one 형태로 들어 있어서 혼란을 주지 않는 반면, Java는 각 영역별로 프레임워크가 모두 다르고, 또한 각 영역별로 존재하는 프레임워크들의 종류도 많아서 초보 개발자들에게 극심한 혼란을 주고 있다.

그래서 나름대로 Java Web 개발자들을 위한 학습 로드맵을 정리해 보았다.

1. Java 그 자체
많은 웹 개발자들이 마치 JSP 코드를 짤 줄 알면 그걸로 Java 웹 개발을 할 줄아는 것이라 생각하고 Java 그 자체를 소홀히 하는 것을 본다.
말도 안되는 소리이다. Java를 모르고서 Java 웹 개발을 제대로 한다는 것은 어불 성설이다. Java 그 자체를 먼저 공부하라.

특히 Java 5 문법을 숙지하길 권한다. 이제 우리나라도 점차 Java 5가 대세가 되어 가고 있다. 대부분의 프레임워크들과 WAS(JSP와 서블릿을 구동하는 서버)도 모두 Java 5를 기준으로 바뀌었으며, JVM 자체도 버전이 높을 수록 성능이 더 좋다.

2. JSP와 Servlet 그리고 Model 1
모델 1은, JSP 하나에 DB에 접속해서 쿼리를 날리는 등의 모든 업무적인 기능(Business Logic)을 넣고, 그 아래에 HTML 코드를 박아 넣는 식으로 개발하는 것을 의미한다.
아직도 많은 개발자들이 여기에 길들여져 있는데, 일단 JSP 자체에 대한 기본기를 익힌 뒤로는 재빨리 버려야 할 습관이다.

그리고 많은 개발자들이 Servlet을 무시하고 JSP만 하는 것을 보곤 하는데, Servlet에 대한 학습이 제대로 이뤄지지 않으면 더 나은 웹 개발이 곤란하다. Servlet에 대한 기초 개념을 확실히 잡길 권한다.

3. Model 2 - 프레임워크의 등장
JSP로 열심히 개발을 하다보니 프로젝트 규모도 커지기 시작하고, JSP 파일 크기도 수천줄에 달하는등 엄청나게 커진다.
그런데 이 JSP에다 두서없이 모든 기능을 다 때려 넣다보니 JSP마다 똑같은 기능들이 Copy&Paste로 들어가고, JSP 안에 들어 있는 Java 코드들에서 에러가 발생하면 찾아내서 디버깅 하는 일이 지옥같이 느껴지기 시작한다.

여기서 Model 2가 구원자로 등장한다.

Model 2는 말만 멋드러졌지 실제로는 간단한 개념이다.

JSP에서 수행하던 DB 쿼리 등의 작업을 Servlet에게 넘겨주고 JSP에서는 오로지 화면 출력만 담당하는 것이다.

Servlet에서 DB 쿼리등 화면 출력과는 상관없는 비지니스 로직을 일단 먼저 모두 수행하고, 그 결과를 request.setAttribute("key",결과객체);로 담은 다음 JSP 페이지로 포워딩(forward)을 하면 JSP에서는 request.getAttribute("key")로 그 객체를 받아서 화면에 뿌려주기만 한다.
이런 업무 수행단/화면 출력단의 철저한 역할 분리가 Model 2이다.

여기서 이러한 각 역할을 "MVC - Model View Controller" 라고 한다. 그래서 Model 2는 MVC와 동일한 의미로 사용하기 도 한다. MVC의 의미는 공부하면서 찾아보라.

이게 뭐가 좋냐고? 개발 기간이 좀 길어지고 프로젝트 규모가 쬐끔 커지고, 기존 프로젝트를 유지보수를 해보면 얼마나 좋은지 몸소 뼈져리게 느끼게 된다.

Model 2의 기능을 정형화해서 쉽게 구현하게 해주는 것이 MVC Framework들의 역할이다.
가장 유명한 Model 2 웹 프레임워크들은 다음과 같은 것들이 있다.

* 스트럿츠 1 - Struts 1
* 스트럿츠 2 - Struts 2
* 스프링 MVC - Spring MVC
* 기타 덜 유명한 Wicket, Stripes, JSF, Tapestry 등.

Struts 1은 MVC의 효시라고 할 수 있다. 우리에게 MVC라는 축복을 주기는하였으나, 나온지 오래된 만큼 낡은 개념들이 많이 녹아있고 쓸데 없이 복잡하고 배우기도 어려운 편이다.

오히려 Struts 2와 Spring MVC가 더 배우기 쉬울 것이며, 개발도 더 쉽다. 현재 추세는 Struts 2와 Spring MVC이다. 대형 포탈이나 SI 업체들도 Spring/Struts 2를 주로 채택하는 추세로 가고 있는 것으로 알고 있다.

둘 중 하나의 개념만 확실히 이해해도 다른 것을 배우는데 어려움이 별로 없으므로 그냥 둘중에 골라서 배우길 권한다. 나는 Spring을 선호한다.

그리고 MVC 프레임워크를 사용하기 시작하면서 View를 만드는 JSP에 대해서도 재조명이 시작된다. 기존에 Java 코드를 JSP에 직접 넣던 관행을 버리고 JSTL과 태그 라이브러리를 사용하거나 아예 JSP를 버리고 다른 템플릿 엔진으로 만들기도 한다. 이에 관해서는 맨 마지막에.

4. 퍼시스턴스 프레임워크 : JDBC 반복 작업에 짜증이 나기 시작하다.
현대 웹 개발에서 가장 큰 역할을 차지하는 것은 뭐니뭐니해도 단연 Database 작업이다.
지금까지는 아마도 JDBC에서 DB 커넥션을 맺고, 쿼리를 날리고 그 결과 ResultSet을 JSP로 넘겨주어서 출력하는 식으로 했을 것이다.
이미 다들 알고 있겠지만 JDBC를 사용하면 똑같은 코드가 굉장히 많이 반복해서 나온다. 한마디로 "삽질"의 전형이 JDBC 작업이다.
이것을 깨달은 많은 개발자들이 조금 어정짱하게 반복작업을 해결해주는 Util 클래스들을 프로젝트별로 만들어서 사용하곤 한다.
하지만, 물론 이에 대해 정형화하고 깔끔하고 훨씬 더 사용하기 쉬게 만들려는 노력이 이미 수년에 걸쳐 이루어졌다.

이렇게 DB관련된 작업을 정형화한 것들을 Persistence Framework 라고 한다.

* 아이바티스 - iBATIS : SQL Mapper - JDBC보다 더 쉽게 배우고, 더 편하게 사용한다.
* 하이버네이트 - Hibernate : 객체지향을 객체지향답게, 개발 기간을 엄청나게 단축시켜주다.

퍼시스턴스 프레임워크의 양대 산맥은 iBATIS와 Hibernate이다. 이 둘 모두 우리나라에 책이 나와 있다.
iBATIS는 SQL Mapper의 한 종류이고, Hibernate는 ORM의 한 종류이다.

이 둘의 차이는 iBATIS는 개발자가 SQL 쿼리를 직접 작성한 것을 객체에 매핑시켜주는 것이고, ORM은 DB 스키마와 객체간의 관계를 설정파일로 만들면 자동으로 쿼리를 만들어주는 것이다.

자, 이 둘을 보면 미국에서는 Hibernate가 인기가 좋고, 우리나라에서는 iBATIS가 사실상 SI 업계를 평정했다.
그러니까, 일단은 우리나라에서는 iBATIS를 공부하면 된다고 보면 된다.

이렇게 말하니까 마치 이 둘이 경쟁자 같은데, 사실 이 둘은 경쟁 상대라기 보다는 보완해주는 역할을 한다. SI에서 처럼 DB 테이블이 정규화 되어 있지 않은 경우에는 Hibernate같은 ORM을 사용하면 프로젝트를 말아먹을 수 있다.

iBATIS는 테이블 정규화에 무관하게, 개발자가 작성한 SQL을 객체로 매핑하기 때문에 DB 스키마가 마구 꼬여 있는 상황에서도 유연하게 작동하고, 개발자가 직접 SQL 튜닝을 할 수 있다는 장점이다.

그리고 Hibernate는 배우기가 굉장히 어려운 프레임워크이고 튜닝이 매우 어렵다. Hibernate책을 보면 캐싱을 통해 성능을 향상시키라고 하지만 캐싱은 iBATIS도 못지않게 잘 지원한다. 하지만 일단 배우면, 그로인한 코딩 생산성이 iBATIS가 감히 넘볼 수 없을 정도록 급격히 향상된다.

Hibernate는 DB 정규화가 잘되어 있는 웹 포탈 업체나 패키지 소프트웨어 제작시에 강력히 권장할만 하다.

5. IoC와 DI - 객체의 생성주기와 의존성을 관리하고 싶어지다
사실 내가 경험한 SI를 보면 4단계 까지만 가도 막장은 아닌 프로젝트라고 본다. 아직도 신규 프로젝트를 하면서도 Model 1에 JDBC로 코딩하는 것을 많이 보았기 때문이다.

앞서, MVC라는 형태로 웹 애플리케이션의 역할을 철저하게 분할해서 처리하라고 했었다.

이제 여기서 좀 더 역할을 분할하기 시작한다.

Database를 관장하는 코드(DAO)와 Database 처리 결과를 가지고 그외 비지니스 로직을 추가로 수행하는 코드(Service), 그리고 웹으로 들어온 요청을 받아서 비지니스 로직을 호출하고, 그 결과를 다시 웹(HTML 등)으로 내보내는 코드(Controller)로 분할을 하면 유지보수가 더 쉽고, DB가 Oracle에서 DB2 로 변경되는 식의 중대 변화가 있을 때도 DAO만 바꾸면 되는 식으로 변화에 대한 대처가 유연해 진다는 것을 깨닫기 시작한다.

이제는 각 역할별로 클래스를 분할하고 컨트롤러 객체는 서비스 객체에 서비스 객체는 DAO 객체에 의존해서 작동하도록 코드를 바꾸기 시작한다. 그리고 객체의 생성과 파괴 주기도 관리해야만 하게 된다. 객체를 하나만 생성하면 되는데 불필요하게 매번 new를 할 필요는 없으니까.

이렇게 객체의 생성/파괴 주기를 관리하고 객체간의 의존성을 관리해주는 프레임워크를 IoC 컨테이너라고 부른다.

1. Spring Framework
2. EJB 3.0

사실상 대세는 Spring Framework로 굳어졌다. EJB 3.0은 내가 안써봐서 뭐라 말은 못하겠다.

Spring MVC는 이 Spring Framework의 일부분이다.

Spring은 또한 AOP도 지원한다.

AOP 의 개념이 상당히 어려운 편이라서 개념 자체를 확실히 한마디로는 표현하지 못하겠다. 어쨌든 개발자들에게 가장 쉽게 다가오는 표현으로 하자면, AOP는 동일한 패턴으로 반복적으로 해야하는 일을 설정을 통해 자동으로 해주는 것이다.
이에 관한 가장 보편적인 예가 바로 트랜잭션이다.
지금까지는 아마도 비지니스 로직이 시작될 때 트랜잭션이 시작되고, 비지니스 로직이 끝날 때 트랜잭션을 종료하는 코드를 매번 작성해서 넣었을 것이다.
AOP를 사용하면, 비지니스 로직의 역할을 하는 메소드가 무엇인지 설정파일에 넣어주기만 하면 자동으로 메소드가 시작될 때 트랜잭션을 시작시키고, 메소드가 끝날 때 트랜잭션을 종료시켜준다. 물론 예외가 발생하면 트랜잭션을 rollback도 해준다. 따라서 Spring을 사용한 프로젝트에서는 트랜잭션 관련 코드를 볼 수 없을 것이다.

Spring 프레임워크는 기본적으로 IoC 컨테이너 역할을 하는 것이 핵심이다. 따라서 Spring을 사용한다고 해서 꼭 Spring MVC를 사용할 필요는 없다. Struts 2 + Spring + iBATIS 나 SpringMVC + Spring + Hibernate 등... 어떠한 조합이라도 가능하다.

6. 그 외
◈ Template Engine : JSP 보다 더 간결하면서 강력한게 필요해!
   * JSP + JSTL : Sun이 지정한 산업표준이다. JSTL은 당연히 쓰고 있으리라 믿는다.
   * Freemarker : 가장 권장할 만하다.
   * Velocity : 굉장히 배우기 쉽다. JSTL보다 더 빨리 배워서 쓸 수 있다. 가독성도 좋다. 그러나 Freemarker 만큼 편하고 강력하지는 못하다.
많은 사람들이 Java 웹 개발을 그냥 "JSP 개발"이라고도 부르는데, MVC가 도입되고, Freemarker 같은 다른 템플릿 엔진을 사용하게 되면 더이상 JSP는 코빼기도 안보이게 된다. 그러므로.. JSP 개발이라는 말은 쓰지 않았으면 좋겠다.

◈ Layout Engine
   * Sitemesh : 헤더 푸터 처럼 동일 패턴이 반복되는 레이아웃을 관리해준다.

◈ XML 도우미 : W3C DOM은 너무 어렵고 난잡하다. 좀 더 편한 XML관련 개발을 원한다면..
   * JDOM : Java 표준으로 지정됐다고 한다.
   * DOM4J
둘 다 비슷하게 편한거 같다. 예전엔 JDOM을 썼었는데, 나 같은 경우 현재 프로젝트에서는 DOM4J를 사용한다. Hibernate가 DOM4J를 사용하기 때문에, 별도의 라이브러리 더 넣는게 귀찮아서.

◈ 단위 테스트
   * jUnit : 코드를 철저하게 테스트하자.

◈ 소스코드 버전관리
   * CVS
   * Subversion : 현재 대세는 Subversion
내가 최고 막장으로 꼽는 프로젝트는 아직도 FTP로 소스 관리하는 프로젝트이다. 이런 프로젝트에는 절대로 참여하지 않을 것이라고 굳게 맹세하고 또 맹세했다. --;
소스 코드 버전관리는 여러 개발자들이 동시에 개발할 때 소스코드를 저장하고 충돌을 관리해주며, 소스 변경 내역을 계속해서 추적해서 과거 소스로 언제든지 돌아갈 수 있도록 도와준다.
현재 대세는 Subversion이지만 CVS로도 버전관리의 이점을 충분히 만끽할 수 있다. 그리고.. 사실 CVS가 사용법을 익히기는 더 쉽다.

◈ 자동 빌드
   * Ant : Ant 면 만사 Ok!
   * Maven
아직도 javac 로 컴파일하고 있고, FTP로 파일 올려서 복사하고 있다면.. 이 모든일을 자동으로 명령 한방에 처리하도록 해야 실수도 적고, 퇴근도 일찍한다.
Ant로 빌드와 배포를 자동화 하자.

결론

내가 권하는 조합은
* SI 업체에서 일하는 경우 : Struts 2 혹은 SpringMVC + iBATIS + JSP/JSTL + 가능하다면 Spring Framework
* 웹 포털등과 같은 업계, 패키지 소프트웨어 제작 업체 : Struts 2 혹은 Spring MVC + Hibernate + Spring Framework + Freemarker + Sitemesh
:
Posted by 라면스프
2008. 11. 4. 21:56

[구버전] 하늘아리 for wow3.02 ver2 It's Me/와우2008. 11. 4. 21:56


출처 : http://wow.gamemeca.com/special/section/html_section/wow/hanulari/download/view.html?subcode=c1134&page=1&search_kind=&search_text=&id=74&gid=74&head=


 

하늘아리 for wow3.02 ver2

 

Change :

1. 블링크의 WhoLink 수정 - 이전 WhoLink와 같은 설정으로 동작하도록 수정

2. 마법경고 기본값 변경 : 자기 자신이 전투시에 대상의 마법만 경고하도록 조정

3. 툴팁 마우스 오버시 게임 기본값 사용하도록 변경

4. 공격대 애드온(그리드, 빅윅) 추가

5. 직업별 애드온 추가

    - 도적, 흑마법사, 성기사 추가

    - 상바, 토템바를 각각 사냥꾼, 주술사로 재분류

6. 내구도, 소지금 표시 재추가(StatsMod2)

7. 마카룬 프로필 재수정

   - 프로필 불러올 시 편집모드가 켜져 있는 문제 수정

8. 통합형 원백 가방애드온(Combucter) 추가

 

설치시 주의사항

- 직업별 애드온과 원백가방 애드온은 기본적으로 설치체크가 되어 있지 않습니다.

   자신에게 맞는 직업을 체크하시고 설치하세요.

- 3.02용 하늘아리 부터는 설치시 무조건 기존 Addon 폴더와 WTF폴더를 다른 이름으로 수정 백업후
   설치됩니다. 기존 설정을 사용하시려면 백업된 WTF를 다시 WTF로 바꾸신 후 사용하시면 됩니다.

- 첫 설치시 에러가 발생할 수 있습니다. 이럴 때는 와우 클라이언트를 재시작 또는 UI 재시작을 하시면 
  해당 에러는 더이상 발생하지 않습니다.

 

 

마카룬! 바 (센터바 및 팝바) 사용시 주의사항

 

- 반드시 마법창의 스킬 또는 인벤토리의 아이템만 올려놓으시기 바랍니다.
  매크로를 만든 것을 그대로 올려놓으시면 기본 액션바와 연동되어버리는 현상이 있습니다.

- 매크로를 사용하시려면 "버튼 편집모드"에서 직접 버튼에 매크로를 적어서 사용하세요  


:
Posted by 라면스프
2008. 11. 1. 18:02

냉비법사 특성 트리 [66렙] It's Me/와우2008. 11. 1. 18:02

 비전(7 포인트)
  신비한 미묘함 - 2/2 포인트
자신의 주문이 무효화될 확률이 30%만큼 감소하고 비전 주문으로 발생되는 위협 수준이 40%만큼 감소합니다.

신비한 안정성 - 3/5 포인트
신비한 화살과 비전 작렬 시전 시 60%의 확률로 피해를 입어도 마법 시전 방해를 받지 않습니다.

마법 흡수 - 2/2 포인트
모든 마법 저항력이 레벨당 1.0만큼 증가하고 주문을 완전히 저항할 때마다 전체 마나의 2%에 달하는 마나를 회복합니다. 1초마다 1번씩만 발동됩니다.

 
 
ㆍ 화염(0 포인트)
  아직 배우지 않았습니다. 
 
ㆍ 냉기(50 포인트)
  동상 - 3/3 포인트
15%의 확률로 빙결 효과에 걸린 적을 5초 동안 움직이지 못하도록 만듭니다.

얼음 화살 연마 - 5/5 포인트
얼음 화살의 시전 시간이 0.5초만큼 단축됩니다.

얼음 파편 - 3/3 포인트
냉기 주문이 치명타로 적중할 경우 보너스 피해가 100%만큼 증가합니다.

원소의 정밀함 - 3/3 포인트
냉기 및 화염 주문의 적중률이 3%만큼 증가하고 주문의 마나 소비량이 같은 비율로 감소합니다.

얼음 핏줄 - 1/1 포인트
기본 마나의 3%
즉시 시전
3분 후 재사용 가능
주문 시전을 빠르게 하여, 주문 시전 가속도를 20%만큼 증가시키고 시전 중 피해를 입어도 100%의 확률로 마법 시전 방해를 받지 않습니다. 20초 동안 지속됩니다.

사무치는 냉기 - 3/3 포인트
냉기 주문의 공격력이 6%만큼 증가합니다.

산산조각 - 3/3 포인트
얼어붙은 적을 주문으로 공격했을 때 극대화 효과를 발휘할 확률이 50%만큼 증가합니다.

혹한의 손길 - 2/2 포인트
얼음 화살, 얼음창, 동결, 눈보라의 사정거리와 얼음 회오리, 냉기 돌풍의 범위가 20%만큼 증가합니다.

냉기계 정신집중 - 3/3 포인트
모든 마법을 시전하는 데 필요한 마나가 10%만큼 감소하고 냉기 주문으로 발생하는 위협 수준이 10%만큼 감소합니다.

매서운 한파 - 1/1 포인트
즉시 시전
8분 후 재사용 가능
최근 사용한 모든 냉기 주문의 재사용 대기시간을 초기화시켜 바로 사용할 수 있도록 합니다.

혹한의 추위 - 2/3 포인트
냉기 공격 주문 사용 시 66%의 확률로 혹한의 추위 효과를 얻게 됩니다. 효과가 활성화되어있는 15초동안 주문이 극대화 효과를 발휘할 확률이 2%만큼 증가합니다. 5번까지 중복됩니다.

얼음 한기 - 1/2 포인트
매서운 한파, 얼음 보호막, 동결, 물의 정령 소환 주문의 재사용 대기시간이 10%만큼 감소합니다.

얼음 보호막 - 1/1 포인트
기본 마나의 25%
즉시 시전
30초 후 재사용 가능
자신 주위에 즉시 보호막을 생성하여 454의 피해를 흡수합니다. 1분 동안 지속됩니다. 보호막이 지속되는 동안은 마법이 취소되지 않습니다.

부서지는 보호막 - 2/2 포인트
얼음 보호막이 파괴되면 100%의 확률로 10미터 반경 내에 있는 모든 적들을 8초동안 얼어붙게 합니다.

북극의 바람 - 5/5 포인트
냉기 공격으로 입히는 피해가 5%만큼 증가하고 근접 및 원거리 공격에 적중 당할 확률이 5%만큼 감소합니다.

얼음 화살 강화 - 2/2 포인트
얼음 화살 주문의 피해가 주문력의 10%만큼 증가하고 치명타 적중률이 추가로 4%만큼 증가합니다.

서리의 손가락 - 2/2 포인트
적에게 빙결 효과를 입혔을 때 15%의 확률로 서리의 손가락효과를 얻습니다. 겨울의 손아귀 효과는 다음에 시전되는 두 개의 주문이 대상을 얼어붙은 상태로 취급하게 합니다. 15초동안 지속됩니다.

물의 정령 소환 - 1/1 포인트
기본 마나의 16%
즉시 시전
3분 후 재사용 가능
45초 동안 시전자의 명령을 따르는 물의 정령을 소환합니다.

두뇌 빙결 - 1/3 포인트
냉기 주문 시전 시 5%의 확률로 다음 화염구 주문은 마나를 소비하지 않고 즉시 시전됩니다.

물의 정령 연마 - 1/3 포인트
소환된 물의 정령이 머무는 시간이 5초만큼 증가하고 매 5초마다 100미터 범위 내의 파티원 혹은 공격대원의 마나를 전체 마나의 0.2%만큼 회복시킵니다.

사무치는 한기 - 5/5 포인트
얼음 화살, 얼음불꽃 화살 및 얼음창의 공격력이 5%만큼 증가하고 빙결 효과에 걸린 대상의 이동 속도를 추가로 10%만큼 감소시킵니다.

:
Posted by 라면스프

출처 : http://rothmans.wordpress.com/category/java


기본적인 코딩 표준

1.클래스명
  : 첫문자는 대문자로 시작하고, 구분되는 부분도 대문자로 시작한다.

2.메소드명
:첫문자는 소문자로 시작하고, 구분은 대문자로 짓는다.메소드명에는 대조할 수 있는
  이름을 붙인다.

3.섀도우 필드는 작성하지 않는다.
  :섀도우 필드, 즉 부모 클래스의 필드명과 동일한 필드명은 버그의 원인이 되므로,
   가능한 한 사용하지 않는다. 언어의 사양에 따라 컴파일러는 통과할 수 있다.

4.외부 리소스는 반드시 해제한다.
  :파일 입출력(I/O)과 데이터베이스의 커넥션,커서는 확실하게 close메소드를 실행하지
   않으면 자원이 해제되지 않는다. 반드시 finally에서 close 메소드를 실행하도록 한다.

ex) Connection = con =null;
     try
     {
     //처리
     }
     finally
     {
      if(con !=null)
      {
        con.close();
      }
     }

5.catch한 예외는 반드시 처리한다.
  :catch한 예외에 대해 아무런 대처도 하지 않으면 디버그를 곤란하게 만든다. 반드시 로그
   출력을 하거나 throw한다. 이유가 있어서 무시하게 될 경우는 무시하는 이유을 주석으로
   붙인다.







Java 성능개선을 위한 Programming 기법

JDK1.3버전 이후로 지원되는 HotSpot VM은 기본적으로 Hip에 동적으로 할당된 Object는 거의 회수할 수 있다고 한다. 하지만 이 기능으로 인해서 VM은 엄청난 OverHead를 가지게 된다. 무리한 Object의 생성은 생성 당시에도 많은 OverHead를 초래하지만, 생성된 Object를 회수하기 위해서는 더 많은 작업이 요구된다. 이를 해결하기 위한 몇 가지 Tip이 있는데, Avoiding Garbage Collection, Object 재사용, static instance variable의 사용에 의한 단일 클래스 인스턴스 구현 방법 등이 그것이다. 핵심은 가능한 Object 생성을 피하자는 것이다.

▶ Avoiding Garbage Collection(static method사용)
예제1)
String string=”55″;
int theInt=new Integer(string).intValue();

예제2)
String string=”55″;
int theInt=Integer.parseInt(string);

예제1)에서는 Integer 클래스를 생성한 다음 string에서 정수값을 추출해 냈다. Object를 생성하고 초기화하는 과정은 상당한 cpu 집약적인 작업이고, Hip 영역에 Object가 생성되고 수집되기 때문에 가비지 컬렉터 작업을 수반한다. 가능한 Object의 Instance가 필요 없는 static 메소드를 사용한다. 예제2) 참조.

▶ Avoiding Garbage Collection(임시 Object 생성 금지)
가장 흔한 예로 String Object의 append를 위해서 (+) 연산을 사용하는 것을 들 수 있다. (+) 연산자를 사용해서 String Object를 append할 경우 우리가 생각하는 것 보다 훨씬 더 많은 임시 Object가 생성되고, 가비지 컬렉터에 의해 다시 수집된다. String Object의 append연산을 위해서는 StringBuffer 클래스를 사용한다. 예제1)과 예제2) 참조

예제1)
String a=”Hello”;
a=a+”World”;
System.out.println(a);

예제2)
StringBuffer a=new StringBuffer();
a.append(”Hello”);
a.append(”World”);
System.out.println(a.toString());

어떤 메소드는 Object의 복사본을 반환하는 경우가 있다. 대표적인 예로 스트링 클래스의 trim() 메소드를 들 수 있다. trim()메소드가 수행되면 기존의 Object는 수집되고, 기존 Object의 복사본이 사용되게 된다. 임시 Object 생성과 복사본을 반환하는 메소드가 루프 안에서 사용될 경우 무수히 많은 Object가 생성되고 수집되기 때문에 심각한 문제를 야기하게 된다. 루프 내부에서 Object를 생성하는 것은 가급적 피해야 한다.

예제3)
for(i=0;i<1000;i++){
Date a=new Date();
:
}

예제4)
Date a;
for(i=0;i<1000;i++){
a=new Date();
:
a=null;
}

예제3)과 예제4)는 현재 날짜와 시간을 얻어오기 위해 루프 안에서 Object를 생성했다. 보통 set으로 시작하는 메소드는 Object의 Instance 값을 재정의 한다. API를 충분히 참조한 다음 지원 메소드가 없을 경우, 클래스를 상속받아 요구에 적합한 메소드를 만드는 방법도 고려할 필요가 있다. 기존 API를 이용한 Object 초기화 방법은 아래 Object 재사용(메소드를 사용한 Object 초기화) 부분 참조.

▶ Avoiding Garbage Collection(primitive data type 사용)
Date 클래스나 String 클래스의 값들중 int나 long 형으로 표현하여 사용할 수 있는 경우가 있다. 예를 들어

String a=”1492″;
String b=”1997″;

과 같을 경우 a와 b는 굳이 String 형으로 표현하지 않아도 된다. 하지만 여기서 주의할 점은 Object의 값을 기본 데이타형으로 Casting 하는 작업이 오히려 시간이 더 많이 걸릴 수도 있는 것이다.
클래스의 인스턴스 변수로 기본 데이타형을 사용하면 Object의 크기도 줄어들고, Object 생성 시간도 줄일 수 있다.

▶ Object 재사용(Pool Management)
Object 재사용 기법으로 흔히 Pool Management 기법을 사용한다. 이는 임의 갯수의 Object를 미리 생성해 두고 이를 Vector 클래스를 사용해서 관리하는 방법이다. 해당 Object를 사용하기 위해서 Pool의 Vector에 있는 Object를 하나 가져오고, 다 사용하고 나면 다시 Pool에 반납한다. 이는 기존에 공개되어 있는 Hans Bergsten의 Connection-Pool의 PoolManager클래스에서 사용되고 있다.(Professional JAVA Server Programming. 정보문화사. 2000.4.4. 제9장 연결풀링 부분 참조) Object Pool을 사용할 경우, 반환되는 Object가 초기화되어 반환되지 않을 경우 다음에 Pool에서 Object를 가져와서 사용하게 되면 문제를 야기할 수 있기 때문에 초기 클래스 Design시 꼼꼼하게 따져 봐야 한다.

▶ Object 재사용(메소드를 사용한 Object 초기화)
예제1)
StringBuffer sb=new StringBuffer();
sb.append(”Hello”);
out.println(sb.toString());
sb=null;
sb=new StringBuffer();
sb.append(”World”);
out.println(sb.toString());

예제1)과 같이 사용할 경우 하나의 인스턴스 변수를 사용하기는 하지만, 두 번의 초기화 과정을 거치게 된다.

예제2)
StringBuffer sb=new StringBuffer();
sb.append(”Hello”);
out.println(sb.toString());
sb.setLength(0);
sb.append(”World”);
out.println(sb.toString());

위와 같이 각 클래스에서 지원해 주는 메소드를 사용하여 Object를 재사용 할 수 있다.

▶ static instance variable의 사용에 의한 단일 클래스 인스턴스 구현
다음은 Hans Bergsten의 PoolManager 클래스 코드 중 일부다.

public class PoolManager{
static private PoolManager instance;
:
private PoolManager(){
init();
}
static synchronized public PoolManager getInstance(){
if (instance == null){
instance = new PoolManager();
}
:
return instance;
}
private void init(){
:
}

PoolManager형의 인스턴스가 static으로 선언되어 있다. getInstance() 메소드는 현재 생성되어 있는 PoolManager의 Object를 조사하고 만약 Object가 있으면 Object를 반환하고 없으면 생성자를 호출해서 PoolManager의 Object를 생성한 후 반환한다. 결국 JVM 내부에는 하나의 PoolManager Object가 존재하게 된다. 단일 클래스 인스턴스 기법을 사용할 경우 하나의 인스턴스를 사용하기 때문에 해당 인스턴스의 무결성 부분이 문제가 된다. 이를 위해 다양한 Synchronization 기법을 사용하게 된다. 아래 I/O 퍼포먼스 개선 부분 참조.

▶ clone() 메소드 사용으로 Object 생성에 따른 OverHead를 피함

private static int[] data = new int[2][2];
int[] someMethod(){
int[] a = (int[])this.data.clone();
return a;
}

대부분의 클래스들에는 clone() 메소드가 존재한다. clone() 메소드가 호출되면 Object의 복사본을 반환하는데, 대신 클래스의 생성자를 호출하지 않기 때문에 생성자 호출에 의한 OverHead를 피할 수 있다. clone() 메소드를 사용할 때의 trade-off 문제는 다음에 예제를 참조 할 것.

static int[] Ref_array1={1,2,3,4,5,6,7,8,9};
static int[][] Ref_array2={{1,2},{3,4},{5,6},{7,8}};

int[] array1={1,2,3,4,5,6,7,8,9}; //faster than cloning
int[] array1=(int[])Ref_array1.clone(); //slower than initializing

int[][] array2={{1,2},{3,4},{5,6},{7,8}}; //slower than cloning
int[][] array2=(int[][])Ref_array2.clone(); //faster than initializing

▶ Method Inline에 의한 method호출 감소
예제1)
public class InlineMe{
int counter=0;
public void method1(){
for(int i=0;i<1000;i++){
addCount();
System.out.println(”counter=”+counter);
}
public int addCount(){
counter=counter+1;
return counter;
}
public static void main(String args[]){
InlineMe im=new InlineMe();
im.method1();
}
}

예제1)에서 addCount() 메소드를 다음과 같이 수정하면

public void addCount(){
counter=counter+1;
}

위와 같이 수정할 경우 addCount() 메소드는 컴파일시 Inline 되어서 실제 메소드를 호출하지 않고 같은 결과를 반환한다. 즉 method1()이 실제 수행될 때는 다음과 같이 수행.

public void method1(){
for(int i=0;i<1000;i++){
counter=counter+1;
System.out.println(”counter=”+counter);
}

▶ 생성자 설계
예제1,2,3) 모두 같은 역할을 하는 생성자들로 구성되어 있다. 하지만 퍼포먼스 측면에서 보면 예제3)이 가장 효율적이다. 하지만 클래스를 설계 할 때 예제1)과 같이 해야 할 때도 있다. 클래스가 요구하는 조건에 따라 생성자의 설계방법이 다르겠지만, Object를 생성할 때 가능한 생성자를 적게 호출하는 방법을 사용하는 것이 퍼포먼스 면에서 좋다는 것은 당연한 일이다.

예제1)
예제2)
예제3)
class SlowFlow{
private int someX, someY;
SlowFlow(){
this(777);
}
SlowFlow(int x){
this(x,778);
}
SlowFlow(int x, int y)
someX=x;
someY=y;
}
}
class SlowFlow{
private int someX, someY;
SlowFlow(){
this(777,778);
}
SlowFlow(int x){
this(x,778);
}
SlowFlow(int x, int y)
someX=x;
someY=y;
}
}
class SlowFlow{
private int someX, someY;
SlowFlow(){
someX=777;
someY=778;
}
SlowFlow(int x){
someX=x;
someY=778;
}
SlowFlow(int x, int y)
someX=x;
someY=y;
}
}

▶ “extends” VS “implements”
예제1) extends
import java.awt.event.*;
import java.awt.*;
public class MyWindowAdapter extends WindowAdapter{
public void windowClosing(WindowEvent we){
Container source=(Container)we.getSource();
source.setVisible(false);
}
}

예제2) implements
import java.awt.event.*;
import java.awt.*;
public class MyWindowListener implements WindowListener{
public void windowClosing(WindowEvent we){
Container sourve=(Container)we.getSource();
source.setVisible(false);
}
public void windowClosed(WindowEvent we){}
pubic void windowActivated(WindowEvent we){}
public void windowDeactivated(WindowEvent we){}
public void windowIconified(WindowEvent we){}
public void windowDeiconified(WindowEvent we){}
public void windowOpened(WindowEvent we){}

“implements”의 경우에는 특정 메소드를 구현하고 인터페이스에 정의된 모든 메소드를 코딩해야 하기 때문에 코드의 낭비를 초래하는 반면, “extends”의 경우에는 슈퍼 클래스에 정의된 메소드들 중 필요한 메소드만 overriding 하면 된다. ==> 설계 시 추상클래스를 사용할 것인지 인터페이스를 사용할 것인지 고려.

▶ 클래스 집약
예제1)
public class Person{
private Name name;
private Address address;
}
class Name{
private String firstName;
private String lastName;
private String[] otherNames;
}
class Address{
private int houseNumber;
private String houseName;
private String streetName;
private String town;
private String area;
private String greaterArea;
private String country;
private String postCode;
}

예제1)에서 정의된 Person 클래스는 Name형의 name과 Address형의 address, 두 개의 인스턴스 변수를 가진다. 클래스를 설계할 때 가능한 클래스의 수를 줄여서 수행 시 동적으로 생성되는 Object의 수를 줄일 수도 있다. 예제1)에서 정의된 세 개의 클래스는 하나의 클래스로 집약될 수 있다.

예제2)
public class Person{
private String firstName;
private String lastName;
private String[] otherNames;
private int houseNumber;
private String houseName;
private String streetName;
private String town;
private String area;
private String greaterArea;
private String country;
private String postCode;
}

▶ I/O 퍼포먼스 개선
자바에서는 자료를 읽거나 쓰기 위해 stream을 사용한다. 자바는 두가지 형태의 stream을 지원한다. Readers and Writers와 Input and Output stream이 그것이다. Reader and Writers는 high-level의 I/O(예. String)를 지원하고 Input and Output stream은 low-level의 I/O(byte)를 지원한다. 속도 향상을 위해서는 Buffered stream을 사용한다. Buffered stream을 사용할 경우 버퍼의 기본값은 2K이다. 이 값은 조정될 수 있으나, 자료의 용량이 클 경우 메모리가 많이 필요하기 때문에 Buffered stream을 사용할 경우 여러 가지 사항을 고려해야 한다.

예제1) Simple file copy
public static void copy(String from, String to) throws IOException{
InputStream in=null;
OutputStream out=null;
try{
in=new FileInputStream(from);
out=new FileOutputStream(to);
while(true){
int data=in.read();
if(data==-1)
break;
out.write(data);
}
in.close();
out.close();
}finally{
if(in!=null){in.close();}
if(out!=null){out.close();}
}
}

Buffered stream을 사용하지 않고 I/O를 했을 경우의 예제이다. 370K의 JPEG 파일을 복사하는데 10800ms.

예제2) Faster file copy
public static void copy(String from, String to) throws IOException{
InputStream in=null;
OutputStream out=null;
try{
in=new BufferedInputStream(new FileInputStream(from));
out=new BufferedOutputStream(new FileOutputStream(to));
while(true){
int data=in.read();
if(data==-1)
break;
out.write(data);
}
}finally{
if(in!=null){in.close();}
if(out!=null){out.close();}
}
}

Bufferd stream을 사용해서 퍼포먼스를 개선한 예제이다. 예제1)과 같은 파일을 복사하는데 130ms.

예제3) Custom buffered copy
public static void copy(String from, String to) throws IOException{
InputStream in=null;
OutputStream out=null;
try{
in=new FileInputStream(from);
out=new FileOutputStream(to);
int length=in.available();
byte[] bytes=new byte[length];
in.read(bytes);
out.write(bytes);
}finally{
if(in!=null){in.close();}
if(out!=null){out.close();}
}
}

while루프를 사용하지 않고 배열을 사용함으로서 퍼포먼스를 개선한 예제이다. 예제1)과 같은 파일을 복사하는데 33ms. 하지만 예제3)은 byte배열로 선언되는 메모리 버퍼의 크기가 실제 파일의 크기와 동일해야 한다. 이에 따라 두 가지의 문제점이 발생할 수 있다. 첫 번째는 파일의 용량이 클 경우 상당한 메모리 낭비를 초래한다는 점이다. 두 번째 문제점은 copy()메소드가 수행될 때마다 new byte[]에 의해 버퍼가 새로 만들어진다는 점이다. 만일 파일의 용량이 클 경우 버퍼가 만들어지고 Garbage Collector에 의해 수집될 때 상당한 OverHead를 초래할 수 있다.

예제4) Improved custom buffered copy
static final int BUFF_SIZE=100000;
static fianl byte[] buffer=new byte[BUFF_SIZE];
public static void copy(String from, String to) throws IOException{
InputStream in=null;
OutputStream out=null;
try{
in=new FileInputStream(from);
out=new FileOutputStream(to);
while(true){
synchronized(buffer){
int amountRead=in.read(buffer);
if(amountRead==-1)
break;
out.write(buffer,0,amountRead);
}
}finally{
if(in!=null){in.close();}
if(out!=null){out.close();}
}
}

크기가 100K인 byte 배열을 임시버퍼로 지정하고, 이를 static으로 선언함으로서 퍼포먼스를 개선했다. 예제1)과 같은 파일을 복사하는데 22ms. static buffer의 사용으로 I/O작업을 수행할 경우 발생할 수 있는 문제점을 해결하기 위해 synchronized block을 사용했다. 비록 synchronization을 사용함에 따라 성능 저하를 초래하지만, 실제 while 루프에 머무는 시간이 극히 짧기 때문에 퍼포먼스에 문제는 없다. 테스트에 의하면 synchronized 버전과 unsynchronized 버전 모두 같은 시간에 수행을 완료했다.

▶ 웹 환경에서 Caching을 이용한 자바 퍼포먼스 개선
웹 환경에서 Object caching 기법은 주로 DB나 파일에서 동일한 내용을 가져오는 루틴에서 사용된다. DBMS에 sql문을 던지고 결과를 받아오는 부분의 내용이 거의 변동이 없을 경우 요청 시마다 매번 sql문을 실행시켜서 결과를 받아오는 것이 아니라 최초 실행된 값을 그대로 반환하는 기법이다. 그리고 시간 Check 기법을 이용해서 특정 시간 경과 후 요청이 들어오면 이전 요청에 의해 수행되어진 값을 갱신해서 반환한다. 결과에 의한 반환값이 메모리에 부담이 되지 않을 정도로 크지 않은 경우, 실시간으로 변경된 정보를 반환값으로 사용하는 루틴이 아닐 경우 유용하게 사용될 수 있다.

▶ Performance CheckList
. 임시로 사용하기 위해 Object를 생성하는 것을 피하라. 특히 Loop에서..
. 빈번하게 호출되는 메소드에서 Object를 생성하는 것을 피하라.
. 가능한 Object를 재사용 하라.
. 임시 Object의 생성을 줄이기 위해 데이타 타입 컨버전 메소드를 재정의 하는 방법을 고 려하라.
. 메소드 설계 시 데이타를 유지하고 있는 Object를 반환하는 메소드보다 데이타로 채워진 재사용 가능한 Object에 접근하는 메소드를 정의하라.
. string이나 Object를 integer 로 대치하라. Object 비교를 위해 equal() 메소드를 호출하지 말고 기본 데이타 타입의 == 연산자를 사용하라.
. 인스턴스 변수로 기본 데이타 타입을 사용하라.
. 단지 메소드 호출을 위해 Object를 생성하는 것을 피하라.
. String 연속 연산자 (+)를 사용하는 것보다 StringBuffer 클래스를 사용하라.
. 복사본을 생성하는 메소드 보다 Object를 직접 수정하는 메소드를 사용하라.
. 생성자는 간단하게… 상속 계층은 얕게…
. 인스턴스 변수를 초기화 하는 것은 한 번 이상 하지 말 것.
. 생성자 호출을 피하기 위해 clone() 메소들 사용할 것.
. 간단한 배열일 경우에는 초기화를.. 복잡한 배열일 경우에는 clone() 메소드 호출.
. 프로그램 내부에서 Object 생성 시기를 조절해서 Object 생성에 따른 bottlenecks를 없앤 다.
. 어플리케이션 내부에서 여분의 시간이 허용된다면 가능한 Object를 빨리 생성하라. 생성 된 Object를 내부적으로 유지하고 있다가 요청이 발생하면 할당하라.
. 사용 가능성이 희박하거나, 분산처리에 의해 Object를 생성할 경우 Object는 생성 시기를 늦춰라.

:
Posted by 라면스프
2008. 10. 28. 17:37

[JSP] JSP 자주쓰는 코드 정리 Enjoy/JSP2008. 10. 28. 17:37


출처 : http://blog.naver.com/korekiss/20044092634


<%
response.sendRedirect("링크주소"); // 주소로 이동
str.length(); //글자길이 갯수 구하기
str.substring(3,7); //글자의 3에서 7번째까지 추출
str.append("문자열"); //str의 문자열에 추가

▷JSP 액션태그

 <jsp:forward>       다른페이지로 이동
 <jsp:include>       다른페이지를 페이지 안에 추가                                               <jsp:include page="url" flush="true" />
 <jsp:parma>         forward, include, plugin과 같이 사용되어 인자를 추가할때
 <jsp:plugin>         애플릿과 같이 클라이언트에서 사용되는 객체 삽입
 <jsp:useBean>     자바빈즈 사용
 <jsp:setProperty>  자바빈즈 프로피티의 값을 설정할때
 <jsp:getProperty>  자바빈즈 프로피티의 값을 얻는데 사용

 

▷토큰자르기 (java.util.*)
 String tel = "055-1234-5678";
 StringTokenizer str = new StringTokenizer(tel, "-");
 str.nextToken()  //055
 str.nextToken()  //1234
 str.nextToken()  //5678

 

▷파일 (java.io.*)
 -파일생성
 String filename = "c:\\aaaaa\\bbbbb\\test.txt";  //리눅스일때 http://mediafile.paran.com/MEDIA_11888685/BLOG/200711/1195526717_
 File f = new File(filename);  //파일클래스 작성
 f.createNewFile();  //파일 생성

 -파일쓰기
FileWriter fw = new FileWriter(filename);  //객체생성
 String data = "ㅇㅇㅇㅇㅇㅇㅇ";
 fw.write(data);  //파일쓰기
 fw.close();  //파일저장

-파일읽기
 FileReader fr = new FileReader(filename);  //리더객체생성
 BufferedReader br = new BufferedReader(fr);  //버퍼리더객체생성 - readLine();
 String line;
 while((line=br.readLine()) != null){
    out.println(line + "<br>");  //여러줄 읽어오기
 }

 -파일정보보기
 f.getAbsolutePath();  //절대경로
 f.getName();  //파일이름
 f.getParent(); //파일위치한 경로
 f.length();  //파일크기

 -파일삭제
 if(f.exists()){  //파일이 존재하면
    f.delete();
    out.println("파일이 삭제되었습니다.");
 }else{
    out.println("파일이 없습니다.");
 }

 

▷형변환
 String -> int
 String a="15";
 int b = Integer.parseInt(a);

 
 int -> String
 int a=12;
 Integer  b=new Integer(a);  //Integer객체 선언
 String c = B.toString();  //toString() 형변환
 

▷세션
 if(session.getAttribute("sid")==null){  //세션값이 아무것도 없을때
   out.println("세션 정보가 없습니다.");
   session.setAttribute("sid", session.getId());  //임의의 세션id를 sid에 저장
   session.setAttribute("name", "이름");  //이름을 name세션에 저장
 }else{
   out.println("이브라우저에 대한 세션 ID는 " + session.getAttribute("sid")+ "입니다.");
   out.println("name에 저장된 값은 " + session.getAttribute("name") + "입니다.");
 }
 session.setMaxInactiveInterval(3600);  //세션 유지시간 (1시간동안)

▷쿠키
 -저장
 Cookie cook1 = new Cookie("name", "aaa");  //쿠키객체생성
 cook1.setPath="/";  //쿠키가 적용될 웹서버의 url 경로
 cook1.setMaxAge(60*60*24*365); //쿠키가 유지되는 시간(1년) -1일경우 삭제하지 않는한 영구
 response.addCookie(cook1);  //쿠키를 클라이언트에 세팅

 Cookie cook2 = new Cookie("mail", aaa@aaa.com);
 cook2.setPath="/";
 cook2.setMaxAge(60*60*24*356);
 response.addCookie(cook2);


 -가져오기
 try(
  Cookie[] cookies = request.getCookies();
   for(int i = 0; i < cookies.length; i++){
     out.println(cookies[i].getName() + "은" + cookies[i].getValue() + "입니다.
   }
 }catch (Exception e){
   out.println(e);
 }

 -삭제하기
 try{
   Cookie[] cookies = request.getCookies();
   for(int i=0; i< cookies.length; i++){
     Cookie cook = cookies[i];
     cook.setMaxAge(0);
     response.addCookie(cook);
   }
   out.println("쿠키가 삭제되었습니다.");
 }catch(Exception e){
   out.println(e);
 }

 

▷JDBC드라이브
 Class.forName("org.gjt.mm.mysql.Driver");
 -mysql
 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "test", "pass");  //연결객체생성
 Statement stmt = conn.createStatement();  //스테이트먼트 객체생성
 ResultSet rs = stmt.executeUpdate("insert into test(id, age) values('aaa','123')");  //쿼리문실행
 rs.next();  //다음 리절트 셋

:
Posted by 라면스프
2008. 10. 28. 17:34

[JAVA] Shell Script 팁 (Unix포함) Enjoy/JAVA2008. 10. 28. 17:34


출처 : http://blog.naver.com/vital45/110024999490


1. 스크립트를 생성할때 구조화를 염두에 둔다
- Unix에서 보통 파일 구조가
/bin
/var/log
등등의 형식을 따르고 있기 때문에 가독성을 높이고 직관적으로 알아볼수 있게 하기 위해 생성

2. find  $PATH -type f | grep -v ".svn"
- .svn이 포함된 디렉토리는 무시하고 file을 검색

3. find . -name "*.sh" | xargs grep "STRING"
- *.sh 의 파일 중 내용에 STRING이 포함되어 있는 곳을 stdout으로 출력

4. 제어권을 갖고 있는 곳은 한군데로 통일하고, 나머지 스크립트는 모든 인자를 받아서
각각의 행동을 하도록 한다.

5. 로그 이름은 script이름과 되도록 통일하여 가독성을 높이도록 한다.

6. wget --output-file=/DIRECTORY/output.log --spider http://localhost:8080/
- wget: 지정된 경로에서 파일 다운로드
- --output-file : 로그 메세지를 지정된 파일에 저장
- --spider: 파일 다운로드 받지 않음

7. shell에서 덧셈 시
- loopcount=0
- loopcount=`expr $loopcount + 1`
- 중요한건 expr 문장을 감싼것은 `(tild)라는 것. 물론 syntax에서 구별할수 있겠지만...

8. svn checkout REPO_PATH PATH
- checkout 명령은 PATH에 없으면 REPO_PATH에서 내려받고, 이미 PATH가 존재하면 update를 한다.
- checkout, update 명령을 굳이 구별할 필요가 없음.

9. shell 스크립트 호출 후 표준출력을 웹 화면에서 보여주는 방법 (jdk 1.5)
(1) jsp 에서
cmd = "ssh";
url = id@server;
args = "A B C";

ProcessBuilder process = ProcessBuilder.start(cmd, url, args);
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);

while ((line = br.readLine()) != null)
   System.out.println(line);

(2) java에서
cmd = "ssh";
url = id@server;
args = "A B C";

ProcessBuilder process = ProcessBuilder.start(cmd, url, args);
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);

while ((line = br.readLine()) != null) {
   // newLine 가공 부분은 따로 처리하는게 있는걸로 알고있는데..
  // 나중에 한번 찾아봐야 할듯. 아래는 예상 코드
   String contents = line + "\n";
}

contents를 jstl을 이용하여 뿌려주는 식으로...

10. Subversion에서의 tag
- SVN Repository를 구성할때 아래와 같은 구조를 권장하고 있다.
repository/trunk : 현재 작업본
repository/branches : 테스트 버전이랄까? (beta버전)
repository/tags : 잠금 버전 (완성본)

TotoiseSVN에서 branches/tags를 클릭하면 실제로 수행하는 명령어는 svn copy다.
svn copy는 Working Copy(이하 WC) 와 Repository PATH(이하 URL)에서 실행할 수 있다. (조합 4가지)
svn copy -m "Message" [WC|URL] [WC|URL]

참고: svn switch 를 실행하면 현재 경로에서부터는 svn repository path를 변경한다.
.svn/entries 의 주소를 확인해보면 알 수 있다.
더 확장하면 svn propset을 이용한 external link를 하는 법도 있는데.. 이건 정확히 잘 모르겠음.

11. argument를 delimeter로 잘라서 loop 돌리는 법
INPUT=$1
DELIM=":" # Delimiter

for part in `echo $input | sed "s/$DELIM/ /g"`
do
   echo $part
done
- sed명령어를 묶어준 것도 역시 `(tild) 이다.

12. ls 에 대한 새삼 깨달은 팁
- ls | grep $option1 | grep $option2
grep 을 줘서 각 인자에 대한 리스트를 뽑아올 수 있다.

 

:
Posted by 라면스프
2008. 10. 28. 17:13

[JSP] HttpSessionBindingListener Enjoy/JSP2008. 10. 28. 17:13


출처 : http://blog.naver.com/korekiss/20038228350


HttpSessionBindingListener 는 웹에서 동시 사용자의 수 또는 하나의 아이디로 동시접속을 제한 할때 유용한 인터페이스 이다.  HttpSessionBindingListener 는 두개의 메소드를 지니는데 valueBound() 와 valueUnbound() 메소드 이다.
 
valueBound() 는 HttpSessionBindingListener 클래스의 인스턴스가 세션에 attribute로
등록될떄 호출된다  session.setAttribute(플래그, 값)
valueUnbound()는 session.removeAttribute(플래그); 사용시
또는 세션종료시  session.invalidate()호출된다.
 
다음은 이를 이용한 동시 사용자및 중복 로그인 방지 프로그램이다.
 
 
LoginManager.java
 
package cookie;
 
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionBindingEvent;
import java.util.Hashtable;
import java.util.Enumeration;
 
public class LoginManager implements HttpSessionBindingListener
{
             private static LoginManager loginManager = null;
             private static Hashtable loginUsers = new Hashtable();
             private LoginManager(){
                           super();
             }
             public static synchronized LoginManager getInstance(){
                           if(loginManager == null){
                                        loginManager = new LoginManager();
                           }
                           return loginManager;
             }
 
             //아이디가 맞는지 체크
             public boolean isValid(String userID, String userPW){
                           return true;   //자세한 로직은 미구현
             }
 
             //해당 세션에 이미 로그인 되있는지 체크
             public boolean isLogin(String sessionID){
                           boolean isLogin = false;
                           Enumeration e = loginUsers.keys();
                           String key = "";
                           while(e.hasMoreElements()){
                                        key = (String)e.nextElement();
                                        if(sessionID.equals(key)){
                                                     isLogin = true;
                                        }
                           }
                           return isLogin;
             }
 
             //중복 로그인 막기 위해 아이디 사용중인지 체크
             public boolean isUsing(String userID){
                           boolean isUsing = false;
                           Enumeration e = loginUsers.keys();
                           String key = "";
                           while(e.hasMoreElements()){
                                        key = (String)e.nextElement();
                                        if(userID.equals(loginUsers.get(key))){
                                                     isUsing = true;
                                        }
                           }
                           return isUsing;
             }
 
             //세션 생성
             public void setSession(HttpSession session, String userID){
                           loginUsers.put(session.getId(), userID);
                           session.setAttribute("login", this.getInstance());
             }
 
             //세션 성립될 때
             public void valueBound(HttpSessionBindingEvent event){
             }
 
             //세션 끊길때
             public void valueUnbound(HttpSessionBindingEvent event){
                           loginUsers.remove(event.getSession().getId());
             }
 
             //세션 ID로 로긴된 ID 구분
             public String getUserID(String sessionID){
                           return (String)loginUsers.get(sessionID);
             }
 
             //현재 접속자수
             public int getUserCount(){
                           return loginUsers.size();
             }
};
 
Bind_login.jsp
 
<%@ page contentType="text/html;charset=euc-kr"
             import="cookie.LoginManager"%>
 
<% LoginManager loginManager = LoginManager.getInstance(); %>
<html>
<body>
<center>
현재 접속자수 : <%= loginManager.getUserCount() %><p>
<hr>
<%
             if(loginManager.isLogin(session.getId())){  //세션 아이디가 로그인 중이면
                           out.println(loginManager.getUserID(session.getId())+"님 안녕하세요<br>"
                                                                  +"<a href=bind_logout.jsp>로그아웃</a>");
             }
             else{  //그렇지 않으면 로그인 할 수 있도록
%>
<form name="login" action="bind_login_ok.jsp">
아이디: <input type="text" name="userID"><br>
비밀번회: <input type="text" name="userPW"><br>
<input type="submit" value="로그인">
</form>
<%         }%>
</center>
</body>
</html>
 
Bind_login_ok.jsp
 
<%@ page contentType="text/html;charset=euc-kr"
             import="cookie.LoginManager"%>
 
<% LoginManager loginManager = LoginManager.getInstance(); %>
<%
             request.setCharacterEncoding("euc-kr");
            
             String userID = request.getParameter("userID");
             String userPW = request.getParameter("userPW");
 
             if(loginManager.isValid(userID, userPW)){
                           if(!loginManager.isUsing(userID)){
                                        loginManager.setSession(session, userID);
                                        response.sendRedirect("bind_login.jsp");
                           }
                           else{
                                        throw new Exception("이미 로그인중");
                           }
             }
             else{
                           throw new Exception("ID/PW 이상");
             }
%>
 
Bind_logout.jsp
 
<%@ page contentType="text/html;charset=euc-kr"%>
<%
             session.invalidate();
             response.sendRedirect("bind_login.jsp");
%>
 
:
Posted by 라면스프
2008. 10. 27. 14:43

Java Tips Enjoy/JAVA2008. 10. 27. 14:43


출처 : http://www.nsftools.com/tips/JavaTips.htm#searchfiles


Java Tips

Using Wildcard Expressions in Java
Getting a File from a Web Site or FTP Site
Java FTP Class
Java Server Addin for Domino
HttpEcho Program
Java HTTP Proxy
Java MessageBoxes, InputBoxes, and ProgressBars
XML NodeReader Class
Java Sample Code Database
Transform WSDL Servlet
Undocumented Base64 Java Classes
Using Java Reflection to Get Class Information
Multi-Part MIME Message Parser
Java RichTextOutputStream Class
Accessing the System Clipboard with Java
Searching for Text in Files
Manipulating JPEG Images
Testing ReplaceSubstring Routines
Terminating Threads and Reacting to Shutdown in Java
Open JAR Files Natively In Windows


Using Wildcard Expressions in Java
August 31, 2002 (updated September 11, 2002)

Here's a Java class that I wrote to evaluate basic wildcard expressions (using *, ?, or []) in Java strings. If you're using the JDK/J2SE 1.4 or higher, you should probably use the java.util.regex package to make Regular Expressions to provide string pattern-matching functionality, because it will give you a much greater range of functionality. There are (at the time of this writing) some good examples of Regular Expression usage here on the Sun website. However, sometimes we Notes developers are stuck using older versions of the JDK...

I also included a sample class called "jdir.java" that calls the PatternMatch class and uses it in a FilenameFilter, as an example. It simulates the very basic functionality of the "dir" command in DOS (make sure you enclose those wildcard arguments in quotes!).

PatternMatch.java
jdir.java

My good friend Mark (a fantastic Java programmer) also told me about an open source regular expression library at apache.org that will work with JDK versions prior to 1.4. That one should be much more full-featured than the one I wrote. Thanks Mark!


Getting a File from a Web Site or FTP Site
August 31, 2002

This is a Java class I wrote to get a file (or a web page) from a web site or an anonymous ftp site. It has additional functionality to allow you to do this kind of thing through a proxy server, which makes it a little more useful in an office setting.

InternetFile.java


Java FTP Class
August 31, 2002 (updated September 11, 2002)

This information has been expanded and moved to a separate page:
see JavaFtp.htm


Java Server Addin for Domino
October 14, 2002 (updated May 17, 2003)

Here's an example of how to write an R5 Domino Server Addin using Java (which is normally something you'd do in C or C++). I got the idea from this tip on the SearchDomino site. The example I wrote doesn't do much, but it should give you a good framework for writing your own Addins. I tried to be as liberal as possible with my comments.

Keep in mind that using the the lotus.notes.addins.JavaServerAddin class from Notes.jar is totally unsupported functionality (at least in R5), so you are using it at your own risk. Normal caveats apply. This also means that I had to make some educated guesses about some of the functionality that I describe in the source code, so please send me a note if you find any mistakes.

JavaAddinTest.java
JavaAddinTest.class


HttpEcho Program
November 21, 2002

This is a simple Java program that takes incoming HTTP requests on a given port and returns them right back to the sender of the request. It's useful for looking at the HTTP headers sent by your browser, or seeing the structure of SOAP requests that are being sent to a server. For example, just compile the Java file into a class file and run "java HttpEcho 8080", and then point your browser to "http://localhost:8080/whatever" to see your browser headers.

Actually, I wrote two slightly different versions of the program: HttpEcho.java, which is single-threaded, and HttpEchoMT.java, which is multi-threaded. That's just to give you an example of how to do some simple multi-threading on a program like this.

HttpEcho.java
HttpEchoMT.java


Java HTTP Proxy
December 18, 2002 (updated February 1, 2003)

This is a multi-threaded HTTP proxy server implementation in Java. Ideally you'll just run it on your local workstation so you can watch HTTP requests going back and forth (because of the way the threading works in this code, I wouldn't recommend running it as a proxy server that serves multiple clients -- see the comments in the code for more detail).

You can either point this proxy to a direct network/Internet connection, or you can point it to another proxy server (if that's how you're set up). Even though the jProxy class has a 'main' method that allows you to run it all by itself, I also tried to structure the methods in the class so you can easily call it from other classes. I didn't spend the time to javadoc any of the comments, but the code should be commented well enough that you can understand what's going on by reading through it. (Updated on Feb 1 so that the HTTP header elements are separated by \r\n instead of just \n, to comply with the official HTTP spec).

jProxy.java


Java MessageBoxes, InputBoxes, and ProgressBars
December 23, 2002 (updated January 15, 2002)

Here's a classic case of a simple little piece of functionality that ended up taking lines and lines of code to implement. All I wanted to do was add a MessageBox and an InputBox to a Java agent that would run in the Notes client, and I wanted to use the java.awt classes so I wouldn't have to package the javax.swing classes along with the agent (note that Swing was included with Lotus Notes starting with release 6, but I was stuck with R5 at the time). It wouldn't have been too bad, except for the fact that java.awt doesn't have a native way of displaying multiple lines of text in a Label-type component...

Since it wasn't quite as straightforward as I thought it would be, I packaged up some sample code, added comments to the source, and posted it for you here. It's a MessageBox class that allows you to present simple Ok/Cancel dialogs, input boxes, drop-down lists, and multiple selection lists. Also included as a special bonus is a MultiLineLabel class that you can use to create text labels of a fixed width that have multiple lines (with text wrapping, too!).

Of course, just because this is implemented as a Lotus Notes agent doesn't mean that you can't use it in your other Java applets/applications. If you do any kind of Java UI work without the Swing classes, this code will probably come in handy.

MsgBox.java

Update: Here's a similar piece of code that allows you to implement a non-modal Progress Bar in a Java agent. Like the MessageBox example above, the ProgressBar class uses only the java.awt classes, so you don't have to package anything special with your agents that use it.

ProgBar.java


XML NodeReader Class
January 17, 2003 (updated February 27, 2003)

The NodeReader class provides some basic functionality for stepping through the elements of a w3c XML Node, so you don't have to write your own loops around a NodeList. It's similar to the TreeWalker class that ships with many org.w3c.dom compatible packages, but the XML4j.jar package that ships with Lotus Notes/Domino doesn't have a TreeWalker class, so I wrote this.

This has been tested with the JDK 1.1.8 and 1.3.1, both in an R5 Notes agent and in a stand-alone Java application. It's also got JavaDoc comments, so you can produce some basic documentation (although I did include a code sample with the comments, so that should help you along).

NodeReader.java


Transform WSDL Servlet
February 19, 2003

I was playing around with WSDL files last week, and I ran across this article about transforming a WSDL file using XSLT. As I was reading it, I thought it would be interesting to write a servlet that would apply the XSL file in the article to any given WSDL file on the web. So I wrote one, and you can download it below.

It worked on my R5 Domino servers using the Domino Servlet Manager, and the method in the code that actually performs the XSL transformation could also be easily copied and pasted into a Notes agent (note that it may not work properly if your server is sitting behind a proxy server). If nothing else, this might be a good framework for how to write a simple servlet.

There's also some interesting information about transforming WSDL files using XSL on the CapeScience site.

TransformWSDL.java


Undocumented Base64 Java Classes
February 23, 2003

While I was poking around through my Java jar file, I discovered a couple of undocumented (i.e. not in the JavaDocs) classes in Sun's Java distribution called sun.misc.BASE64Encoder and sun.misc.BASE64Decoder. As expected, they Base64 encode and decode data, and they even have really convenient methods for encoding/decoding an InputStream to an OutputStream, which is handy for working with files (I used reflection to figure out what the public methods were).

As always, you should be a little cautious working with undocumented features, but I'd bet these are pretty safe (Base64 ain't rocket science). It could save you a little coding or the need to import extra classes into your project, and I even tested the functionality with an R5 Notes client, so I'd guess these classes have been around for a while (at least since the 1.1.8 JDK).

Here's some sample code that demonstrates example usage:

Base64Test.java


Using Java Reflection to Get Class Information
February 24, 2003

This is a simple example of how to use Java reflection to get information about a compiled Java class. This is useful for getting the public fields, constructors, and methods of a class that you may not have documentation for.

ReflectClass.java


Multi-Part MIME Message Parser
March 4, 2003

This is a class that will read and parse an RFC 1521 multi-part MIME message. It works with any InputStream, it's been tested with the 1.1.8 and 1.3.1 JDK, and it doesn't require any additional classes or overhead.

The code is pretty well commented (JavaDoc comments and everything), including a class usage example, so you should be able to figure out how to use it fairly quickly.

SimpleMimeReader.java


Accessing the System Clipboard with Java
May 6, 2003

This is a wrapper to the java.awt.datatransfer.Clipboard methods that allow you to copy and paste items to the system clipboard. Strings are handled natively, and other Object types can be used with a little programming of your own. The big reason to use this class is because it sets the java.awt process up in a daemon thread, which allows your program to terminate properly without a call to System.exit() -- see the JavaDoc comments in the code for more explanation.

ClipHelper.java


Searching for Text in Files
May 30, 2003

A while ago, I did some testing to find out how to search for a String in a file as quickly as possible. This may seem like a fairly rudimentary thing to do, but I was quite surprised at how much variance there was in the speed of many of the obvious solutions, especially when you started looking at large or multiple files. You can use different InputStreams and Readers, adopt different buffering strategies, and so on.

In the end, I found that it seemed to be faster to read a FileInputStream in chunks of 2048 bytes at a time, and compare a byte array representation of my String with the bytes of the file. Just for fun, I wrapped the file searching function (which is called searchFile) in a little Swing application that's pretty easy to use. There are also examples of how to perform some handy little tasks in Swing in there too (like responding to double-clicks and launching threads with your ActionListeners), so some of the other code might be useful to you as well.

(If you're lucky enough to be using Java 1.4 or higher, there's a nice example of how to grep a file using regular expressions and the new java.nio classes in the Sun api docs.)

SearchFiles.java


Manipulating JPEG Images
July 30, 2003

Here's a class I was playing around with that manipulates JPEG images. It's the JpgImage class, and it allows you to do things like rotate, scale, and invert a JPEG image. You can either read an image in from a file or pass a BufferedImage to the constructor. The Sun version of Java 1.2 or higher is required, as this class not only uses some Graphics2d classes, but also a few of the com.sun.image.codec.jpeg classes.

A lot of the methods are trivial wrappers around some of the transform classes, but the rotate() method was a little tricky. See the source code for details.

As an example, I also wrote the JpgResizer class, which is really just a command-line application that calls the methods in the JpgImage class, based on the command-line parameters that you pass. Again, see the source code for details.

JpgImage.java
JpgResizer.java


Testing ReplaceSubstring Routines
September 17, 2003 (updated March 14, 2003)

This is just a little speed test of a few different routines that can be used to replace all occurrences of a substring within a larger String. More interesting than the functions themselves (StringBuffer was faster...no surprise there) is the testing method. Reflection is used to run all the validation and the speed testing, which makes it very modular.

Normally, for tests of multiple similar functions like this, you end up copying and pasting a lot of redundant code to run the same test against multiple functions. Using the techniques in this example, you can see how Java reflection makes it possible to simply pass the name of the method you want to test, and all the testing code ends up in a single routine that gets called multiple times.

(Added the ReplaceSubstring6 method on March 14, 2004, which is similar to the other methods but checks for a condition where both the original string and the find string are "", in which case the method should return the replace string, not the original string as with the other methods. Thanks to John Marshall for that tip.)

ReplaceSubstringTest.java
ReplaceSubstringTest.class


Terminating Threads and Reacting to Shutdown in Java
November 10, 2003

When you're writing a multi-threaded program in Java, you generally want to add some handling for killing the threads when the program is ready to terminate, especially if your threads are running continuously (or potentially for a very long time) while waiting for an event to occur. For instance, a multi-threaded command-line Java program might be structured similar to this example:

ThreadKillTest.java

This type of setup should allow our program to kill and cleanup the thread and its resources, as long as the program shuts down the way we're expecting it to. However, what if a user decided to just use Control-C to terminate the program instead? None of the structured clean-up work would get done, and you could be left with a mess. This could happen just as easily with a GUI program if someone kills it at the command-line, despite the fact that you've registered your handlers for java.awt (addWindowListener) or javax.swing (setDefaultCloseOperation) or whatever GUI library you're using.

Luckily, starting with Java 1.3, Sun gave us the ability to register shutdown hooks to handle just such a case. All you have to do is make a call to

    Runtime.getRuntime().addShutdownHook(Thread t)

and you're on your way. Here are some good articles to get you started:

http://developer.java.sun.com/developer/TechTips/2000/tt0711.html
http://www.onjava.com/pub/a/onjava/2003/03/26/shutdownhook.html

Once you've got a feel for how addShutdownHook() works, you might want to delve a little deeper with these related articles:

How to effectively handle long-running tasks in Java:
http://builder.com.com/5100-6370_14-1049564-1.html

Writing your own signal handlers in Java (very technical, very cool):
http://www-106.ibm.com/developerworks/ibm/library/i-signalhandling/


Open JAR Files Natively In Windows
October 14, 2004

In case you didn't know, a Java Archive (.jar) file is really just a .zip file with a different extension. Windows 2000 and XP (and I think even ME, if anyone still uses that) came with built-in support for zip files, and you can take advantage of that to open jar files natively in Windows as though they were zip files.

This is convenient not only because you can easily open and navigate the .jar files as though they were folders, but also because Windows will then be able to search within these archive files when you're performing a regular file system search. Very handy for finding .class files buried deep within a .jar.

Technically, the steps to follow are these:

  • open regedit
  • navigate to HKEY_CLASSES_ROOT\.zip
  • right-click the .zip branch and export it to a .reg file
  • edit the .reg file in Notepad
  • do a search and replace to change HKEY_CLASSES_ROOT\.zip to HKEY_CLASSES_ROOT\.jar
  • save and close the .reg file
  • double-click the .reg file to import it to your registry
  • reboot

However, if you don't want to follow all those steps you can probably just download this .reg file and run it locally on your machine:

OpenJars.reg

Make sure you reboot after you've run/imported the .reg file, because the changes won't take effect until you restart the machine. Also, you can easily modify the .reg file to register .ear and .war files as zip files too, if you're so inclined. Those also use the zip technique for compression (well, they've got a certain directory structure too, but they're still just zips).



:
Posted by 라면스프
2008. 10. 24. 18:42

JDBC로 인한 서버 Hang(정지) - weblogic Enjoy/etc2008. 10. 24. 18:42

출처:http://kr.bea.com/support/customer_support/service_pattern/pattern/JDBC_Causes_Server_Hang_Pattern.html


문제 설명
응용 프로그램 또는 WebLogic Server 자체에 사용되는 JDBC 커넥션에 의해 해당 커넥션을 통한 호출이 완료될 때까지 WebLogic Server Execute 스레드가 차단됩니다. JVM은 CPU가 자체적인 스레드 스케줄 메커니즘에 따라 실행 가능한 스레드에 할당되며 SQL 쿼리를 차단하는 스레드가 대기해야 하는지 확인합니다. 그러나 JDBC가 사용 중인 스레드는 SQL 쿼리에서 호출이 반환될 때까지 응용 프로그램용으로 할당됩니다.

트랜잭션 시간이 초과되더라도 해당 트랜잭션에 참가한 리소스가 수행하는 작업이 중단되거나 종료되지 않습니다. 작업은 진행되는 동안 중단 없이 실행됩니다. 트랜잭션 제한 시간에 따라 설정된 플래그에 의해 트랜잭션이 롤백만 가능한 것으로 표시되기 때문에 이 트랜잭션에 대한 이후의 모든 커밋 요청은 TimedOutException 또는 RollbackException이 발생하여 실패합니다. 그러나 위에서 언급한 것처럼 실행 시간이 긴 JDBC 호출로 인해 WebLogic Server Execute 스레드가 차단될 수 있으며 그 결과 모든 스레드가 차단되어 들어오는 요청을 처리할 Execute 스레드가 남지 않으면 인스턴스가 Hang(정지) 상태가 될 수 있습니다.

최신 버전의 WebLogic Server에서는 스레드가 특정 시간(디폴트값: 600초) 내에 반응하지 않는지 규칙적으로 확인하는 상태 검사 기능이 제공됩니다. 이러한 문제가 발생하면 로그 파일에 다음과 같은 오류 메시지가 출력됩니다.

####<Nov 6, 2004 1:42:30 PM EST> <Warning> <WebLogicServer> <mydomain> <myserver> <CoreHealthMonitor> <kernel identity> <>
<000337> <ExecuteThread: '64' for queue: 'default' has been busy for "740" seconds working on the request "Scheduled Trigger",
which is more than the configured time (StuckThreadMaxTime) of "600" seconds.>


이 오류 메시지는 단순히 관리자에게 상태를 알리기 위한 것으로 스레드가 중단되지는 않습니다. 멈춘 스레드는 요청 처리가 완료되어야 다시 실행됩니다. 이 경우 WebLogic Server의 로그 파일에 다음과 같은 메시지가 표시됩니다.

####<Nov 7, 2004 4:17:34 PM EST> <Info> <WebLogicServer><mydomain> <myserver> <ExecuteThread: '66' for queue: 'default'>
<kernel identity> <> <000339> <ExecuteThread: '66' for queue: 'default' has become "unstuck".>


상태 검사 기능의 간격은 변경할 수 있습니다. config.xml 파일의 <Server> 태그에서 StuckThreadMaxTime 속성을 확인하십시오. 자세한 내용은 http://e-docs.bea.com/wls/docs81/config_xml/Server.html#StuckThreadMaxTime 또는 http://e-docs.bea.com/wls/docs81/perform/WLSTuning.html#stuckthread의 WebLogic Server 관리 콘솔 도움말에서 "멈춘 스레드 검색" 단원을 참조하십시오.

페이지 맨 위

문제 해결
다른 프로그래밍 방법이나 JDBC 커넥션 풀 구성을 사용할 경우 JDBC 데드락(Deaklock) 또는 WebLogic Server 인스턴스 Hang(정지) 상태를 초래하는 JDBC 호출이 발생할 수 있습니다. WebLogic Server 인스턴스 Hang(정지) 상태를 해결하고 분석하는 방법에 대한 자세한 내용은 일반적인 서버 Hang(정지) 패턴을 참조하십시오.

이 패턴에서는 서버 Hang(정지) 상태의 원인이 되는 JDBC 호출과 기타 WebLogic Server 인스턴스 Hang(정지) 상태를 초래하는 일반적인 JDBC 관련 문제에 대해 설명합니다. 이 패턴의 참조 지원 패턴은 WebLogic Server 지원 패턴 사이트에서 확인할 수 있습니다.

항목 바로가기

문제 발생 원인
다음과 같은 경우 WebLogic Server 인스턴스 Hang(정지) 상태가 발생할 수 있습니다.
  • JDBC 코드에 DriverManager.getConnection()을 사용하는 경우
  • 데이터베이스에 대한 SQL 쿼리 결과가 반환되는 데 너무 오래 걸리는 경우
  • JDBC 커넥션 풀이 구성된 데이터베이스가 Hang(정지)되어 적절한 시간 내에 호출에 응답하지 않는 경우
  • 느리거나 오버헤드가 발생한 네트워크로 인해 데이터베이스 호출이 느려지거나 Hang(정지)되는 경우
  • 데드락으로 인해 모든 Execute 스레드가 Hang(정지)되어 계속 대기하는 경우
  • JDBC 커넥션 풀의 RefreshMinutes 또는 TestFrequencySeconds 속성으로 인해 WebLogic Server에서 Hang(정지) 기간이 발생하는 경우
  • JDBC 커넥션 풀 축소 및 데이터베이스 커넥션 재생성으로 인해 응답 시간이 길어지는 경우
페이지 맨 위

동기화된 DriverManager.getConnection()
이전의 JDBC 응용 프로그램 코드에서는 특정 드라이버를 사용하는 데이터베이스 커넥션을 검색하기 위해 DriverManager.getConnection() 호출을 사용하기도 했습니다. 이 방법은 데드락을 발생시키거나 커넥션 요청의 성능을 상대적으로 저하시킬 수 있으므로 사용하지 않는 것이 좋습니다. 이러한 문제가 발생하는 원인은 모든 DriverManager 호출이 클래스별로 동기화되어 있어 한 스레드의 특정 DriverManager 호출이 WebLogic Server 인스턴스의 스레드에서 발생하는 다른 모든 DriverManager 호출을 차단하기 때문입니다.

또한 SQLException 생성자에 의해 DriverManager 호출을 발생시키는 대부분의 드라이버에는 로깅을 위한 DriverManager.println() 호출이 포함되어 있기 때문에 DriverManager 호출을 보내는 다른 모든 스레드가 차단될 수 있습니다.

DriverManager.getConnection()에 의해 데이터베이스에 대해 만들어진 커넥션이 반환될 때까지는 상당히 오래 걸립니다. 데드락이 발생하지 않더라도 한 스레드가 커넥션을 가져올 때까지 다른 모든 호출은 대기해야 합니다. WebLogic Server와 같은 멀티 스레드 시스템의 경우 이러한 방법은 바람직하지 않습니다.

이 정보는 http://forums.bea.com/bea//thread.jspa?forumID=2022&threadID=200063365&messageID=202311284&start=-1#202311284에서 발췌한 내용입니다.
DriverManager.getConnection()을 사용해서는 안 된다는 점은 http://e-docs.bea.com/wls/docs81/faq/jdbc.html#501044의 설명서에도 명확히 기술되어 있습니다.

JDBC 코드에 JDBC 커넥션을 사용하려면 WebLogic Server JDBC 커넥션 풀을 사용하고 풀에 대한 DataSource를 정의하여 DataSource에서 커넥션을 가져와야 합니다. 그러면 데이터베이스가 다운되는 등의 문제가 발생한 경우에 리소스 공유, 커넥션 재사용, 커넥션 새로 고침과 같은 풀의 이점을 활용할 수 있습니다. 또한 DriverManager 호출 시에 데드락 발생을 방지할 수 있습니다. WebLogic Server에서 JDBC 커넥션 풀, DataSource 및 기타 JDBC 개체를 사용하는 방법에 대한 자세한 내용은 http://e-docs.bea.com/wls/docs81/jdbc/intro.html#1036718http://e-docs.bea.com/wls/docs81/jdbc/programming.html#1054307을 참조하십시오.

DriverManager.getConnection() 호출에서 차단된 스레드의 일반적인 유형은 다음과 같습니다.
"ExecuteThread-39" daemon prio=5 tid=0x401660 nid=0x33 waiting for monitor entry [0xd247f000..0xd247fc68]
  at java.sql.DriverManager.getConnection(DriverManager.java:188)
  at com.bla.updateDataInDatabase(MyClass.java:296)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:865)
  at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:120)
  at weblogic.servlet.internal.ServletContextImpl.invokeServlet(ServletContextImpl.java:945)
  at weblogic.servlet.internal.ServletContextImpl.invokeServlet(ServletContextImpl.java:909)
  at weblogic.servlet.internal.ServletContextManager.invokeServlet(ServletContextManager.java:269)
  at weblogic.socket.MuxableSocketHTTP.invokeServlet(MuxableSocketHTTP.java:392)
  at weblogic.socket.MuxableSocketHTTP.execute(MuxableSocketHTTP.java:274)
  at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:130)



페이지 맨 위

장시간 실행되는 SQL 쿼리
장시간 실행되는 SQL 쿼리는 호출하는 응용 프로그램에 결과를 반환할 때까지 Execute 스레드를 점유합니다. 따라서 응용 프로그램 로드에 의해 요청된 호출을 동시에 여러 개 처리할 수 있도록 WebLogic Server 인스턴스를 구성해야 합니다. 이 경우 제한 요인은 JDBC 커넥션 풀의 Execute 스레드 및 커넥션 수입니다. 또한 가장 중요한 일반 규칙은 리소스 사용량을 최적화하기 위해서는 풀의 커넥션 수를 Execute 스레드 수와 동일하게 설정해야 한다는 것입니다. JTS를 사용하는 경우 실제로 활성화되지 않은 트랜잭션에 대해 커넥션이 확보될 수 있으므로 풀에 커넥션 수를 좀 더 많이 설정해야 합니다.

장시간 실행되는 SQL 호출에서 Hang(정지)되는 스레드의 경우 스레드 덤프에 Hang(정지) 상태의 데이터베이스와 매우 유사한 스택이 표시됩니다. 자세한 내용은 다음 단원에서 비교해 보십시오.

Hang(정지) 상태의 데이터베이스
데이터베이스를 사용하는 응용 프로그램의 성능은 해당 데이터베이스의 성능에 의해 가장 크게 좌우됩니다. 따라서 Hang(정지) 상태의 데이터베이스는 WebLogic Server 인스턴스의 Execute 스레드 중 대부분 또는 일부를 차단시킬 수 있으며 결과적으로 서버 Hang(정지) 상태를 발생시킵니다. 이러한 문제를 진단하려면 Hang(정지) 상태의 WebLogic Server 인스턴스에서 5개 내지 10개의 스레드 덤프를 통해 Execute 스레드가 현재 SQL 호출에 참가하고 있는지, 그리고 데이터베이스의 결과를 기다리고 있는지 확인해야 합니다. 다음은 현재 SQL 쿼리를 보낸 스레드에 대한 스택 트레이스의 일반적인 예입니다.

"ExecuteThread: '4' for queue: 'weblogic.kernel.Default'" daemon prio=5 tid=0x8e93c8 nid=0x19 runnable [e137f000..e13819bc]
  at java.net.SocketInputStream.socketRead0(Native Method)
  at java.net.SocketInputStream.read(SocketInputStream.java:129)
  at oracle.net.ns.Packet.receive(Unknown Source)
  at oracle.net.ns.DataPacket.receive(Unknown Source)
  at oracle.net.ns.NetInputStream.getNextPacket(Unknown Source)
  at oracle.net.ns.NetInputStream.read(Unknown Source)
  at oracle.net.ns.NetInputStream.read(Unknown Source)
  at oracle.net.ns.NetInputStream.read(Unknown Source)
  at oracle.jdbc.ttc7.MAREngine.unmarshalUB1(MAREngine.java:931)
  at oracle.jdbc.ttc7.MAREngine.unmarshalSB1(MAREngine.java:893)
  at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:375)
  at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1983)
  at oracle.jdbc.ttc7.TTC7Protocol.fetch(TTC7Protocol.java:1250)
  - locked <e8c68f00> (a oracle.jdbc.ttc7.TTC7Protocol)
  at oracle.jdbc.driver.OracleStatement.doExecuteQuery(OracleStatement.java:2529)
  at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2857)
  at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:608)
  - locked <e5cc44d0> (a oracle.jdbc.driver.OraclePreparedStatement)
  - locked <e8c544c8> (a oracle.jdbc.driver.OracleConnection)
  at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:536)
  - locked <e5cc44d0> (a oracle.jdbc.driver.OraclePreparedStatement)
  - locked <e8c544c8> (a oracle.jdbc.driver.OracleConnection)
  at weblogic.jdbc.wrapper.PreparedStatement.executeQuery(PreparedStatement.java:80)
  at myPackage.query.getAnalysis(MyClass.java:94)
  at jsp_servlet._jsp._jspService(__jspService.java:242)
  at weblogic.servlet.jsp.JspBase.service(JspBase.java:33)
  at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:971)
  at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:402)
  at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:305)
  at weblogic.servlet.internal.RequestDispatcherImpl.include(RequestDispatcherImpl.java:607)
  at weblogic.servlet.internal.RequestDispatcherImpl.include(RequestDispatcherImpl.java:400)
  at weblogic.servlet.jsp.PageContextImpl.include(PageContextImpl.java:154)
  at jsp_servlet._jsp.__mf1924jq._jspService(__mf1924jq.java:563)
  at weblogic.servlet.jsp.JspBase.service(JspBase.java:33)
  at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:971)
  at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:402)
  at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:305)
  at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:6350)
  at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:317)
  at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:118)
  at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3635)
  at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2585)
  at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:197)
  at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:170)


스레드는 실행 상태가 됩니다. 여러 스레드 덤프의 스레드를 비교하여 SQL 호출로부터 적절한 시간 내에 응답을 받는지 아니면 동일한 호출에서 장시간 Hang(정지)되어 있는지 확인해야 합니다. 스레드 덤프에서 SQL 호출 응답 시간이 너무 긴 것으로 확인되면 해당 데이터베이스 로그를 통해 이러한 성능 저하나 Hang(정지) 상태가 데이터베이스 문제 때문에 발생한 것인지 확인해야 합니다.

페이지 맨 위

느린 네트워크
WebLogic Server와 데이터베이스 간의 통신이 이루어지고 적절한 시간 내에 요청이 처리되기 위해서는 네트워크가 정상적으로 작동하고 안정적이어야 합니다. 따라서 네트워크가 느리면 SQL 쿼리의 결과를 기다리는 Execute 스레드가 Hang(정지)되거나 차단될 수 있습니다. 관련 스택 트레이스는 Hang(정지) 상태의 데이터베이스 단원의 예제와 비슷합니다. WebLogic Server 스레드 덤프만 분석해서는 SQL 쿼리가 Hang(정지)되거나 느려지는 근본 원인을 알 수 없습니다. 스레드 덤프는 SQL 호출의 성능에 문제가 있음을 파악할 수 있는 초기 징후라 할 수 있습니다. 다음 단계로 SQL 호출 성능 저하의 원인이 데이터베이스 문제인지 아니면 네트워크 문제인지를 확인해야 합니다.

데드락
데이터베이스 수준의 데드락과 응용 프로그램 수준의 데드락은 스레드를 Hang(정지) 상태로 만들 수 있습니다. 응용 프로그램 수준 데드락이 있는지 알아보려면 스레드 덤프를 확인해야 합니다. 이 작업을 수행하는 방법은 ServerHang - 응용 프로그램 데드락(Deadlock) 패턴을 참조하십시오. 데이터베이스 데드락은 데이터베이스 로그 또는 WebLogic Server 로그 파일의 SQL Exception을 통해 확인할 수 있습니다. 다음은 관련 SQL Exception의 예입니다.

java.sql.SQLException: ORA-00060: deadlock detected while waiting for resource
  at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:170)
  at oracle.jdbc.oci8.OCIDBAccess.check_error(OCIDBAccess.java:1614)
  at oracle.jdbc.oci8.OCIDBAccess.executeFetch(OCIDBAccess.java:1225)
  at oracle.jdbc.oci8.OCIDBAccess.parseExecuteFetch(OCIDBAccess.java:1338)
  at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:1722)
  at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1647)
  at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2167)
  at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:404)


일반적으로 데이터베이스에서 데드락이 감지되고 원인이 된 하나 이상의 트랜잭션을 롤백하여 데드락을 해결하기까지는 다소 시간이 걸리기 때문에 롤백이 끝날 때까지 하나 이상의 Execute 스레드가 차단될 수 있습니다.

RefreshMinutes 또는 TestFrequencySeconds
데이터베이스 성능 저하, SQL 호출 속도 저하 또는 최다 커넥션이 주기적으로 반복되는 경우 JDBC 커넥션 풀에 설정된 RefreshMinutes 또는 TestFrequencySeconds 구성 속성이 원인일 수 있습니다. 자세한 내용은 JDBC 문제 조사 패턴을 참조하십시오. WebLogic Server 인스턴스와 데이터베이스 사이에 방화벽이 없는 경우 외에는 이 기능을 사용하지 말아야 합니다.

풀 축소
새로운 커넥션 요청은 데이터베이스, 운영 체제 커널 및 WebLogic Server에 상당한 리소스 오버헤드를 발생시키므로 데이터베이스에 대한 커넥션을 한 번 열면 가능한 한 오랫동안 유지해야 합니다. 따라서 이러한 오버헤드를 최소한으로 유지하려면 운영 시스템에서 풀 축소를 사용하지 말아야 합니다. 풀 축소를 사용하면 유휴 풀 커넥션이 닫히게 되고 풀에서 커넥션 요청을 처리할 수 없는 경우에 다시 열립니다.

이와 같은 작업에는 다소 시간이 걸릴 수 있으므로 관련 응용 프로그램 요청에 시간이 예상 외로 많이 걸려 사용자가 시스템이 Hang(정지)되었다고 판단할 수 있습니다. JDBC 커넥션 풀 구성을 최적화하는 방법에 대한 자세한 내용은 JDBC 문제 조사 패턴을 참조하십시오.

페이지 맨 위

Hang(정지) 상태의 WebLogic Server 인스턴스 분석
Hang(정지) 상태의 WebLogic Server 인스턴스를 분석하는 방법에 대한 자세한 내용은 일반적인 서버 Hang(정지) 패턴을 참조하십시오.

시스템이 Hang(정지)되는 경우 대개 문제를 파악하려면 먼저 Hang(정지) 상태의 시스템에서 스레드 덤프를 확인하는 것이 좋습니다. 예를 들어 여러 스레드가 어떤 작업을 수행하고 있는지, 왜 Hang(정지)되었는지 등을 확인합니다. 일반적으로 스레드 덤프는 운영 시스템에서 생성할 수 있지만 오래된 JVM 버전(1.3.1_09 이전 버전)의 경우 스레드 덤프를 생성하는 동안 크래시가 발생할 수 있으므로 주의해야 합니다. 또한 WebLogic Server 인스턴스에 막대한 수의 스레드가 있는 경우 스레드 덤프를 완료하는 데 상당한 시간이 소요되고 그 동안 나머지 스레드가 잠기게 됩니다.

지연 시간이 몇 초 이내인 스레드 덤프를 두 개 이상(5-10개) 생성하십시오. 그러면 다른 스레드의 진행 상태를 확인할 수 있습니다. 또한 시스템이 실제로 Hang(정지)되어 작업이 전혀 진행되지 않거나 처리가 느려 시스템이 Hang(정지)된 것처럼 보이는 경우 이러한 내용이 표시됩니다.

스레드 덤프를 생성하는 방법에 대한 자세한 내용은 "일반적인 서버 Hang(정지)" 지원 패턴 또는 http://e-docs.bea.com/wls/docs81/cluster/trouble.html의 설명서를 참조하십시오.

또한 전체 WebLogic Server 인스턴스가 Hang(정지)된 것인지 아니면 응용 프로그램이 Hang(정지)된 것인지를 확인하십시오. 스레드 덤프를 분석하면 앞의 문제 발생 원인 단원에서 설명한 여러 가지 원인 중에서 인스턴스 Hang(정지)의 실질적인 원인을 알아낼 수 있습니다. 예를 들어 모든 스레드가 getConnection()과 같은 DriverManager 메쏘드에 있는 경우 근본 원인을 파악한 다음에 DriverManager.getConnection() 대신 DataSource 또는 Driver.connect()를 사용하도록 응용 프로그램을 변경해야 합니다.

Samurai라는 유용한 도구를 사용하여 스레드 덤프를 분석하고 여러 스레드 덤프 간에 스레드 진행 상태를 모니터할 수 있습니다. Samurai는 dev2dev 웹 사이트 http://dev2dev.bea.com/resourcelibrary/utilitiestools/adminmgmt.jsp에서 다운로드할 수 있습니다.

또한 dev2dev 웹 사이트 http://dev2dev.bea.com/products/wlplatform81/articles/thread_dumps.jsp에 있는 스레드 덤프 분석에 관한 백서를 통해 스레드 덤프와 서버 Hang(정지)에 대해 자세히 알아볼 수 있습니다.

페이지 맨 위

JDBC 코드 및 JDBC 커넥션 풀 구성 최적화를 위한 팁과 유용한 정보
JDBC 코드 개발 또는 JDBC 커넥션 풀 구성 시에 일반적인 문제 발생을 방지하고 리소스 사용량을 최적화하여 서버 인스턴스 Hang(정지)이 발생하지 않도록 하는 데 도움이 되는 몇 가지 모범 사례를 적용할 수 있습니다.

JDBC 프로그래밍
WebLogic Server에서 리소스 사용량을 최적화하고 데이터베이스 리소스를 절약하려면 응용 프로그램의 JDBC 호출에 JDBC 커넥션 풀을 사용해야 합니다. 응용 프로그램 코드에서 만들어지고 제거되는 커넥션은 불필요한 오버헤드를 발생시킵니다. JDBC 프로그래밍에 대한 자세한 내용은 http://e-docs.bea.com/wls/docs81/jdbc/rmidriver.html#1028977을 참조하십시오. 또한 JDBC 성능 조정에 대한 자세한 내용은 http://e-docs.bea.com/wls/docs81/jdbc/performance.html#1027791을 참조하십시오.

JDBC 코드 및 JDBC 리소스 사용량을 최적화하는 데 유용한 포괄적인 JDBC 관련 정보는 dev2dev Java Database Connectivity 페이지(http://dev2dev.bea.com/technologies/jdbc/index.jsp)를 참조하십시오.

JDBC 커넥션 풀 구성
JDBC 문제 조사 패턴에는 운영 환경의 커넥션 풀 구성에 대한 권장 사항이 나와 있습니다. Hang(정지)이나 성능 저하를 방지하려면 이러한 구성 팁을 고려해야 합니다.

페이지 맨 위

알려진 문제
사용하고 있는 WLS 버전의 릴리스 정보를 주기적으로 검토하여 서비스 팩에서 알려진 문제나 해결된 문제를 확인하고 JDBC 서버 Hang(정지) 관련 문제를 검색할 수 있습니다. 간편하게 다음을 참조하십시오.
드라이버가 현재 실행 중인 명령문이 반환될 때까지 기다려야 하기 때문에 특정 JDBC 커넥션에 대해 트랜잭션 롤백 호출이 바로 처리되지 않는 CR134921 오류는 WLS 8.1 SP3에서 해결되었습니다.

검색하면 릴리스 정보뿐 아니라 추가 도움말에서 언급된 기타 지원 솔루션 및 CR 관련 정보도 알 수 있습니다. 계약 고객은 http://support.bea.com/에 로그인한 다음 Browse 포틀릿에서 Solutions 및 Bug Central을 검색하여 제품 버전별로 사용 가능한 최신 CR을 찾을 수 있습니다.
:
Posted by 라면스프