- imbedded tomcat 에 jndi 적용

https://jforj.tistory.com/128
1. build.gradle 에

org.apache.commons:commons-dbcp2 dependency 추가

2. resource 설정 클래스 JndiResource 생성

@Configuration
public class JndiResource {
	@Bean
	TomcatServletWebServerFactory tomcatFactory() {
		return new TomcatServletWebServerFactory() {
			@Override
			protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
				tomcat.enableNaming();
				return super.getTomcatWebServer(tomcat);
			}
			
			@Override
			protected void postProcessContext(Context context) {
				context.getNamingResources().addResource(getResource());
			}
		}
	}
	
	public ContextResource getResource() {
		ContextResource resource = new ContextResource();
		resource.setName("jndi/mysql"); // 사용될 jndi 이름
		resource.setType("javax.sql.DataSource");
		resource.setAuth("Container");
		resource.setProperty("factory", "org.apache.commons.dbcp2.BasicDataSourceFactory");
		
		// datasource 정보
		resource.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
		resource.setProperty("url", "jdbc:mysql://localhost:3306/test?serverTimezone=UTC");
		resource.setProperty("username", "root");
		resource.setProperty("password", "root");
		return resource;
	}
}

3. applicaion.properties 에
spring.datasource.jndi-name: jndi/mysql

 

- external tomcat 에 jndi 적용

https://pkguma.tistory.com/269
https://solbel.tistory.com/284
0. external war 로 build 하도록 설정

1. application.properties 에
spring.datasource.jndi-name:jndi/mysql

2. tomcat server.xml 에 Resource 추가

<GlobalNamingResources>
	...
	<Resource auth="Container"
		name="jdbc/mysql"
		driverClassName="com.mysql.jdbc.Driver"
		type="javax.sql.DataSource"
		maxActive="8" maxIdle="8" maxWait="-1"
		url="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"
		username="root"
		password="root" />
</GlobalNamingResource>

3. tomcat web.xml에 ResourceLink 추가

<Context>
...
	<WatchedResource>...
	<ResourceLink name="jdbc/mysql"
		global="jdbc/mysql"
		auth="Container"
		type="javax.sql.DataSource" />
</Context>

 

에러 해석

1. 

jndi 는 오타 등으로 Resource 정보가 잘못되었을 때 아래와 같이 DataSourceLookupFailureException 에러를 뱉었다.

jndi Resource 자체가 오타로 제대로 생성되지 않았을 경우에도 LookupFailure Exception을 던져서 해석하기 어려웠다.

[org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/JndiDataSourceAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name 'jdbc/mysql'; nested exception is javax.naming.NameNotFoundException: Name [jdbc/mysql] is not bound in this Context. Unable to find [jdbc].

 

@참고(JSP에서 DB연동하기 - JNDI, DBCP 이용): https://all-record.tistory.com/104

블로그 이미지

uchacha

개발자 일지

,