Launch Java Applications from Assembly Language Programs

{cs.r.title}



Java Native Interface (JNI) is a mechanism that can be used to establish communication between native language programs and the Java virtual machine. The  documentation for JNI and the technical literature on JNI deal extensively with interactions between the JVM and C/C++ code. The Java SDK even provides a utility to generate a header file to facilitate calling C/C++ programs from Java code. However, there is hardly any mention of Java andassembly language code working together. In an earlier article I showed how assembly language programs can be called from Java applications. Here I deal with the technique for invoking Java programs from an ASM process through a demo application that calls a Java method from assembly language code. The Java method brings up a Swing JDialog to show that it has, indeed, been launched.

Why Java with ASM?

JNI is essential to the implementation of Java, since the JVM needs to interact with the native platform to implement some of its functionality. Apart from that, however, use of Java classes can often be an attractive supplement to applications written in other languages, as Java offers a wide selection of APIs that makes implementation of advanced functions very simple.

Some time ago, I was associated with an application to collect real-time data from a number of sources and save them in circular buffers so that new data would overwrite old data once the buffer got filled up. If a designated trigger event was sensed through a digital input, a fixed number of data samples would be saved in the buffers so that a snapshot of pre- and post-trigger data would be available. The original application was written in assembly language. After the application was used for a few months, it was felt that it would be very useful to have the application mail the snapshots to authorized supervisors whenever the trigger event occurred. Of course, it would have been possible to write this extension in assembly, but the team felt that in that particular instance it was easier to write that extension in Java and hook it up with the ASM program. As I had earlier worked with ASM-oriented JNI, I knew this could be done and, indeed, the project was implemented quickly and successfully.

I am sure there are many legacy applications written in assembly language that could benefit from such add-ons. However, it is not only for old applications in need of renovation that JNI can prove useful. Although it may seem unlikely to some of us, assembly language is still used for writing selected portions of new programs. In an article published not very long ago, the author says, "I have found that many of Sun's partners still use assembly language in their products to ensure that hot code paths are as efficient as possible. While compilers are able to generate much more efficient code today, the resulting code still doesn't always compete with hand-coded assembly written by an engineer that knows how to squeeze performance out of each microprocessor instruction. Assembly language remains a powerful tool for optimization, granting the programmer greater control, and with judicious use can enhance performance." Clearly, in such "mixed language" applications the ability to use Java with ASM can be useful.

Note that the technique shown here can also be used to call Java code from languages other than ASM. If JInvoke is rewritten as a .dll, code written in FORTRAN, for instance, can link to it and call a Java method.

I have used JNI with legacy ASM code in two ways:

  • Functional enhancement: Mail-enabling an existing ASM application, as mentioned earlier.
  • Interface enhancement: Adding interactive user interface (mostly AWT, but some Swing as well).

These enhanced applications have run on Windows 2000 and XP. The Java versions used were 1.3, 1.4, and 1.6. In all cases the applications worked smoothly.

The version of assembly language I have used for the demo code is MASM32. The entire MASM32 bundle is a free download, and if you are going to experiment with Java-ASM interaction, you will need to have it on your computer. A set of extremely useful tutorials on MASM programming are available on Iczelion's site. The definitive work on JNI is Sheng Liang's book The Java Native Interface: Programmer's Guide and Specification. This too is a free download. This article's Java code sample,AsmToJava, will obviously need an SDK (or, at least, a JRE) for execution. The assembly language part of the demo, JInvoke, has been compiled into an .exe file and will run even without the MASM bundle; the assembler/linker is required only if you want to modify the source code and recompile it.

The Basics

JNI provides a comprehensive interface to a JVM. This interface is exposed primarily through a rich set of functions. Native code can call these functions to interact with a JVM implementation. These functions are described in detail in Sheng Liang's book. While most of these functions can be accessed only after a JVM has been created, JNI also directly exports a number of native functions. As we shall see later, a function of the second type can be used to instantiate a JVM, so that other JNI functions can be called.

Once a JVM has been created, an assembly language program can access those JNI functions that need a JVM instance to implement their functionalities. Pointers to all these JNI functions are stored in a table, the Function Table. When the ASM code loads a JVM, it receives a variable named JNIEnv, which is really a pointer. JNIEnv points to a memory location that, in turn, contains the actual pointer to the Function Table. This chain of access is shown in Figure 1.

Access to JNI functions

Figure 1. Access to JNI functions

As we see, each of the pointers to JNI functions is four bytes long. So the pointer to any given function can be found at the location defined by adding four times the index for that function to the starting address of the function table. The function indices are zero-based--the pointer for the first function is at index 0, that for the second is at index 1, and so on. In his book, Sheng Liang lists the index values for all JNI functions.

To call a Java program, ASM code needs to execute the following steps:

  • Instantiate a JVM
  • Locate the class
  • Get the ID of the method
  • Call the method

Before we look at these steps in detail, let us check out how we can use an include file to simplify the task of writing this and similar programs. As interactions between Java and native codes take place through the functions exposed by JNI, it becomes necessary for native processes to call these functions repeatedly. So we would like to use macros to take care of these activities. That would reduce the need for repeatedly writing similar (and fairly long) code and would also reduce the chances of bugs getting into the program through typos.

The Macros

Calling a function from ASM code involves getting the pointer to the function from the Function Table and then calling the function using that pointer. Getting the pointer, as we know, involves following the JNIEnv pointer chain to obtain the starting address of the Function Table and then retrieving the pointer to the desired function by using the index of the function. The first part--getting the starting address of the Function Table--would use identical code every time and can be handled by the following macro:

    ;This macro returns the pointer to     ;Function Table in fnTblPtr    GetFnTblPtr MACRO envPtr, fnTblPtr        mov ebx, envPtr        mov eax, [ebx]        mov fnTblPtr, eax    ENDM

The code shown above defines a macro that takes two parameters. The first is the JNIEnv pointer and the second points to the location where the macro will return the pointer to Function Table. The macro loads the pointer to Function Table intoeax, which is then saved in fnTblPtr. One way of using this macro would be to define it within the program itself. Another way, adapted here, is to define all such macros within an include file, which can then be used with the ASM program through an include statement. The include file used here is jav_asm.inc. This file defines not only theGetFnTblPtr macro, but also all the others that are required for this example. In addition to the macros,jav_asm.inc defines the prototype of the function that creates a JVM as well as the structs that are to be used as parameters with that function. Finally, java_asm.incassigns symbolic names to all JNI function indices to simplify their use.

Once the pointer to the Function Table has been obtained, the pointer to the desired function needs to be retrieved. The code for this too will be the same every time except for the index. The following macro performs this task:

    ;This macro returns the pointer     ;to a function in fnPtr.        GetFnPtr MACRO fnTblPtr, index, fnPtr                mov eax, index                mov ebx, 4                mul ebx                mov ebx, fnTblPtr                add ebx, eax                mov eax, [ebx]                mov fnPtr, eax        ENDM

The macro multiplies the value of index by 4 and adds the result to the starting address of Function Table (available in fnTblPtr) to get the pointer to the function we want to access. This pointer is then saved infnPtr.

The three remaining macros are almost identical; the only difference is in the number of parameters handled:

    ;The next 3 macros push parameters as per     ;stdcall and call the function through fnPtr        CallFunction2 MACRO param1, param2, fnPtr                push param2                push param1                call [fnPtr]        ENDM        CallFunction3 MACRO param1, param2, param3, fnPtr                push param3                push param2                push param1                call [fnPtr]        ENDM        CallFunction4 MACRO param1, param2, param3, param4, fnPtr                push param4                push param3                push param2                push param1                call [fnPtr]        ENDM

As we see, these macros push the parameters (exceptfnPtr) in reverse order as required forstdcall, and then call the targeted function usingfnPtr as the pointer.

Now that the basic building blocks are in place, we can take a look at the four-step sequence followed by our demo application.

Creating a JVM Instance

JInvoke creates an instance of JVM more or less in the same way as the java command does when we launch a Java application from the command line. A Java virtual machine implementation offers a mechanism known as the Invocation Interface that allows a native application to load the virtual machine. The java command calls a C program that uses the Invocation Interface to run a Java application, andJInvoke uses this same interface. The code for loading the JVM is given below:

    .    .    .    va          vm_args <>    jvmo        JavaVMOption <>    .    .    .    mov jvmo.optionString, offset opzero    mov va.options, offset jvmo    mov va.version, 00010002h    mov va.nOptions,1    mov va.ignoreUnrecognized, TRUE    invoke JNI_CreateJavaVM, offset JavaVM, offset JNIEnv,         offset va

Here we first declare two structs. As we have already seen, these structs are defined in jav_asm.inc. The creation of a JVM requires that a number of parameters be specified. These are passed to the JNI_CreateJavaVM function through the structs.

In our example, we want to invoke the main method of the AsmToJava class. On my computer, the class file is in the C:\j2sdk1.4.2_05\testjni folder. The stringopzero defines this path in accordance with the method described in the JNI specs. Note that opzero is loaded into the struct jvmo, and then the offset tojvmo is loaded into the struct va. The last parameter passed to the JNI_CreateJavaVM function is va and, therefore, the JVM that is loaded comes to know where to find the class that we are interested in.

