2022.11.24-1 JAVA 라이브러리와 모듈
10. 라이브러리와 모듈
10.1 라이브러리
라이브러리는 프로그램 개발 시 활용할 수있는 클래스와 인터페이스들을 모아 놓은것을 말한다.
다른 사람도 사용해야하는 것 클래스나 인터페이스를 내가 나중에 또 재사용하려면 효율적으로 만들어놓는게 좋다.
예를들어 클래스 100개만들었을때 파일별로 100개보단 기능별로 쪼개서 묶음처리 하는게 낫다.
라이브러리나 모듈로 만들어서 다른패키지에서 사용하는게 낫다.
재사용을 더 편리하게 하는법. 다른사람이 만든 걸 가져오는 법. 활용하는 법을 알기위해 사용

도서관처럼 보관하고 있다가 필요한 시점에 가져다가 사용
여러개의 클래스 인터페이스를 기능별로 묶어 놓은 것.
JAR라는 자바 압축파일로 묶여있음.
필요한걸 가져다 사용하면 개발기간단축
여러프로젝트에서 공통적으로 사용하는 경우가 많음.
my_lib 라이브러리 프로젝트 생성
새로운 프로젝트 만들어서 라이브러리 생성함.
package pack1;
public class A {
//필드 생성자 메소드
public void method() {
System.out.println("A-methond 실행");
}
}
package pack2;
public class B {
//필드 생성자 메소드
public void method() {
System.out.println("B-methond 실행");
}
}
my_lib 새로운 프로젝트 만들고 패지지로 jar파일 생성


y_application_1 새로운프로젝트생성해서 jar파일 가져오기
우클릭 Build path 빌드와 컴파일이 뭐가ㅏ 다른가?
컴파일은 소스 단위로 기계어
빌드는 프로젝트 단위 프로젝트 전체를 컴파일 하거나 새로운 디렉토리를 만들고 필요로하는 외부라이브러리잇으면
사용할수잇게 설정 하나의 애플리케이션을 최종산출물로 만드는과정이 빌드이다.
build path - configure build path
source-소스파일이 있다. 컴파일해야한다.
project , library 외부의 것을 가져와서 쓰겟냐?
library- add external jars
Referenced Libraries생기고 pack1 class A pack2 class B 생김

package app;
import pack1.A;
import pack2.B;
public class Main {
public static void main(String[] args) {
A a = new A(); // 컨트롤 시프트 O
a.method();
B b = new B();
b.method();
}
}
10.2 모듈
라이브러리랑 비슷하게 jar파일로 저장됨.
java9부터 지원하며 라이브러리보다는 좀 더 많은 기능을 제공함.
모듈은 패키지 관리 기능까지 포함된 라이브러리이다.
일반 라이브러리 전부다 사용가능. 모듈 어떤 패키지는 사용가능 어떤건 불가능하게
a모듈 패키지a 사용가능 패키지2사용가능 패키지3 은닉

의존관계설정도 가능
모듈a -> 모듈b -> 모듈c 모듈a가 잘되려면 b와c가 필요하다는 걸 알려줄수잇다.
모듈기술자 module-info.java에 기술할 수 잇기땜에 의존관계를 쉽게 파악할 수잇다.
물리적인 형태는 jar파일 형태로 라이브러라와 같고 모듈기술자가 포함되어잇다면 모듈임.
직접 작성하기도 하지만 모듈을 결합해서 응용프로그램을 만들수도 잇다.
대규모의 기능은 나누어 개발하기 위해 각 기능을 모듈화 시켜 만들고 최종에는 레고처럼 합쳐서 만듬.
하나의 모듈들이 각 프로젝트가 되어서 개발하는거임 모둘별로 개발하고 조립하면 좋다.

10.3 응용프로그램 모듈화
my_application_2를 만들고싶은데 기능이 너무많아서 my_moudle_a 와 my_moudle_b로 나눠 개발
따로 개발하고 결합해서 app을 만듬