When JNI_CreateJavaVM returns, it signals success by returning zero in eax and failure by returning a negative number in eax. If the function succeeds in creating the JVM instance, the pointer to the JVM interface and the corresponding JNIEnv pointer are available inJavaVM and JNIEnv, respectively.

On return from the JNI_CreateJavaVM function,JInvoke checks the content of eax. If it is not zero, the JVM has not been loaded. The user is informed of this and the process exits:

    .if eax == 0        .        .        .    .else        invoke MessageBox, 0, addr Fail1Text,             addr Caption, 16; failed to create JVM    .endif 

On the other hand, if the content of eax is zero, then a message box is shown (Figure 2) with the corresponding message and the next step is executed:

    .if eax == 0        invoke MessageBox, 0, addr VmText,             addr Caption, 64; indicate success

Message to show that JVM has been loaded

Figure 2. Message to show that the JVM has been loaded

I must point out here that JInvoke uses the simplest approach to JVM instantiation since it is meant to be a vehicle for concept demonstration only. A number of additional parameters can be specified, as is explained by Sheng Liang in his book.

Locating the Class

After loading the JVM, JInvoke needs to locate the class that is the entry point for the target Java application. The following code calls the FindClass function to do this:

    GetFnTblPtr JNIEnv, fntblptr    GetFnPtr fntblptr, FI_FC, fnptr ; ptr to FindClass    CallFunction2 JNIEnv, offset ProcName,         fnptr ; call FindClass    .if eax != 0        mov classid, eax        invoke MessageBox, 0, addr FcText,             addr Caption, 64; class found

Note that the path to the class was earlier loaded into the struct jvmo (mov jvmo.optionString, offset opzero) and is already known to the JVM. If the FindClass function is able to locate the class, it returns the ID in eax. Otherwise it returns zero. Once the class is located, its ID is saved and a message box so informs the user (Figure 3).

Message to show that the class has been found

Figure 3. Message to show that the class has been found

If the class cannot be located, then the process exits after showing an appropriate message. Figure 4 is an example of a message shown when a called function does not succeed.

Message to show that the class could not be found

Figure 4. Message to show that the class could not be found

Getting the Method ID

In order to call the method, the corresponding ID has to be obtained. The function that returns the ID for a static method isGetStaticMethodID. We use this function here since we want to call the main method of theAsmToJava class. The parameters for this function--in addition to JNIEnv--are:

  • The ID of the class to which the method belongs; this is theclassid variable referred to in the previous step.
  • The name of the method; this is the stringmethodname.
  • The descriptor of the method that specifies the parameters for the method and its return type; the string methodsig is the descriptor for our target method. In this case, the parameter is a String array and the return type isvoid. Sheng Liang's book on the JNI specification shows how to create descriptors for methods and for variables too.

The call to GetStaticMethodID is very similar to the other function calls we have seen so far:

    GetFnPtr fntblptr, FI_GSMID, fnptr ; ptr to GetStaticMethodID    CallFunction4 JNIEnv, classid, offset methodname,         offset methodsig, fnptr ; GetStaticMethodID    .if eax != NULL        mov methid, eax        invoke MessageBox, 0, addr GsmiText, addr Caption, 64

GetStaticMethodID returns the ID ineax. If the attempt to obtain the method ID is unsuccessful then NULL is returned instead. So JInvokechecks the content of eax to determine whether to go on to the next step (Figure 5) or exit the process.

Message to show that method ID has been obtained

Figure 5. Message to show that method ID has been obtained

Calling the Target Method

The JNI function that calls a static method with the return typevoid (remember, we are calling the mainmethod) is CallStaticVoidMethod. The following code gets the pointer to this function and calls it with the required parameters:

    GetFnPtr fntblptr, FI_CSVM, fnptr ; get CallStVM ptr    CallFunction3 JNIEnv, classid, methid, fnptr; call CallStVM

The Java application displays a dialog to show that it has been successfully launched.

Java method successfully invoked

Figure 6. Java method successfully invoked

Once the called Java method returns, JInvokeexits.

Message to show that the process is exiting

Figure 7. Message to show that the process is exiting

When the ExitProcess function is called, all threads in the process are stopped, so the Java threads created by the process will also be stopped. Therefore, if this approach is used to launch a Java program, care must be taken to ensure that the called Java method returns only after completing all required activities. Actually, the issues involved in terminating the calling process and the JVM need careful attention. Please refer to the Windows API  documentation and the latest JNI specs.

Conclusion

The approach shown here demonstrates the basic technique used for launching Java applications from assembly language code. Adequate error checking should be incorporated in native programs to ensure safe interaction with the Java environment. Sheng Liang provides many examples of checks including handling of exceptions in native code. ASM programs working with JNI should use such error checking methods wherever applicable.

The jav_asm.inc file provides an easy way of specifying JNI function indices. The use of symbolic names instead of numbers to specify an index is less likely to lead to errors. The use of macros, too, is useful in reducing errors. You are free to use this file with your code and also to modify it to suit your requirements. However, make sure that the file is not redistributed without the disclaimer.

When running JInvoke, you may get an error message saying that jvm.dll cannot be located. If this happens, you need to add the path to the directory containing jvm.dllto your PATH environment variable. This DLL is normally located in the jre\bin\client directory under the Java SDK root folder. For instance, on my computer, the path isC:\j2sdk1.4.2_05\jre\bin\client for the Java 1.4 release. If you are using Java 1.3, however, the folder would bejre\bin\classic. So make sure you've got the right path.

Finally, I would like to point out that the paths to the files named in the include statements ofJInvoke would be determined by the directory structure of your computer. The paths specified in JInvoke are valid for my computer. As far as JInvoke.exe is concerned, it will run even without any MASM component (specifically, any .inc or .lib file) being loaded into your system. If you want to modify the code and recompile it, you will have to make sure that the path details correspond to the way your directories are set up. The AsmToJava class file will have to be loaded in the directory specified byopzero. Alternately, opzero will have to be changed to reflect the path to this class. In that case, the source file for JInvoke will need to be recompiled, keeping in mind the need to modify other path names as mentioned above.

Resources

Biswajit Sarkar is an electrical engineer with specialization in Programmable Industrial Automation. Biswajit is the author of "LWUIT 1.1 for Java ME Developers" published by PACKT Publishing.



XCode 간단 설치와 사용법 - Objective-C의 예제 개발하기
[출처]XCode 간단 설치와 사용법 - Objective-C의 예제 개발하기 :
http://www.hanb.co.kr/network/view.html?bi_id=1623

1. 이 글의 목적

Objective-C : 맥과 아이폰 애플리케이션 프로그래밍이 Objective-C 본연의 내용에 충실하기 위해 개발 툴인 Xcode에 대해서는 의도적으로 설명이 배제되어 있습니다. 이에 Xcode를 사용해서 Objective-C의 예제를 개발하고 싶은 독자를 위해 간단히 Xcode를 설치하고 프로젝트를 만드는 과정과 소스 코드를 개발, 실행하는 과정을 HelloWorld라는 친숙한 예제로 예를 들었습니다.

2. Xcode 설치

개발 툴을 설치하기 위해 Mac OS X 10.5 패키지에 들어 있는 DVD 혹은 Mac을 구입했을 때 제공된된 DVD를 본체의 DVD 드라이브에 넣습니다. 이 책에서는 Mac 구입 시 제공된 DVD를 사용하였습니다. DVD의 내용을 Finder로 보면 'Optional Install'이라는 항목이 나오는데 이것을 열어봅니다.

null

그리고 'Xcode Tools'라는 폴더를 엽니다.

null

'Xcode Tools.mpkg'를 더블 클릭하면 설치 프로그램이 실행됩니다.

null

설치 프로그램이 실행되면 사용권 계약과 설치 확인 화면 등이 차례대로 나오는데 화면에 나오는 지시에 따라 설치를 계속하면 됩니다.

null

설치 프로그램이 종료되면 지정한 드라이브에 'Developer'라는 이름으로 폴더가 만들어집니다.

null

이 폴더 안에는 개발에 필요한 애플리케이션과 기술 자료, 샘플 코드들이 들어 있는데 이것들을 통틀어서 'Developer Tools'라고 부릅니다. 프로그램 개발을 위한 애플리케이션은 'Applications' 폴더에 들어 있으므로 이 폴더를 열어봅니다.

null

이 폴더 안에서 주로 사용하는 애플리케이션이 'Xcode'와 'Interface Builder'입니다.

null

3. Xcode 실행하기

Developer 폴더 안에 있는 Applications 폴더에서 Xcode 아이콘을 찾아 더블 클릭하면 Xcode가 실행됩니다.

null

Xcode가 처음 실행되면 네비게이션 윈도우가 표시됩니다(설정에 따라 나오지 않을 수도 있습니다).

null