my_module_a, my_module_b을생성
모듈도 프로젝트임 new project 에서 맨밑 create module-info.java file 눌러서 모듈기술서를 생성해줌.
모듈만들면 모듈 기술서 자동으로 생김 exports => 공개하겠다.
//모듈 a
module my_module_a {
exports pack1;
exports pack2;
}
//모듈 b
module my_module_b {
exports pack3;
exports pack4;
}
모듈ab를 사용하는 my_application_2만들기 new 프로젝트 - my_application_2
my_application_2도 a와 b를 의존하고 잇기때문에 모듈기술자를 만들어줘야해서 모듈로 만들어야함.
.jar일때는 library 들어가서 jar부르기
exports 를 안쓰면 은닉이 되어서 사용불가. 사용할수있게하려면 exports를 붙이자.
requires 는 의존한다는 것을 나타내줌

module my_application_2 {
requires my_moudle_a;
requires my_moudle_b;
}
뭘 참조하는지 몰라서 오류가뜸
라이브러리 추가할때처럼 Build path해줘야함.
jar파일로 할수도잇지만 현재는 프로젝트이니 project의 Module path에서 add하기

package app;
import pack1.A;
import pack2.B;
import pack3.C;
import pack4.D;
public class Main {
public static void main(String[] args) {
A a = new A();
a.method();
B b = new B();
b.method();
C c = new C();
c.method();
D d = new D();
d.method();
}
}

10.4 모듈 배포용 jar파일
프로젝트 형태로 존재하는 파일을 jar로 만들기
라이브러리만들듯이 dist파일생성 export jar파일 생성
옆에 class path 나 project넣을 필요없음.>얘들은 이클립스 프로젝트로 인식되기 위한거
jar파일안에는 모듈기술자에 대한 바이트파일, 모듈a, b에 대한 바이트파일만 있으면됨.