영문으로 표시되는 각 항목을 클릭하면 별도의 창이 뜨면서 해당 기술 자료가 표시 됩니다. 윈도우 왼쪽 아래에 있는 'Show at launch'를 끄면 다음 실행부터 네비게이션 윈도우가 표시되지 않습니다.

4. 신규 프로젝트 만들기

Xcode의 기본적인 사용 방법을 이해하기 위해 새로 프로젝트를 만들어봅니다. 파일 메뉴에서 'New Project'를 선택합니다.

null

신규 프로젝트의 템플릿을 선택하기 위한 다이얼로그 창이 뜹니다. 왼쪽 리스트에서 'Command Line Utility'를 선택한 후, 오른쪽 아이콘들 중 'Foundation Tool'을 선택합니다. 참고로 3장에서는 'Cocoa Application'을 선택했었는데 이번 예제는 윈도우나 버튼과 같은 유저 인터페이스가 없기 때문에 'Foundation Tool' 형태로 만듭니다. 여기까지 선택이 되었으면 우측 하단의 'Choose' 버튼을 클릭합니다.

null

프로젝트 폴더의 저장 위치를 결정하기 위한 시트 다이얼로그 창이 뜹니다. 이름을 'HelloWorld'라고 정하고 저장 위치를 'Desktop'으로 지정한 후, 'Save' 버튼을 클릭합니다.

프로젝트 윈도우 창이 뜹니다.

null

5. 빌드하고 실행하기

우측 상단의 파일 목록에서 HelloWorld.m 파일을 선택하면 우측 하단의 편집기에 파일 내용이 표시됩니다.

null

참고로 Xcode는 프로젝트명과 동일한 이름으로 main 함수를 가지는 구현 파일을 자동으로 생성합니다. 그리고 바로 실행이 가능하도록 NSLog에 "Hello, World!"를 출력하도록 되어 있습니다. 우선은 현재 이 상태에서 그래도 빌드하고 실행해 봅니다. 툴 바에 있는 'Build and Go' 버튼을 클릭합니다.

null

우측 상단 파일 목록에는 Code 항목에 빌드된 파일의 크기가 표시되고 우측 하단에는 빌드가 성공했음을 표시하는 'Succeeded'를 볼 수 있습니다. 이제 실행을 시켜 보겠습니다. 메뉴 바에서 'Run'을 선택한 후, 펼쳐지는 항목들에서 'Console'을 클릭합니다.

null

실행 결과는 아래와 같습니다.

null

소스 코드를 손을 대지 않은 상태에서 그냥 프로젝트를 만든 후, 기본 파일을 빌드하고 실행만 하더라도 간단한 "Hello, World!" 메시지를 출력하여 정상 동작하는 것을 확인하였습니다.다만 이는 C언어에서의 개발과 같이 객체지향적인 개념을 아직 사용하지 않았습니다.

본격적으로 객체지향적은 개념을 도입하기 위해 "Hello, World!" 출력을 해주는 MyHelloWorld 객체를 만들어 보겠습니다.

MyHelloWorld 클래스 만들기

프로젝트 윈도우의 왼쪽에 있는 'Groups & Files' 목록에서 'Source' 항목을 선택합니다.

null

파일 메뉴에서 'New File'을 선택합니다.

null

신규 파일의 템플릿을 선택하기 위한 다이얼로그 창이 뜹니다.

null

왼쪽 리스트에서 'Cocoa'를 선택한 후, 오른쪽 아이콘 중에서 'Objective-C class'를 선택합니다. 'Next' 버튼을 누르면 저장 위치를 묻는 시트 다이얼로그 창이 뜹니다.

null

파일명을 'MyHelloWorld.m'으로 지정하고 저장 위치가 프로젝트 폴더 안에 있는 것을 확인한 후, 'Finish' 버튼을 클릭합니다. 'Groups & Files' 목록의 'Source'에 MyHelloWorld.m과 MyHelloWorld.h가 등록된 것을 알 수 있습니다.

null

MyHelloWorld 인터페이스 개발하기

이미 만들어진 MyHelloWorld.h를 선택해서 편집기에 불러들이면 아래와 같이 기본 골격이 만들어져 있습니다.

null

여기에 "Hello, World!"를 출력하기 위한 sayHello 메소드를 추가합니다.

null

이제는 이 메소드를 구현할 차례입니다.

6. MyHelloWorld 구현코드 개발하기

이미 만들어진 MyHelloWorld.m을 선택해서 편집기에 불러들이면 아래와 같이 기본 골격이 만들어져 있습니다.

null

여기에 방금 추가한 sayHello 메소드를 구현합니다.

null

이제 MyHelloWorld에 대한 인터페이스와 구현이 완성되었으니 원래 있던 HelloWorld.m이 이것을 사용하도록 수정합니다. 참고로 자동으로 생성된 코드는 주석으로 막았습니다.

null

이제 앞서 해본 것과 같이 빌드와 실행을 해 봅니다.

null

앞서 HelloWorld.m에서 직접 "Hello, World!" 메시지를 찍었던 것을 MyHelloWorld 객체를 통해서 메시지를 찍도록 리팩토링되었습니다.

7. 마무리

이제까지 Xcode를 사용한 간단한 HelloWorld 예제를 만들어 보았습니다. Objective-C에 보다 집중하기 위해 저자는 Xcode의 사용 방법에 대해서는 의도적으로 배제해 두었습니다만, Vim이나 Emacs 편집기 사용이 불편한 개발자에게는 Xcode의 편집 기능이 유용할 것입니다.











Introduction

Android source code is maintained in two code bases: the Android Linux kernel (kernel directory) and Android platform and applications (device directory). This  document provides a high-level introduction to the source code organization and an overview of the major components of each primary directory.

Android Source

Linux Kernel

The Android Linux kernel includes enhancements to the Linux 2.6 kernel that provide additional drivers to support the Android platform, including:

  • Binder: an OpenBinder-based driver to facilitate inter-process communication (IPC) in the Android platform.
  • Android Power Management: a light weight power management driver built on top of standard Linux power management but optimized for embedded systems.
  • Low Memory Killer: Based on hints from the userspace, the low memory killer can kill off processes to free up memory as necessary. It is designed to provide more flexibility than the Out Of Memory (OOM) killer in the standard kernel.
  • Logger: A light weight logging device used to capture system, radio, logdata, etc.
  • USB Gadget: Uses the USB function framework.
  • Android/PMEM: The PMEM (physical memory) driver is used to provide contiguous physical memory regions to userspace libraries that interact with the digital signal processor (DSP) and other hardware that cannot cope with scatter-gather.
  • Android Alarm: A driver which provides timers that can wake the device up from sleep and a monotonic timebase that runs while the device is asleep.

Look for Android-specific enhancements in the following directories:

  • /drivers/android
  • /drivers/misc
  • /include/linux

Android Platform and Applications

The following list outlines the directory structure found within the device branch of Android source code:

  • apps : Core Android applications such as Phone, Camera, and Calendar.
  • boot : Reference Android bootloader and other boot-related source code.
  • commands : Common Android commands, the most important of which is the runtime command, which does much of the initialization of the system.
  • config : System-wide makefiles and linker scripts.
  • content : Standard Android ContentProvider modules.
  • dalvik : Android runtime Virtual Machine (VM).
  • data : Fonts, keymaps, sounds, timezone information, etc.
  • docs : Full set of Android  documentation.
  • extlibs : Non-Android libraries. This directory is intended to host unmodified external code. None of the libraries included within this directory rely on Android headers or libraries.
  • ide : Tools for support of the IDE's used to write Android applications.
  • include : Android system headers for inclusion.
  • java : Android core APIs, as well as some external libraries.
  • libs : Android-specific C++ based libraries.
  • partner : Project-specific source code for various proprietary components.
  • prebuilt : Prebuilt tools, like the toolchains and emulator binary.
  • product : Device-specific configuration files. This directory will include a subdirectory for each new device.
  • samples : Sample applications.
  • servers : C++ based system servers.
  • system : Core of the embedded Linux platform at the heart of Android. These essential bits are required for basic booting, operation, and debugging.
  • tests : Platform and application test cases.
  • tools : Tools for building and debugging Android (of particular interest for porting are "adb" and "emulator").

Java Spring 2.0 Web 예제(Hello World)

이전 포스트(Spring Framework 다운로드) 참조 => http://blog.naver.com/sungback/90036900896

0. http://www.springsource.org/download 링크를 따라가서

spring-framework-2.5.6-with-dependencies.zip 을 다운받아 압축 해제한다.

1. 이클립스에서 File -> New -> Dynamic Web Project -> hellospring 이라고 하자.

2. WEB-INF -> lib 폴더에 아래 그림처럼 jar 파일을 복사한다.

1) 압축 해제 폴더\dist\spring.jar

2) 압축 해제 폴더\dist\modules\spring-webmvc.jar

3) 압축 해제 폴더\lib\jakarta-commons\commons-logging.jar

3. web.xml 을 아래와 같이 수정한다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>hellospring</display-name>
<servlet>
<servlet-name>spring2</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>spring2</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>

4. Java Resource: src -> 우클릭 -> New -> Class

아래 소스 작성

package hellospring.web;

import! javax.servlet.http.HttpServletRequest;
import! javax.servlet.http.HttpServletResponse;
import! org.apache.commons.logging.Log;
import! org.apache.commons.logging.LogFactory;
import! org.springframework.web.servlet.ModelAndView;
import! org.springframework.web.servlet.mvc.Controller;

public class HelloController implements Controller {
protected final Log logger = LogFactory.getLog(getClass());

@Override
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
logger.info("hello 예제 정상 작동");//로그 메세지 보여준다.
request.setAttribute("name", "홍길동");//name 홍길동 셋팅.
return new ModelAndView("hello.jsp");//hello.jsp 로 가라.

}
}

5. WebContent -> 우클릭 -> JSP -> hello.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello Spring 예제</title>
</head>
<body>
<h3>Hello Spring 예제</h3>
Hello!!! <%=request.getAttribute("name") %>
</body>
</html>

6. WEB-INF -> 우클릭 -> spring2-servlet.xml -> [Finish]

규칙 : web.xml 에서 정의한 서블릿 이름인 spring2-servlet.xml 로 만들어야 한다.

아래의 소스를 작성한다. (url 인 /hello.htm 을 처리할 클래스 HelloController 에 맵핑시킨다..)

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean name="/hello.htm" class="hellospring.web.HelloController"/>

</beans>

7. 서버 시작 후 http://localhost:8080/hellospring/hello.htm 테스트.

[출처] 이클립스 첫번째 Spring 예제(Hello World)|작성자 메멘토

1) 데이트 강간을 위한 ‘악마의 술잔’ 한모금에 블랙아웃…24시간내 검사 못하면 미제사건

2) 죽음의 性도착증 ‘자기 색정사’ 혼절직전의 성적 쾌감 탐닉…‘질식에 중독되다’

3) 부인을 죽인 건 오열했던 남편 사고로 위장한 최악의 선택…죽거나 혹은 더 나빠지거나

4) 아내의 눈속에 담긴 죽음의 비밀… 흔해서 더욱 잔인한 교통사고 위장 살인

5) 강간 후 살해된 여성, 그리고 부검의 반전 죽을 때까지 여성이고 싶었던 남성의 사연

6) 살인현장 속 왠 대변(?)검사… 초미니 흔적 ‘미세증거물’ 속에 숨은 진실

7) 정자가 수상한 정액…씨없는 발바리’ 과학수사 얕봤다가 정관수술까지 한 연쇄 성폭행범

8) 엽기살인마는 피가 다르다(?) 혈흔 속 性염색체가 ‘악마의 姓’ 을 지목하다

9) “왜 그날 조폭은 남진의 허벅지를 찔렀나?”… 칼잡이는 당신의 ‘치명적 급소’를 노린다

10) 물 마시던 A씨의 갑작스런 사망 왜? 사람의 능력 이상으로 물 많이 마시면 생명 잃는다

11) 장문의 유서를 남기고 자살한 엄마…알고보니 생활반응은 죽음의 진실을 알고 있다

12) 불탄 시신의 마지막 호흡…그녀가 아들을 지목하다 화재사망 속 숨어있는 타살흔적 찾기

13) 車 운전석에서 질식해 숨진 그녀의 주먹쥔 양팔

14) 성형수술 자국이 일러준 주검의 주민번호 광대뼈 축소술, 동거男에 목졸린 백골의 한 풀다

15) 연쇄살인범에 당한 20대女…6년만의 대반전 연쇄살인 택시기사, 274만개의 눈 CCTV가…

16) 20대 여성이 남긴 마지막 글씨…살인자를 지목하다 찢어진 장부가 범인을 증언하다

17) 물속에서 떠오른 그녀의 흰손…살인자를 가리키다 바다에서 건진 토막시신의 신원찾기

18) 헤어드라이어 살인…‘전류반’은 못 숨겼네 몸에 남은 전기충격 자국이 완전범죄 밝혀내다

19) 자살이라 보기엔 너무 폭력적인 죽음…왜? 참혹한 죽음…가해자·피해자는 하나였다

20) 아파트 침대 밑 여성 시신 2구의 잔인한 진실게임… 누명 벗겨준 거짓말 탐지기

21) 그 남자 노리는 ‘한밤 통증’… 동양인의 저주? 청장년 급사 증후군

22) 70% 부패한 시신… 말없이 증언하는 ‘어금니’ 억울한 죽음 단서 된 치아

23) 살인현장의 240㎜ 운동화…60대 노인의 트릭이었다 별무늬 자국의 비밀

24) 사회 첫발 20대女 살해한 택시기사, 흙탕물이… 돈 버리고 납치 이상한 택시 강도

25) 그녀가 남긴 담배꽁초…DNA는 남자라고 말하는데 살인 현장에 남은 ‘그 남자’의 립스틱

26) 목졸려 숨진 60대 시신 크게 훼손됐는데… 범인의 속임수였다 ‘파란 옷’ 입었던 살인마

27) 흉기에 17번 찔려 죽은 여자 유일 목격자 경비 최면 걸자 법최면이 일러준 범인의 얼굴

28) 소리없이 사라진 30대 새댁, 알고보니 들짐승이… 부러진 다리뼈가 범인을 지목

'생활의 발견' 카테고리의 다른 글

젊은이들이 취업 못하는 뻔한 이유... 그 두번째 이야기  (0) 2011.11.19
특허 등록 절차  (0) 2011.11.17
2010.11.30 하늘공원 나들이  (0) 2010.11.30
comphy on IMVU  (0) 2010.10.21
Work for Project PUC(U+)  (0) 2010.10.15

kernel.org가 아닌 구글에서 안드로이드 소스 다운로드 및 빌드

* 결국 kernel.org는 복구가 안돼네요. 구글에서 안드로이드 소스를 공유하기로 하고,

제 3자인 kernel.org에 소스를 위탁했던 것 같은데, 이젠 구글에서 직업 배포합니다.

* Linux 64bit version을 컴퓨터에 설치 후

소스만 2GB이므로 빌드 환경을 위해서는 10GB 이상이 요구됩니다.

* 1. JDK 설치

$ sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu hardy main multiverse"
$ sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu hardy-updates main multiverse"
$ sudo apt-get update
$ sudo apt-get install sun-java5-jdk

sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
$ sudo add-apt-repository "deb-src http://archive.canonical.com/ubuntu lucid partner"
$ sudo apt-get update
$ sudo apt-get install sun-java6-jdk

* 2. 빌드 환경을 위한 유틸리티 설치

$ sudo apt-get install git-core gnupg flex bison gperf build-essential \
zip curl zlib1g-dev libc6-dev lib32ncurses5-dev ia32-libs \
x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev \
libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown \
libxml2-utils

* 3. 소스 다운로드를 위한 repo 설치

$ mkdir ~/bin
$ PATH=~/bin:$PATH
$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

* 4. repo 초기화

$ repo init -u https://android.googlesource.com/platform/manifest

* 5. 소스 다운로드

$ repo sync

기존 kernel.org 에서 다운로드 하던 방식에서 변경된 것은

repo 초기화가 주소가 https://android.googlesource.com/platform/manifest

으로 변경된 것입니다.

* 6. 소스 빌드

$make



'Computer Science' 카테고리의 다른 글

Android : Source Code Overview  (0) 2011.11.10
Java Spring 2.0 Web 예제(Hello World)  (0) 2011.11.09
[알아봅시다] 샵 메일  (0) 2011.11.06
spring + iBatis 연동하기  (0) 2011.11.02
스프링 - 아이바티스 연동  (0) 2011.11.02

[알아봅시다] 샵 메일

메일 보내고도 안보냈다 발뺌 못해
'내용증명' 역할 톡톡

신동규 기자dkshin@dt.co.kr | 입력: 2011-11-03 20:24

[2011년 11월 04일자 18면 기사]

@자리에 # 도입한 형태
계정등록해 서비스 이용
이메일 분쟁 대폭 줄 듯

1990년대 후반부터 대중화되기 시작한 이메일을 통한 소통은 우리 생활과 뗄 수 없는 `산소'같은 존재가 돼 버렸습니다. 거래처와의 의사소통에서 친구들과 안부를 주고받는 일까지 이메일 없이 지금같이 원활한 의사소통을 상상할 수 있을까요.

하지만 이메일을 통해 주고받은 내용이 누군가에 의해 소송에 걸리고 법정 안의 공방으로 이어진다면 이야기가 달라집니다. 현행법상 이메일 등 전자플랫폼으로 문서를 주고 받은 것을 공식적으로 입증할 수 있는 명확한 규정이 없습니다. 각종 계약서를 둘러싼 소송에서 송수신자가 메일을 보내거나 받아놓고도 `오리발'을 내밀 경우 법적으로 이를 명확하게 입증할 방법이 없었기 때문입니다.

하지만 `샵(#)메일'이 도입되면 이 같은 전자문서 송수신 및 유통을 둘러싼 분쟁이 상당부문 줄어들 전망입니다. 오늘은 기존 이메일 기능에 `내용증명' 기능을 크게 강화한 `샵메일'에 대해 알아보겠습니다.