물리적으로 같으나 module info가잇으면 모듈임
my_application_3 생성
build path 들어가서 library- add external jar 해서 넣어주기.
my_application_3은 jar파일 받아서 참조함. 이것은 오픈소스 jar를받앗다면 이렇게 해야함.
my_application_2는 내가 만드는 프로젝트가 너무커서 모듈을 만들어 조립을 할대사용하는데
다른 프로젝트를 수정하면 my_application_2에서도 수정이 되기때문에 프로젝트로 햇던게 더 편할수잇음.
상황마다 필요한게 다르다.
10.5 패키지 은닉
module my_module_a {
exports pack1;
// exports pack2;
이렇게 exports를 포함하지 않으면 패키지가 은닉이된다.

패키지 은닉하는 이유?
1.모듈 사용방법 통일
모듈 외부에서 패키지 2와 3을 사용하지 못하도록 막고 패키지1로 사용방법을 통일한다.
pack1을 인터페이스라고 생각하면 pack2 pack3이 달라져도 문제가 안생김
pack1에서 pack2-2로 수정가능
외부에서는 결국 pack1를 부르는 코드가 바뀌는게 아니기때문에 유지보수가 더좋다.
직접 pack2를 사용하다가 pack2-2가 되면 오류가됨.
pack2와 pack3를 은닉하고 외부에서는 pack1만 사용하게 하면 문제가 생기지 않을 것임.
2.쉬운수정
모듈 성능 향상을 위해 패키지2와 3을 수정하더라도 모듈 사용방법 패키지1이 달라지지 않기 때문에 외부에 영향을 주지않음.
쉽게 은닉개체를 바꿀수잇고 pack1만 안바뀌면됨.
library는 다 수정해야되서 어려움. 모듈이 이런점에서 장점이 있음.
10.6 전의 의존
현재 my_application_2가 my_moudle_a와 my_moudle_b를 각각 의존하고잇음.
이관계를 my_application_2 -> my_moudle_a -> my_moudle_b
a가b를의존하게 만들면? a를만들때 b를쓰고 다시 my_application_2 a를의존하면
my_application_2가 b를 직접사용이 불가능함. 경우에따라 직접사용하고 싶으면 어떻게 해야하는가

module my_module_a{
exports pack1;
requires transitive my_module_b;
//transitive 전이 될수 있다.
my_application_2{
requires my_module_a;
이렇게 짜면 my_application_2에서 a도 사용하고 b도 사용할 수 있게 된다.
package pack1;
import pack2.B;
import pack3.C;
public class A {
//필드 생성자 메소드
public void method() {
System.out.println("A-methond 실행");
//b객체 생성
B b = new B();
b.method();
}
//메소드 메소드의 리턴값으로 c를 얻기
public C getC() {
C c = new C();
return c;
}
}
module my_application_2 {
requires my_module_a;
// requires my_module_b; b를 사용못함에도 불구하고 b에 존재하는걸 사용할수 있게됨
}
package app;
import pack1.A;
import pack3.C;
import pack4.D;
public class Main {
public static void main(String[] args) {
A a = new A();
a.method();
C c = new C();
c.method();
D d = new D();
d.method();
}
}

10.7 집합모듈
무언가가 집합적으로 들어간 모듈 == 여러모듈을 모아놓은 무언가
왜 만드나? 어떤 app을만드는 데 모듈이 100개가잇음
100개가 대부분 필요한데 필요할때마다 requires 하면 매우 귀찮아짐.
따라서 transitive를 전부다 넣어줌
module my_module{
requires transitive my_module_a;
requires transitive my_module_b;}
my_module은 집합 모듈임 모듈기술자만 있고 패키지도 없고 아무것도 없음.
자주사용되는 모듈들을 묶어 놓고 전이시켜서 사용할수잇게함.
module my_application_2 {
requires my_module;
//requires my_module_a;
//requires my_module_b;
이거만해도 다 사용하는 느낌이됨. 빌드패스에서는 다 넣어주자.
10.8 리플렉션 허용
아직 배우지 않은 용어
어떤 클래스에 어떤필드가잇고 어떤생성자가잇고 어떤 메소드가 잇는지를 조사하는것.
이걸알아야 하는 이유? 프로그램이 판단 outline에 나옴 이것이 리플렉션

그런데? 모듈에서 모든 패키지를 허용해야하나?
패키지 은닉한경우 보이면 안됨.
그러나 은닉되어잇어도 리플렉션을 허용하고싶다?(잘 사용은 안함.)
모듈 선언시 open module 모듈명{} 하면 리플렉션됨
리플렉션 허용한다고 사용할 수 있다는 것은 아님!
지정한 패키지에 리플렉션 허용
module 모둘명 {
opens 패키지1
opens 패키지2}
지정된 패키지에 대해 특정 외부 모듈에서만 리플렉션허용
module 모둘명 {
opens 패키지1 to 외부모듈명, 외부모듈명
opens 패키지2}
10.9 자바 표준 모듈
자바 프로그램이라면 반드시 활용해야하는 라이브러리가 잇다.
바로 JDK가 제공하는 표준 라이브러리이다. 자바언어가 기본적으로 제공해주는 거임!

java9부터 모듈화가 되어 java17표준모듈이 완성되었다.
java.se모듈로부터 모든 것이 의존되어있다! java.se = 집합모듈임
module my_application{ requires java.se; }만 해줘도 집합모듈이기에 모든 모듈 사용가능함

2022.11.24 리뷰
까먹고 안적을 뻔했다.
라이브러리와 모듈은 프로그램을 짤때 확실히 편하게 짤 수있는 것같다.
블로그 작성을 하기 위해 이클립스를 켰는데 워크스페이스를 읽지 못하고 프로젝트도 아예 읽지 못하는 버그가 발생했다.
https://bluesocketfactory.blogspot.com/2015/02/blog-post_5.html
구글링을 통해 블로그를 찾아 해결하였다.
중요한 것은 꺾이지 않는 마음