지난달 27일 지식경제부 산하 정보통신산업진흥원(NIPA)은 `샵메일' 서비스를 개시한다고 발표했습니다. 이에 따라 샵메일 서비스를 원하는 개인이나 법인 등은 NIPA가 등록대행 계약을 체결한 공인전자문서보관소 홈페이지를 방문해 전자공인주소 계정을 등록하고 샵메일을 발급받을 수 있습니다. 현재는 KTNET이 1호 사업자로 선정돼 샵메일 등록 대행기관의 첫 장을 열었고 삼성SDS, 유퍼스트뱅크, 코스콤 등이 추가 사업자 선정을 기다리고 있습니다. NIPA 회계팀은 외부 단체와의 계약서 작성시 샵메일을 통해 문서를 주고받는 시범사업에 나섰습니다.
◇메일 주소에 @(at)대신 #(sharp) 사용= 샵메일은 `사용자계정(ID)+구분기호(#)+기업/개인명.kr'으로 구성됩니다. 예를 들어 ABC전자 기획팀의 경우 PLAN#ABC.co.kr, 정보통신산업진흥원 전자문서팀의 경우 e- document#nipa.or.kr로 표기되는 식입니다. 기존 이메일에서 `@'이 들어가는 자리에 샵(#)을 도입한 형태입니다.

이메일과 샵메일의 가장 큰 차이점은 샵메일이 `내용증명' 기능을 갖추고 있다는 점입니다. 샵메일에서는 송신자가 자신이 메일을 송신하고 보내지 않았다고 부인하거나 수신자가 메일을 수신한 후 수신하지 않았다고 부인할 수 없어 각종 소송 등에서 사실관계를 입증할 수 있는 데 크게 기여할 것으로 기대하고 있습니다. 또한 공인전자문서보관소를 통해 문서의 유통을 증명하는 유통증명서(송신, 수신, 열람)를 공인전자문서보관소에 보관, 법적 증거력을 확보하고 스팸메일 관리와 악성코드로부터 메일 서비스를 보호ㆍ관리할 수 있는 기능을 갖췄습니다.

◇`계약서ㆍ증명서' 송수신시 분쟁 줄여=정부 및 관련업계는 샵메일 서비스가 본격화되면, 다양한 형태의 비즈니스 모델이 나타날 것으로 기대하고 있습니다. 정부ㆍ공공ㆍ기업간 문서 송수신부터 민간 부문의 계약ㆍ고지ㆍ통보 등에 이르기까지 다양한 영역에서 샵메일의 내용증명 기능이 역할을 할 것으로 전망됩니다. 졸업증명서, 가족관계증명서 등 11개 부문에 걸쳐 작년부터 시범사업을 시행해온 지식경제부는 샵메일 개시와 더불어 전자문서 업계 등 관련 업계가 활기를 띌 것으로 기대하고 있습니다. 샵메일 서비스가 본격적으로 탄력을 받기 위해서는 10월 말 국회에 제출된 전자거래기본법 개정안이 올해 국회를 통과해야 합니다. 이 개정안이 통과되면 기존 법안의 전자문서의 `보관' 기능에 `유통'기능까지 합법화돼 샵메일 서비스가 날개를 달 것으로 전망됩니다.
◇보안 문제 해소가 확대 관건= 샵메일의 다양한 특장점에도 불구하고 자신의 메일기록이 제3의 장소에 보관된다는 사실에 일각에서는 우려를 하기도 합니다.

NIPA 전자문서팀 안대섭 팀장은 "현재 포털업체들에서 쓰고 있는 이메일의 내용이 어디서 어떻게 쓰이고 있는지 알 수 있느냐"며 "공인전자문서보관소 관리자들이 메일의 내용을 열람할 수 없도록 하고 있으며 지식경제부에서 1년 단위로 사업자들에 대한 신뢰성 및 메일열람 여부를 조사하는 등 안전한 중개자 역할을 할 것"이라고 말했습니다. 지식경제부 관계자도 "샵메일 관리를 맡게 되는 민간사업자들은 신원조회 등 공무원과 같은 강도의 도덕적인 규제가 가해져 객관적인 관리와 안전성 문제는 안심해도 될 것"이라고 강조했습니다.

신동규 기자 dkshin@

자료=정보통신산업진흥원

[저작권자 ⓒ디지털타임스 무단 전재-재배포 금지]

spring + iBatis 연동하기

[출처] http://suicide102.egloos.com/2283394

1. web.xml 설정

: 아래의 설정은 spring과 iBatis의 연동과는 상관이 없는 설정내용입니다. 아래 설정은 WEB-INF/spring-config/ 에 있는 applicationContext로 시작하는 xml 파일을 웹어플리케이션이 시작될때 읽도록 하기 위해 설정하였습니다.(밑에 설명을 위해 참고로 설명)

<?xml version="1.0" encoding="UTF-8"?>

<web-app>

...

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-config/applicationContext*.xml</param-value>
</context-param>

...

</web-app>

2. applicationContext.xml 설정

: spring 관련 설정들은 프로젝트의 규모에 따라 업무단위 또는 웹어플리케이션 계층(layer)단위로 나누기도 합니다. 나는 업무단위로 설정파일을 나누었으며, 일반적인 설정(dataSource,messageSource등)을 이 파일에서 설정하였습니다.

2.1. sqlMapClient 설정하기!

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="
http://www.springframework.org/schema/p"
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

...

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/spring?characterEncoding=euckr"
p:username="javajigi" p:password="password" />

<bean id="
sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="
classpath:spring/mvc/sample/mapper/maps/sqlMapConfig.xml" />
<property name="dataSource" ref="dataSource" />
</bean>

...

</beans>

3. sqlMapConfig.xml 설정

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"
http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<!-- Optimizing Setting -->
<settings enhancementEnabled="true" useStatementNamespaces="true" />

<!-- Sql Map 설정 -->
<sqlMap resource="spring/mvc/sample/common/model/mapper/maps/sqlMap-Board.xml" />

</sqlMapConfig>

참고> settings의 요소

azyLoadingEnabaled 적재지연은 정보를 필요한 때에만 읽어 들이고 다른 데이터는 명시적인 요청이 있을 때가지 적재를 미루는 기술이다.
cacheModelsEnabled 캐싱은 성능을 향상시키는 기법으로 최근 사용된 데이타가 미래에 다시 사용될 것이라고 가정하고 메모리에 계속저장해 두는 것
enhancementEnabled 이 설정은 CGLIB에 최적화된 클래스를 통해 적재 지연 성능을 향상시킬지 여부를 지정
|참고| CGLIB는 실행시간에 코드를 생성하는 라이브러리이다. 다른 성능 향상 기법들 처럼 꼭 필요하다고 생각되지 않으면 사용하지 않는 것이 좋다.
useStatementNameSpace name space 사용 여부
maxRequest, maxSessions,maxTransactions 사용하기를 권장하지 않는다.
maxRequest 이것은 한꺼번에 SQL문을 수행할 수 있는 쓰레드의 수. 셋팅값 보다 많은 쓰레드는 다른 쓰레드가 수행을 완료할때까지 블록된다. 다른 DBMS는 다른 제한을 가진다. 이것은 최소한 10개의 maxTransactions이고 언제나 maxSessions과 maxTransactions보다 크다. 종종 동시요청값의 최대치를 줄이면 성능향상을 보여준다.
예:
maxRequests=”256”
Default: 512
maxSessions 이것은 주어진 시간동안 활성될수 있는 세션의 수이다. 세션은 명시적으로 주어질수도 있고 프로그램적으로 요청될수도 있고 쓰레드가 SqlMapClient 인스턴스를 사용할때마다 자동적으로 생성될수도 있다. 이것은 언제나 maxTransaction보다 같거나 커야 하고 maxRequests보다 작아야 한다. 동시세션값의 최대치를 줄이면 전체적인 메모리사용량을 줄일수 있다.
예:
maxSessions=”64”
Default: 128
maxTransactions 이것은 한꺼번에 SqlMapClient.startTransaction()에 들어갈수 있는 쓰레드의 최대갯수이다. 셋팅값보다 많은 쓰레드는 다른 쓰레드가 나올때까지 블록된다. 다른 DBMS는 다른 제한을 가진다. 이 값은 언제나 maxSessions보다 작거나 같아야 하고 maxRequests보다 작아야 한다. 종종 동시트랜잭션의 최대치를 줄이면 성능향상을 보여준다.
예:
maxTransactions=”16”
Default: 32

4. sqlMap 예

<?xml version="1.0" encoding="EUC-KR" standalone="no"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"
http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Board">

<!-- DB 컬럼과 OBJECT 맵핑 -->

<resultMap id="boardList" class="spring.mvc.sample.board.model.Board">
<result property="boardNo" column="boardno" />
<result property="name" column="name" />
<result property="title" column="title" />
<result property="createDate" column="createDate" />
<result property="hitCount" column="hitCount" />
</resultMap>

<select id="list" resultMap="Board.boardList">
SELECT boardno, title, name, createdate, hitcount
FROM board
ORDER BY createdate DESC
</select>

</sqlMap>

5. 퍼시스턴스 계층(Persistence Layer)에서의 사용 예

...

public class IbatisWithMysqlBoardDAO extends SqlMapClientDaoSupport implements BoardDAO {

...

public List findBoardList(int currentPage, int countPerPage) throws DataAccessException,SQLException {
List result = null;
String sqlId = "
Board.list";
SqlMapClient sqlMap = this.
getSqlMapClient();
try{
result =
sqlMap.queryForList(sqlId);
}catch(SQLException ex){
throw ex;
}
return result;
}

...

}

Spring - iBatis Integration

스프링 - 아이파티스 연동

[출처] http://www.javabeat.net/articles/52-spring-ibatis-integration-1.html

1) Introduction

iBatis is an object-relational mapping tool (ORM) that simplifies access to database. This article details the steps needed for integrating iBatis with Spring. Through such an integration, objects that are specific to iBatis can utilise all the benefits given by Spring's IOC Container. This is not an introductory article for both Spring and iBatis Frameworks. First-time readers are encouraged to read the Introductory article for Spring in javabeat Introduction to Spring Web Framework to know the preliminary concepts related to Spring.

2) Step-by-Step Procedure for Integration

2.1) Introduction

We are going to create a sample table in the MySql Database and going to access the data within it using Spring-iBatis Integration. The required bundles needed to build and run the sample program are listed below.

  • Spring Distribution
  • MySql Database
  • MySql Database Driver

2.2) Creating tables

Create a table called Jsr which contains relevant information for holding information like name, id, description and specification lead for a Java Specification Request (JSR). Issue the following command in the MySql Client command prompt to create the table,

create table Jsr (JsrId varchar(10), JsrName varchar(50), JsrDescription,  varchar(500), SpecLead varchar(100));

2.3) Creating the Java Equivalent

Now let us create a equivalent Java class for the Jsr table. This class, will contain properties that will map to the column names in the Jsr table. Given here is the complete code listing for the Jsr Java class,

Jsr.java

package javabeat.net.articles.spring.ibatis;public class Jsr {    private String id;    private String name;    private String description;    private String specLead;    public String getId()    {        return id;    }    public void setId(String id)    {        this.id = id;    }    public String getName()    {        return name;    }    public void setName(String name)    {        this.name = name;    }    public String getDescription()    {        return description;    }    public void setDescription(String description)    {        this.description = description;    }    public String getSpecLead()    {        return specLead;    }    public void setSpecLead(String specLead)    {        this.specLead = specLead;    }    public String toString()    {        return "Id = " + id + ", Name = " + name +             ", Description = " + description + ", Lead = " + specLead;     }}

2.4) JsrDao Class

Then, we need to get into the client-facing Dao interface design. This is the interface that clients will be depending on, to perform various database operations like selection of rows, insertion, deletion, updating data etc.

JsrDao.java

package javabeat.net.articles.spring.ibatis;import java.util.List;public interface JsrDao {    public List<Jsr> selectAllJsrs();    public Jsr selectJsrById(String jsrID);    public void insertJsr(Jsr insertJsr);    public void deleteJsr(String jsrId);    public void updateJsr(Jsr jsrWithNewValues);}

2.5) iBatis Mapping File

Jsr.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN""http://www.ibatis.com/dtd/sql-map-2.dtd"><sqlMap>    <typeAlias type = "javabeat.net.articles.spring.ibatis.Jsr" alias = "jsr"/>    <resultMap class = "jsr" id = "result">        <result property = "id" column = "JsrId"/>        <result property = "name" column = "JsrName"/>        <result property = "description" column = "JsrDescription"/>        <result property = "specLead" column = "SpecLead"/>    </resultMap>      <select id = "selectAllJsrs" resultMap = "result">        select * from Jsr    </select>    <select id = "selectJsrById" resultMap = "result" parameterClass = "string">        select * from Jsr where JsrId = #value#    </select>    <insert id = "insertJsr" parameterClass="jsr">        insert into Jsr (JsrId, JsrName, JsrDescription, SpecLead) values (#id#, #name#, #description#, #specLead#)    </insert>    <delete id = "deleteJsr" parameterClass="string">        delete from Jsr where JsrId = #value#    </delete>    <update id = "updateJsr" parameterClass="jsr">        update Jsr set JsrName = #name#, JsrDescription = #description#, SpecLead = #specLead#         where JsrId = #id#    </update></sqlMap>

iBatis mapping file contains the mapping information between a Java class and its corresponding table in the database. Not only does it contain this mapping information, but also it contains many definitions for Named Queries. A Named Query is just a query defined with some name so that it can be reused across multiple modules.

The above Xml file starts with an element called 'typeAlias' which is just a short-name for 'javabeat.net.articles.spring.ibatis.Jsr'. Instead of referencing the fully-qualified name of the Jsr class, now it can be shortly referred as 'jsr' in the other sections of the Xml file. Next comes the mapping information specified in the form of 'resultMap' element where the associations between the Java properties for the corresponding column names are made.

Then, the Named Queries section follows. A query called 'selectAllJsrs' has been defined which is actually a select query. The query string value is manifested in the form of 'select * from Jsr'. By having such a query definition, it can be used elsewhere in the Application just by referring the query identifier. Now, let us choose a query definition that illustrates passing parameters to it. The query identifier 'selectJsrById' needs the JsrId as a parameter using which it can filter the number of rows fetched. This can be represented by using the attribute 'parameterClass'. Here 'string' stands for java.lang.String which means that the parameter is of type String. Similarly there are values like 'int', 'float', etc for java.lang.Integer and java.lang.Float respectively. Inside the query definition, we have the following query string,

select * from Jsr where JsrId = #value#

In the above query string, we have defined a new symbol called 'value'. This is the default symbol name for the parameter and since we have only one parameter it would not cause any problem. The expression '#value#' will be substituted with the values specified at the run-time. (Later we will see how the value gets substituted to the above expression).

Now, let us see a query definition that accepts multiple parameters. In the query definition 'insertJsr', we want the jsr id, jsr name, jsr description and spec lead values to get inserted and we have defined the query string as follows,

insert into Jsr (JsrId, JsrName, JsrDescription, SpecLead) values (    #id#, #name#, #description#, #specLead#)

In the query definition, the value of the parameter value is pointing to 'jsr', which means that during run-time the query string will get translated as follows,

insert into Jsr (JsrId, JsrName, JsrDescription, SpecLead) values (    jsr.getId(), jsr.getName(),jsr.getDescription(), jsr.getSpecLead())

2.6) iBatis Configuration File

The Configuration file for iBatis contains references to various mapping files as well as to the dataSource. But in our case, we would not define any dataSource related information in the Configuration file, but instead we will have it in the Spring Configuration file.

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE sqlMapConfigPUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN""http://www.ibatis.com/dtd/sql-map-config-2.dtd"><sqlMapConfig>    <sqlMap resource="./spring/ibatis/Jsr.xml" /></sqlMapConfig>

2.7) Implementation for JsrDao

We have designed only the client-facing interface in section 2.4. In this section, we shall see the implementation for the same. The following class extends SqlMapClientDaoSupport for getting reference to SqlMapClientTemplate object which simplifies the access to most of the database related operations.

JsrDaoImpl.java

package javabeat.net.articles.spring.ibatis;import java.util.List;import org.springframework.orm.ibatis.SqlMapClientTemplate;import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;public class JsrDaoImpl extends SqlMapClientDaoSupport implements JsrDao {    @Override    public List<Jsr> selectAllJsrs()     {        SqlMapClientTemplate template = getSqlMapClientTemplate();        return (List<Jsr>)template.queryForList("selectAllJsrs");    }    @Override    public Jsr selectJsrById(String jsrID)    {        SqlMapClientTemplate template = getSqlMapClientTemplate();        Object objectJsr = template.queryForObject("selectJsrById", jsrID);        return objectJsr instanceof Jsr ? ((Jsr)objectJsr) : null;    }    @Override    public void insertJsr(Jsr insertJsr)    {        SqlMapClientTemplate template = getSqlMapClientTemplate();        template.insert("insertJsr", insertJsr);	    }    @Override    public void deleteJsr(String jsrId)     {        SqlMapClientTemplate template = getSqlMapClientTemplate();        template.delete("deleteJsr", jsrId);    }    @Override    public void updateJsr(Jsr jsrWithNewValues)    {        SqlMapClientTemplate template = getSqlMapClientTemplate();        template.update("updateJsr", jsrWithNewValues);    }}

All the CRUD operations like select(), delete(), insert(), update() will take the named query object which was previously defined in the Configuration file.

2.8) Spring Configuration File

The Spring configuration that we are going to see has 3 sections. The first section configures a Spring Bean for database access like the data source, the driver class name and username/password information etc. Next we have defined a Factory Bean for reading all the mapping definitions and the named query information in the iBatis Configuration file. This Bean is the 'SqlMapClientFactoryBean' and it references the configuration file 'SqlMapConfig.xml'. The final section is the definition of the JsrDaoImpl bean for client access and it contains references to both the data-source and the sqlMapClientFactoryBean that were declared previously.

spring-ibatis.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd">    <beans>        <bean id="dataSource"         class="org.apache.commons.dbcp.BasicDataSource"         destroy-method="close">            <property name="driverClassName">                <value>com.mysql.jdbc.Driver</value>            </property>            <property name="url">                <value>jdbc:mysql://localhost/test</value></property>            <property name="username"><value>root</value></property>            <property name="password"><value>rootPassword</value></property>    </bean>     <bean id="sqlMapClient"     class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">        <property name="configLocation">            <value>./spring/ibatis/SqlMapConfig.xml</value>        </property>    </bean>    <bean id="jsrDao"     class="javabeat.net.articles.spring.ibatis.JsrDaoImpl">        <property name="dataSource"><ref local="dataSource"/></property>        <property name="sqlMapClient"><ref local="sqlMapClient"/></property>    </bean></beans>

2.9) Client Application

JsrClientApplication.java

package javabeat.net.articles.spring.ibatis;import java.util.List;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframework.core.io.FileSystemResource;import org.springframework.core.io.Resource;public class JsrClientApplication{    public static void main(String[] args)    {        Resource resource = new FileSystemResource(            "./src/spring/ibatis/spring-ibatis.xml");        BeanFactory beanFactory = new XmlBeanFactory(resource);        JsrDaoImpl jsrDao = (JsrDaoImpl)beanFactory.getBean("jsrDao");        System.out.println("Inserting JSR's");        insertJsrs(jsrDao);        System.out.println("Listing all JSR's");        List<Jsr> allJsrs = jsrDao.selectAllJsrs();        for (Jsr aJsr : allJsrs)        {            System.out.println(aJsr);        }        System.out.println("Selecting a JSR by Id 'JSR002'");        Jsr aJsr = jsrDao.selectJsrById("JSR002");        System.out.println(aJsr);        System.out.println("Updating a JSR");        Jsr fourthJsr = allJsrs.get(3);        fourthJsr.setName("Servlets-Updated");        fourthJsr.setDescription("Java Servlets and JSP-Updated");        fourthJsr.setSpecLead("Belkin-Updated");        jsrDao.updateJsr(fourthJsr);        System.out.println("Deleting a JSR");        jsrDao.deleteJsr("JSR004");    }    static void insertJsrs(JsrDaoImpl jsrDao)    {        Jsr newJsr = createJsr("JSR001", "JMX",             "Java Management Extension", "McManus");        jsrDao.insertJsr(newJsr);        newJsr = createJsr("JSR002", "XML",             "XML Parsing Spec", "Rajiv");        jsrDao.insertJsr(newJsr);        newJsr = createJsr("JSR003", "JDO",             "Java Data Objects", "Russell");        jsrDao.insertJsr(newJsr);        newJsr = createJsr("JSR004", "Servlets",             "Java Servlets and JSP", "Belkin");        jsrDao.insertJsr(newJsr);    }    static Jsr createJsr(String id, String name, String description, String specLead)    {        Jsr newJsr = new Jsr();        newJsr.setId(id);        newJsr.setName(name);        newJsr.setDescription(description);        newJsr.setSpecLead(specLead);        return newJsr;    }}

The Client Application in the above case gets a reference to the JsrDao object defined in the Spring Configuration file and makes use of it by testing the various available CRUD operations.

3) Conclusion

This article provided the various introductory details for integrating iBatis with Spring Framework. The procedure for this integration has been explained in depth. This would help the readers to integrate iBatis with Spring framework and thereby allow the objects specific to iBatis to make optimum use of the features available in the Spring framework.

Spring 3 MVC Hello World Example

[출처] http://www.roseindia.net/tutorial/spring/spring3/web/spring-3-mvc-hello-world.html

Getting stated with the Spring 3 MVC by developing first Hello World MVC example. This is the first example of writing first example in Spring MVC. After completing the tutorial you will be able to start developing small applications using Spring MVC.

In this section we will create a new project in Eclipse IDE and will name it "Spring MVC Hello World" application. We are using Spring 3 libraries in the application. You can download the latest Spring 3 framework fromhttp://www.eclipse.org/downloads/.

Let's start application "Spring MVC Hello World " example

Step 1:

Before we start Spring 3.0 at least requires JDK 5. So, make sure you have JDK 5 or above. Open dos prompt if you are using windows and type java -version. This will display the version of Java installed on your machine as shown below:

C:\>java -version
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) Client VM (build 14.0-b16, mixed mode, sharing)
C:\>

If you don't know how to install Java read it athttp://www.roseindia.net/java/index.shtml

Step 2:

Download Eclipse IDE from Eclipse download site athttp://www.eclipse.org/downloads/. find the eclipse.exe in the extracted folder and double click eclipse.exe.

Step 3:

Spring 3.0 MVC JAR files:. Following are the list of JAR files required -

  • commons-logging-1.1.1.jar
  • jstl-1.2.jar
  • spring-asm-3.0.3.RELEASE.jar
  • spring-beans-3.0.3.RELEASE.jar
  • spring-context-3.0.3.RELEASE.jar
  • spring-core-3.0.3.RELEASE.jar
  • spring-expression-3.0.3.RELEASE.jar
  • spring-web-3.0.3.RELEASE.jar
  • spring-webmvc-3.0.3.RELEASE.jar

Step 4:

Let us start with our first Spring 3.0 MVC based application.
Open Eclipse and goto File->New->Dynamic Web Project-(click) wizard screen

After selecting Dynamic Web Project, open wizard screen, Inter Project name


After entering project name press Next; wizard will display the following screen:


After that press Next button


Now press Finish display project structure

Step 5:

Now copy all jar files and put in WebContent->WEB-INF > lib folder. display as


Step 6:

now src->New->other->Select Class and press Next

After press Next Inter Package name "net.roseindia.controllers" and Controller class name "HelloWorldController" and press Finish . after modify "HelloWorldController" as

package net.roseindia.controllers;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.ContextLoaderListener;

@Controller
public class HelloWorldController {
@RequestMapping("/helloworld")
public ModelAndView helloWord(){
String message = "Hello World, Spring 3.0!";
return new ModelAndView("helloworld", "message",message);
}
}

Step 7:

Now select WebContent->WEB-INF->New ->select Folder and Inter Folder name "views" and press Finish. Now create "helloworld.jsp" under WEB-INF->views.

File: WEB-INF/views/helloworld.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring 3.0 MVC Series: Hello World</title>
</head>
<body>
${message}
</body>
</html>

Step 8:

Now create "index.jsp" under WebContent->index.jsp

File:WebContent/index.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring 3, MVC Examples</title>
</head>
<body>
<h1>Spring 3, MVC Examples</h1>
<ul>
<li><a href="forms/helloworld.html">Hello World</a></li>
</ul>
</body>
</html>

Step 9:

Now modify web.xml under WebContent/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd">

<display-name>RoseIndia</display-name>

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/forms/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

Step 9:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:component-scan base-package="net.roseindia.controllers"/>

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

</beans>

Step 10:

After we Add server in project . right click project -> New->server-> select server

Now press Next

Now press Add and set server runtime environment. if exists in local tomcat then press "Browse" and select Tomcat server path otherwise press "Download and Install" .

Now press Finish and press Next.

Now press Add All>> and after press Finish .

Step 11:

Now Run the Project , Right click project ->Run As->Run on Server((Shortcut: Alt+Shift+X, R))

After click "Hello World" Link

Download Source Code

Click here to download source code

Related Tags for Spring 3 MVC hello world, Spring 3.0 Web MVC Example:

Spring DI(Dependency Injection)와 AOP(Aspect Oriented Programming) 맛보기

[출처] http://suecream.tistory.com/entry/Spring-DIDependency-Injection%EC%99%80-AOPAspect-Oriented-Programming-%EB%A7%9B%EB%B3%B4%EA%B8%B0

Spring

Spring이란 무엇인가?엔터프라이즈 어플리케이션에서 필요로 하는 기능을 제공하는 프레임 워크이다.

J2EE에서 제공하는 다양한 기능 뿐만 아니라, DI, AOP와 같은 기능도 지원하고 있다.

특징

1. 스프링은 경량 컨테이너 이다.

스프링은 자바 객체를 담고 있는 컨테이너이다. 스프링은 이들 자바 객체의 생성, 소멸과 같은 라이프 사이클을 관리하며, 스프링으로부터 필요한 객체를 가져와 사용할 수 있다.

2. 스프링은 DI패턴을 지원한다.

스프링은 설정 파일을 통해서 객체간의 의존 관계를 설정할 수 있도록 하고 있다. 따라서 객체는 직접 의존하고 있는 객체를 생성하거나 검색할 필요가 없다.

3. 스프링은 AOP를 지원한다.

스프링은 자체적으로 AOP를 지원하고 있기 때문에 트랜잭션이나 로깅 보안과 같이 여러 모듈에서 공통적으로 필요로 하지만 실제 모듈의 핵심이 아닌 기능들을 분리해서 각 모듈에 적용할 수있다.

4. 스프링은 POJO를 지원한다.

스프링 컨테이너에 저장되는 자바 객체는 특정한 인터페이스를 구현하거나, 클래스를 상속받지 않아도 된다. 따라서 기존에 작성한 코드를 수정할 필요없이 스프링에서 사용할 수 있다.

5. 트랜잭션 처리를 위한 일관된 방법을 제공한다.

JDBC를 사용하든, JTA를 사용하든 또는 컨테이너가 제공하는 트랜잭션을 사용하든, 설정 파일을 통해 트랜잭션 관련 정보를 입력하기 때문에, 트랜잭션 구현에 상관없이 동일한 코드를 여러 환경에서 사용할 수 있다.

6. 영속성과 관련된 다양한 API를 제공한다.

스프링은 JDBC를 비롯하여 iBatis, 하이버네이트등 데이터베이스 처리와 관련하여 널리 사용되는 라이브러리와의 연동을 지원하고 있다.

7. 다양한 API에 대한 연동을 지원한다.

스프링은 JMS, 메일, 스케쥴링등 엔터프라이즈 어플리케이션을 개발하는데 필요한 다양한 API를 설정 파일을 통해서 손쉽게 사용할 수 있도록 하고 있다.

8. 자체적으로 MVC프레임워크를 제공한다.

때문에 스프링만 사용하면 MVC기반의 웹어플리케이션을 어렵지 않게 개발할수 있다.

Spring Framework의 설치와 모듈 구성

1. http://Springframework.org/download 에서 최신 버전을 다운 받는다 (현재: 2.5.6)

2. 압축을 푼다

dist폴더 : 스프링 Jar파일을 포함하고 있는 폴더

lib폴더 : 스프링을 사용하는 필요한 모든 외부 라이브러리를 포함하고 있는 폴더

docs폴더 : 스프링 레퍼런스 및 API Javadoc를 포함하고 있는 폴더

DI(Dependency Injection과 Spring Framework)

객체사이의 의존 관계를 객체끼리 직접하는것이 아니라, 외부 조립기가 수행한다는 개념

의존 관계 처리 방법 3가지

1. 코드에 직접 의존 객체 명시 AbstractDAO dao = new LoginDAO();

2. Factory 패턴이나 JNDI등을 사용해 클래스를 명시 (EJB같은곳에서 사용)

AbstractDAO dao = DAOFactory.create();

3. 외부 조립기를 사용 (Dependency Injection - DI 패턴 ~Inversion of Control)

외부 조립기를 사용하는 이 방법은 불필요한 의존 관계를 없애주는 좋은 방법이다.

DI패턴을 이용하면 직접적으로 객체에 의지 하지 않고 인터페이스에만 의존하게 된다.

DI패턴 적용 두가지 방법

1. 생성자 방식을 이용하여 설정

2. 설정 메소드를 이용하여 설정 (setter)

2. 스프링 설정 파일을 이용하여 의존 관계 설정(applicationContext.xml))

<bean name="writeArticleService"

class="kame.spring.chap01.WriteArticleServiceImpl">

<constructor-arg>

<ref bean="articleDao" />

</constructor-arg>

</bean>

<bean name="articleDao"

class="kame.spring.chap01.MysqlArticleDao">

</bean>

의 의미는

MySqlArticleDao articleDao = new MyArticleDao();

WriteArticleServiceImpl writeArticleService = new WriteArticleServiceImpl (articleDao);

위와 같은 xml 선언을 통해 WriteArticleServiceImpl객체와 MySqlArticleDao객체 사이의 의존 관계를 설정하였다.

//이렇게 설정하면 스프링 컨테이너로 부터 빈 객체를 가져와서 사용 할 수 있다.

Resource resource = new ClassPathResource("applicationContext.xml");

BeanFactory beanFactory = new XmlBeanFactory(resource);

WriteArticleService articleService =

(WriteArticleService) beanFactory.getBean("writeArticleService");

articleService.write(new Article);

이것을 제어 역행이라고 하는데, 스프링 프레임 워크의 핵심이다.

의존성을 띄는 객체를 내가 생성하는 것이 아니라,
내가 주입 받는것이다. 따라서 내가 원래 그 객체를 생성하고 살리고 하는 주제 제어자 였는데,

Dependency Injection에 의하여 내가 주입을 받는 대상자가 되어 버렷다.

따라서 저어가 역행하게 된것이다.

결합된 코드 즉, 밀접하게 연관이 된 코드는 테스트하고 재 사용 시 어려우며 이해하기도 어렵다. 때문에 결합도를 낮추어서 의존하는 객체들 간 협업을 조정하는 책임이 객체 자체로부터 분리되어 나간 을 말한다.

스피링에서 AOP

1. POJO AOP

기존 우리 클래스() 공통적으 사용 필요성 있을

, 트랜잭, 공통 (Common Class, Common Method ) 여러 객체들에 접근하 사용하 일일 생성하 메소드 러서 써야 .

사용자 입력(, , , 개인정보 대하 필드 통해 입력 받을) String객체 암호 프로세스 간단 프로그램 있다 가정할, 각각 정보들 대하 일일 암호화하(동일 암호 알고리즘으..) 프로세스 거쳐 (적절 예인지 모르겠;;) 생성 객체 대하 일일 메소드 넣은 받아 와야 번거로움 생기, 복잡 의존성 불필요하 가지 . 갑작스러 요구 사항 변경으 필드 추가하거, 필드 삭제하 메소드 부르 작업 하거 삭제 해야 . (깜빡하 삭제하 않으 당연 엑셉션 발생하 )

효율 틀림없.

때문 나온 AOP 기법이.

AOP(Aspect Oriented Programming) 관심사항 대하여 발생하 복잡성 중복 해소 프로그래 기법이.

여기 중요 개념 Aspect, Aspect 모듈 로직 구현 클래스 적용된.

(써놓 난해하;;;)

한마디 관심사 관해서 관심사 사용 객체들 관심( ) 접근하 프로그램 복잡도 증가 시키, 코드 중복 시키 결합도 객체지향적이 못해지 요인으 작용하므, 그렇 ( 관심사 사용 놈들 생성해 지지 ) 외부에 이쁘 처리하~! 이말이.

< 관심 클래> - 아래 클래스 우리 관심사로 사용 클래 .

public class LoggingAspect {

private Log log = LogFactory.getLog(getClass());

public Object logging(ProceedingJoinPoint joinPoint) throws Throwable {

log.info("기록시작);

StopWatch stopWatch = new StopWatch();

try {

stopWatch.start();

Object retValue = joinPoint.proceed();

return retValue;

} catch (Throwable e) {

throw e;

} finally {

stopWatch.stop();

log.info("기록종료);

log.info(joinPoint.getSignature().getName() + "메소드실행시간: "

+ stopWatch.getTotalTimeMillis());

}

}

}

그렇다 이놈 일일 사용 객체들에 접근하 어떻 ?

<bean id="logging" class="kame.spring.chap01.LoggingAspect" />

<aop:config>

<aop:pointcut id="servicePointcut" expression="execution(* *..*Service.*(..))" />

<aop:aspect id="loggingAspect" ref="logging">

<aop:around pointcut-ref="servicePointcut" method="logging" />

</aop:aspect>

</aop:config>

이렇 , expression="execution(* *..*Service.*(..))" /> 의해 Service 끝나 인터페이스 구현 객체들 대하 우리 관심 객체 적용 된다.

. . 자세 내용 해보아 . DI AOP맛보기 ~!

( : 최범균님 Spring 2.5 Programming, Spring in Action 이해하 잘되 두책 번갈 보면 공부하 효율적이. 그리 출판사에 나오 서적들 매력 느낀 . . Struts 그랫 . . EJB3.0 그렇 . .)

[JSP/JAVA] 최상위, 파일 경로 알아내기

[출처] http://blog.nachal.com/232
JSP/Servlet 사이트 경로 1 (드라이브:\사이트경로\)
String strRoot=request.getSession().getServletContext().getRealPath("/");
out.println(strRoot);

JSP/Servlet 사이트 경로 2 (드라이브:\사이트경로\)
String strRoot=getServletContext().getRealPath("/");
out.println(strRoot);

JSP/Servlet 특정 페이지 경로
String strRealPath=getServletContext().getRealPath("경로/파일명");
strRealPath=strRealPath.substring(0,strRealPath.lastIndexOf(System.getProperty("file.separator")));
out.println(strRealPath);

JSP/Servlet 현재 페이지 경로
String strRealPath=getServletContext().getRealPath(request.getRequestURI());
strRealPath=strRealPath.substring(0,strRealPath.lastIndexOf(System.getProperty("file.separator")));
out.println(strRealPath);

JAVA - 현재 클래스 경로
this.getClass().getResource("").getPath();


JAVA - 클래스 디렉토리 경로
this.getClass().getResource("/").getPath();

+ Recent posts