Spring Boot : auto-configuration 그리고 debug

Java|2015. 4. 17. 13:39

Spring Boot 애플리케이션의 auto-configuration 정보를 확인하거나 DEBUG 레벨의 로그를 확인하려면 아래와 같이 --debug-Ddebug 옵션을 주면 됩니다.

$ java -jar myapp.jar --debug

그리고 문서에서는 확인이 안되지만 applicaton.properties 파일에, 값 없이 debug 키를 선언해도 됩니다(debug: 혹은 debug=).

debug:
spring.datasource.url: jdbc:hsqldb:file:D:/tmp/hsqldb/scratchdb
spring.jpa.show-sql: true
spring.jpa.generate-ddl: true
spring.jpa.hibernate.ddl-auto: create

이렇게 debug 옵션을 주면 auto-configuration 정보와 사용 중인 framework, library 등의 DEBUG 레벨 로그를 확인할 수 있습니다.

아래는 --debug 옵션과 함께 Spring Data JPA 앱의 테스트케이스를 실행했을 때의 콘솔 로그입니다.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::  (v1.3.0.BUILD-SNAPSHOT)

2015-04-17 13:17:28.927  INFO 5124 --- [           main] c.i.rt.execution.junit.JUnitStarter      : Starting JUnitStarter on envy-i7 with PID 5124 (started by kyutae.park in D:\dev\repos\spring-boot-data-jpa-javaworld)
2015-04-17 13:17:28.928 DEBUG 5124 --- [           main] o.s.boot.SpringApplication               : Loading source class sample.data.jpa.SampleDataJpaApplication
2015-04-17 13:17:29.243 DEBUG 5124 --- [           main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application.yaml' resource not found

    ..............
    .... 중략 ....
    ..............

Hibernate: alter table tb_person_02837_cars add constraint FK_enugsq5f3484moat7h2ggrf1a foreign key (tb_person_02837_id) references tb_person_02837
2015-04-17 13:17:43.191  INFO 5124 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000230: Schema export complete
2015-04-17 13:17:45.352 DEBUG 5124 --- [           main] utoConfigurationReportLoggingInitializer : 


=========================
AUTO-CONFIGURATION REPORT
=========================


Positive matches:
-----------------

   AopAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.context.annotation.EnableAspectJAutoProxy,org.aspectj.lang.annotation.Aspect,org.aspectj.lang.reflect.Advice (OnClassCondition)
      - matched (OnPropertyCondition)

   AopAutoConfiguration.JdkDynamicAutoProxyConfiguration
      - matched (OnPropertyCondition)

   DataSourceAutoConfiguration
      - @ConditionalOnClass classes found: javax.sql.DataSource,org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)

   DataSourceAutoConfiguration.DataSourceInitializerConfiguration
      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer; SearchStrategy: all) found no beans (OnBeanCondition)

   DataSourceAutoConfiguration.JdbcTemplateConfiguration
      - existing auto database detected (DataSourceAutoConfiguration.DataSourceAvailableCondition)

   DataSourceAutoConfiguration.JdbcTemplateConfiguration#jdbcTemplate
      - @ConditionalOnMissingBean (types: org.springframework.jdbc.core.JdbcOperations; SearchStrategy: all) found no beans (OnBeanCondition)

   DataSourceAutoConfiguration.JdbcTemplateConfiguration#namedParameterJdbcTemplate
      - @ConditionalOnMissingBean (types: org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; SearchStrategy: all) found no beans (OnBeanCondition)

   DataSourceAutoConfiguration.NonEmbeddedConfiguration
      - supported DataSource class found (DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition)
      - @ConditionalOnMissingBean (types: javax.sql.DataSource,javax.sql.XADataSource; SearchStrategy: all) found no beans (OnBeanCondition)

   DataSourcePoolMetadataProvidersConfiguration.TomcatDataSourcePoolMetadataProviderConfiguration
      - @ConditionalOnClass classes found: org.apache.tomcat.jdbc.pool.DataSource (OnClassCondition)

   DataSourceTransactionManagerAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.jdbc.core.JdbcTemplate,org.springframework.transaction.PlatformTransactionManager (OnClassCondition)

   DataSourceTransactionManagerAutoConfiguration.TransactionManagementConfiguration
      - @ConditionalOnMissingBean (types: org.springframework.transaction.annotation.AbstractTransactionManagementConfiguration; SearchStrategy: all) found no beans (OnBeanCondition)

   GenericCacheConfiguration
      - Automatic cache type (CacheCondition)

   HibernateJpaAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,org.springframework.transaction.annotation.EnableTransactionManagement,javax.persistence.EntityManager (OnClassCondition)
      - found HibernateEntityManager class (HibernateJpaAutoConfiguration.HibernateEntityManagerCondition)

   HttpEncodingAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.web.filter.CharacterEncodingFilter (OnClassCondition)
      - matched (OnPropertyCondition)

   HttpEncodingAutoConfiguration#characterEncodingFilter
      - @ConditionalOnMissingBean (types: org.springframework.web.filter.CharacterEncodingFilter; SearchStrategy: all) found no beans (OnBeanCondition)

   HttpMessageConvertersAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.http.converter.HttpMessageConverter (OnClassCondition)

   HttpMessageConvertersAutoConfiguration#messageConverters
      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.HttpMessageConverters; SearchStrategy: all) found no beans (OnBeanCondition)

   HttpMessageConvertersAutoConfiguration.StringHttpMessageConverterConfiguration
      - @ConditionalOnClass classes found: org.springframework.http.converter.StringHttpMessageConverter (OnClassCondition)

   HttpMessageConvertersAutoConfiguration.StringHttpMessageConverterConfiguration#stringHttpMessageConverter
      - @ConditionalOnMissingBean (types: org.springframework.http.converter.StringHttpMessageConverter; SearchStrategy: all) found no beans (OnBeanCondition)

   JacksonAutoConfiguration
      - @ConditionalOnClass classes found: com.fasterxml.jackson.databind.ObjectMapper (OnClassCondition)

   JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration
      - @ConditionalOnClass classes found: com.fasterxml.jackson.databind.ObjectMapper,org.springframework.http.converter.json.Jackson2ObjectMapperBuilder (OnClassCondition)

   JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration#jacksonObjectMapperBuilder
      - @ConditionalOnMissingBean (types: org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; SearchStrategy: all) found no beans (OnBeanCondition)

   JacksonAutoConfiguration.JacksonObjectMapperConfiguration
      - @ConditionalOnClass classes found: com.fasterxml.jackson.databind.ObjectMapper,org.springframework.http.converter.json.Jackson2ObjectMapperBuilder (OnClassCondition)

   JacksonAutoConfiguration.JacksonObjectMapperConfiguration#jacksonObjectMapper
      - @ConditionalOnMissingBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found no beans (OnBeanCondition)

   JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration
      - @ConditionalOnClass classes found: com.fasterxml.jackson.databind.ObjectMapper (OnClassCondition)
      - matched (OnPropertyCondition)
      - @ConditionalOnBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found the following [jacksonObjectMapper] (OnBeanCondition)

   JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration#mappingJackson2HttpMessageConverter
      - @ConditionalOnMissingBean (types: org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; SearchStrategy: all) found no beans (OnBeanCondition)

   JpaBaseConfiguration#entityManagerFactory
      - @ConditionalOnMissingBean (types: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; SearchStrategy: all) found no beans (OnBeanCondition)

   JpaBaseConfiguration#entityManagerFactoryBuilder
      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilder; SearchStrategy: all) found no beans (OnBeanCondition)

   JpaBaseConfiguration#jpaVendorAdapter
      - @ConditionalOnMissingBean (types: org.springframework.orm.jpa.JpaVendorAdapter; SearchStrategy: all) found no beans (OnBeanCondition)

   JpaBaseConfiguration#transactionManager
      - @ConditionalOnMissingBean (types: org.springframework.transaction.PlatformTransactionManager; SearchStrategy: all) found no beans (OnBeanCondition)

   JtaAutoConfiguration
      - @ConditionalOnClass classes found: javax.transaction.Transaction (OnClassCondition)
      - matched (OnPropertyCondition)

   MultipartAutoConfiguration
      - @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.multipart.support.StandardServletMultipartResolver,javax.servlet.MultipartConfigElement (OnClassCondition)
      - matched (OnPropertyCondition)

   MultipartAutoConfiguration#multipartConfigElement
      - @ConditionalOnMissingBean (types: javax.servlet.MultipartConfigElement; SearchStrategy: all) found no beans (OnBeanCondition)

   MultipartAutoConfiguration#multipartResolver
      - @ConditionalOnMissingBean (types: org.springframework.web.multipart.MultipartResolver; SearchStrategy: all) found no beans (OnBeanCondition)

   NoOpCacheConfiguration
      - Automatic cache type (CacheCondition)

   PersistenceExceptionTranslationAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor (OnClassCondition)

   PersistenceExceptionTranslationAutoConfiguration#persistenceExceptionTranslationPostProcessor
      - @ConditionalOnMissingBean (types: org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; SearchStrategy: all) found no beans (OnBeanCondition)
      - matched (OnPropertyCondition)

   PropertyPlaceholderAutoConfiguration#propertySourcesPlaceholderConfigurer
      - @ConditionalOnMissingBean (types: org.springframework.context.support.PropertySourcesPlaceholderConfigurer; SearchStrategy: current) found no beans (OnBeanCondition)

   RedisCacheConfiguration
      - Automatic cache type (CacheCondition)

   SimpleCacheConfiguration
      - Automatic cache type (CacheCondition)

   TransactionAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.transaction.support.TransactionTemplate,org.springframework.transaction.PlatformTransactionManager (OnClassCondition)
      - @ConditionalOnSingleCandidate (types: org.springframework.transaction.PlatformTransactionManager; SearchStrategy: all) found a primary candidate amongst the following [transactionManager] (OnBeanCondition)

   TransactionAutoConfiguration#transactionTemplate
      - @ConditionalOnMissingBean (types: org.springframework.transaction.support.TransactionTemplate; SearchStrategy: all) found no beans (OnBeanCondition)

   WebSocketAutoConfiguration
      - @ConditionalOnClass classes found: javax.servlet.Servlet,javax.websocket.server.ServerContainer (OnClassCondition)

   WebSocketAutoConfiguration.TomcatWebSocketConfiguration
      - @ConditionalOnClass classes found: org.apache.catalina.startup.Tomcat,org.apache.tomcat.websocket.server.WsSci (OnClassCondition)

   WebSocketAutoConfiguration.TomcatWebSocketConfiguration#websocketContainerCustomizer
      - @ConditionalOnMissingBean (names: websocketContainerCustomizer; SearchStrategy: all) found no beans (OnBeanCondition)


Negative matches:
-----------------

   ActiveMQAutoConfiguration
      - required @ConditionalOnClass classes not found: javax.jms.ConnectionFactory,org.apache.activemq.ActiveMQConnectionFactory (OnClassCondition)

   AopAutoConfiguration.CglibAutoProxyConfiguration
      - @ConditionalOnProperty missing required properties spring.aop.proxy-target-class  (OnPropertyCondition)

   AtomikosJtaConfiguration
      - required @ConditionalOnClass classes not found: com.atomikos.icatch.jta.UserTransactionManager (OnClassCondition)

   BatchAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.batch.core.launch.JobLauncher (OnClassCondition)

   BitronixJtaConfiguration
      - required @ConditionalOnClass classes not found: bitronix.tm.jndi.BitronixContext (OnClassCondition)

   CacheAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.cache.CacheManager (OnClassCondition)
      - @ConditionalOnBean (types: org.springframework.cache.interceptor.CacheAspectSupport; SearchStrategy: all) found no beans (OnBeanCondition)

   CloudAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.cloud.config.java.CloudScanConfiguration (OnClassCondition)

   DataSourceAutoConfiguration.EmbeddedConfiguration
      - existing non-embedded database detected (DataSourceAutoConfiguration.EmbeddedDataSourceCondition)

   DataSourceAutoConfiguration.TomcatDataSourceJmxConfiguration
      - @ConditionalOnClass classes found: org.apache.tomcat.jdbc.pool.DataSourceProxy (OnClassCondition)
      - existing auto database detected (DataSourceAutoConfiguration.DataSourceAvailableCondition)
      - @ConditionalOnProperty missing required properties spring.datasource.jmx-enabled  (OnPropertyCondition)

   DataSourcePoolMetadataProvidersConfiguration.CommonsDbcpPoolDataSourceMetadataProviderConfiguration
      - required @ConditionalOnClass classes not found: org.apache.commons.dbcp.BasicDataSource (OnClassCondition)

   DataSourcePoolMetadataProvidersConfiguration.HikariPoolDataSourceMetadataProviderConfiguration
      - required @ConditionalOnClass classes not found: com.zaxxer.hikari.HikariDataSource (OnClassCondition)

   DataSourceTransactionManagerAutoConfiguration#transactionManager
      - @ConditionalOnMissingBean (names: transactionManager; SearchStrategy: all) found the following [transactionManager] (OnBeanCondition)

   DeviceDelegatingViewResolverAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver (OnClassCondition)

   DeviceResolverAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.mobile.device.DeviceResolverHandlerInterceptor,org.springframework.mobile.device.DeviceHandlerMethodArgumentResolver (OnClassCondition)

   DispatcherServletAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.web.servlet.DispatcherServlet (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   EhCacheCacheConfiguration
      - required @ConditionalOnClass classes not found: net.sf.ehcache.Cache,org.springframework.cache.ehcache.EhCacheCacheManager (OnClassCondition)

   ElasticsearchAutoConfiguration
      - required @ConditionalOnClass classes not found: org.elasticsearch.client.Client,org.springframework.data.elasticsearch.client.TransportClientFactoryBean,org.springframework.data.elasticsearch.client.NodeClientFactoryBean (OnClassCondition)

   ElasticsearchDataAutoConfiguration
      - required @ConditionalOnClass classes not found: org.elasticsearch.client.Client,org.springframework.data.elasticsearch.core.ElasticsearchTemplate (OnClassCondition)

   ElasticsearchRepositoriesAutoConfiguration
      - required @ConditionalOnClass classes not found: org.elasticsearch.client.Client,org.springframework.data.elasticsearch.repository.ElasticsearchRepository (OnClassCondition)

   EmbeddedServletContainerAutoConfiguration
      - not a web application (OnWebApplicationCondition)

   ErrorMvcAutoConfiguration
      - @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.servlet.DispatcherServlet (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   FacebookAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.social.config.annotation.SocialConfigurerAdapter,org.springframework.social.facebook.connect.FacebookConnectionFactory (OnClassCondition)

   FallbackWebSecurityAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.security.config.annotation.web.configuration.EnableWebSecurity (OnClassCondition)

   FlywayAutoConfiguration
      - required @ConditionalOnClass classes not found: org.flywaydb.core.Flyway (OnClassCondition)

   FreeMarkerAutoConfiguration
      - required @ConditionalOnClass classes not found: freemarker.template.Configuration,org.springframework.ui.freemarker.FreeMarkerConfigurationFactory (OnClassCondition)

   GroovyTemplateAutoConfiguration
      - required @ConditionalOnClass classes not found: groovy.text.markup.MarkupTemplateEngine (OnClassCondition)

   GsonAutoConfiguration
      - required @ConditionalOnClass classes not found: com.google.gson.Gson (OnClassCondition)

   GsonHttpMessageConvertersConfiguration
      - required @ConditionalOnClass classes not found: com.google.gson.Gson (OnClassCondition)

   GuavaCacheConfiguration
      - required @ConditionalOnClass classes not found: com.google.common.cache.CacheBuilder,org.springframework.cache.guava.GuavaCacheManager (OnClassCondition)

   GzipFilterAutoConfiguration
      - required @ConditionalOnClass classes not found: org.eclipse.jetty.servlets.GzipFilter (OnClassCondition)

   HazelcastCacheConfiguration
      - required @ConditionalOnClass classes not found: com.hazelcast.core.HazelcastInstance,com.hazelcast.spring.cache.HazelcastCacheManager (OnClassCondition)

   HornetQAutoConfiguration
      - required @ConditionalOnClass classes not found: javax.jms.ConnectionFactory,org.hornetq.api.jms.HornetQJMSClient (OnClassCondition)

   HypermediaAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.hateoas.Resource,org.springframework.plugin.core.Plugin (OnClassCondition)

   IntegrationAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.integration.config.EnableIntegration (OnClassCondition)

   JCacheCacheConfiguration
      - required @ConditionalOnClass classes not found: javax.cache.Caching,org.springframework.cache.jcache.JCacheCacheManager (OnClassCondition)

   JacksonAutoConfiguration.JodaDateTimeJacksonConfiguration
      - required @ConditionalOnClass classes not found: org.joda.time.DateTime,com.fasterxml.jackson.datatype.joda.ser.DateTimeSerializer,com.fasterxml.jackson.datatype.joda.cfg.JacksonJodaDateFormat (OnClassCondition)

   JacksonHttpMessageConvertersConfiguration.MappingJackson2XmlHttpMessageConverterConfiguration
      - required @ConditionalOnClass classes not found: com.fasterxml.jackson.dataformat.xml.XmlMapper (OnClassCondition)

   JerseyAutoConfiguration
      - required @ConditionalOnClass classes not found: org.glassfish.jersey.server.spring.SpringComponentProvider (OnClassCondition)

   JmsAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.jms.core.JmsTemplate (OnClassCondition)

   JmxAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.jmx.export.MBeanExporter (OnClassCondition)
      - @ConditionalOnProperty expected 'true' for properties spring.jmx.enabled (OnPropertyCondition)

   JndiConnectionFactoryAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.jms.core.JmsTemplate (OnClassCondition)

   JndiDataSourceAutoConfiguration
      - @ConditionalOnClass classes found: javax.sql.DataSource,org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)
      - @ConditionalOnProperty missing required properties spring.datasource.jndi-name  (OnPropertyCondition)

   JndiJtaConfiguration
      - @ConditionalOnClass classes found: org.springframework.transaction.jta.JtaTransactionManager (OnClassCondition)
      - JNDI environment is not available (OnJndiCondition)

   JpaBaseConfiguration.JpaWebConfiguration
      - @ConditionalOnClass classes found: org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   JpaRepositoriesAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.data.jpa.repository.JpaRepository (OnClassCondition)
      - matched (OnPropertyCondition)
      - @ConditionalOnMissingBean (types: org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean,org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension; SearchStrategy: all) found the following [&personRepository, &reviewRepository, &cityRepository, &hotelRepository, &carRepository, org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension#0] (OnBeanCondition)

   LinkedInAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.social.config.annotation.SocialConfigurerAdapter,org.springframework.social.linkedin.connect.LinkedInConnectionFactory (OnClassCondition)

   LiquibaseAutoConfiguration
      - required @ConditionalOnClass classes not found: liquibase.integration.spring.SpringLiquibase (OnClassCondition)

   MailSenderAutoConfiguration
      - required @ConditionalOnClass classes not found: javax.mail.internet.MimeMessage (OnClassCondition)

   MessageSourceAutoConfiguration
      - No bundle found for spring.messages.basename: messages (MessageSourceAutoConfiguration.ResourceBundleCondition)

   MongoAutoConfiguration
      - required @ConditionalOnClass classes not found: com.mongodb.Mongo (OnClassCondition)

   MongoDataAutoConfiguration
      - required @ConditionalOnClass classes not found: com.mongodb.Mongo,org.springframework.data.mongodb.core.MongoTemplate (OnClassCondition)

   MongoRepositoriesAutoConfiguration
      - required @ConditionalOnClass classes not found: com.mongodb.Mongo,org.springframework.data.mongodb.repository.MongoRepository (OnClassCondition)

   MustacheAutoConfiguration
      - required @ConditionalOnClass classes not found: com.samskivert.mustache.Mustache (OnClassCondition)

   RabbitAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.amqp.rabbit.core.RabbitTemplate,com.rabbitmq.client.Channel (OnClassCondition)

   ReactorAutoConfiguration
      - required @ConditionalOnClass classes not found: reactor.spring.context.config.EnableReactor,reactor.core.Environment (OnClassCondition)

   RedisAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.data.redis.connection.jedis.JedisConnection,org.springframework.data.redis.core.RedisOperations,redis.clients.jedis.Jedis (OnClassCondition)

   RepositoryRestMvcAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration (OnClassCondition)

   SecurityAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.security.authentication.AuthenticationManager,org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter (OnClassCondition)

   SendGridAutoConfiguration
      - required @ConditionalOnClass classes not found: com.sendgrid.SendGrid (OnClassCondition)

   ServerPropertiesAutoConfiguration
      - not a web application (OnWebApplicationCondition)

   SitePreferenceAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.mobile.device.site.SitePreferenceHandlerInterceptor,org.springframework.mobile.device.site.SitePreferenceHandlerMethodArgumentResolver (OnClassCondition)

   SocialWebAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.social.connect.web.ConnectController,org.springframework.social.config.annotation.SocialConfigurerAdapter (OnClassCondition)

   SolrAutoConfiguration
      - required @ConditionalOnClass classes not found: org.apache.solr.client.solrj.impl.HttpSolrServer,org.apache.solr.client.solrj.impl.CloudSolrServer (OnClassCondition)

   SolrRepositoriesAutoConfiguration
      - required @ConditionalOnClass classes not found: org.apache.solr.client.solrj.SolrServer,org.springframework.data.solr.repository.SolrRepository (OnClassCondition)

   SpringDataWebAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.data.web.PageableHandlerMethodArgumentResolver,org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   ThymeleafAutoConfiguration
      - required @ConditionalOnClass classes not found: org.thymeleaf.spring4.SpringTemplateEngine (OnClassCondition)

   TwitterAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.social.config.annotation.SocialConfigurerAdapter,org.springframework.social.twitter.connect.TwitterConnectionFactory (OnClassCondition)

   VelocityAutoConfiguration
      - required @ConditionalOnClass classes not found: org.apache.velocity.app.VelocityEngine,org.springframework.ui.velocity.VelocityEngineFactory (OnClassCondition)

   WebMvcAutoConfiguration
      - @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.servlet.DispatcherServlet,org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   WebSocketAutoConfiguration.JettyWebSocketConfiguration
      - required @ConditionalOnClass classes not found: org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer (OnClassCondition)

   WebSocketAutoConfiguration.UndertowWebSocketConfiguration
      - required @ConditionalOnClass classes not found: io.undertow.websockets.jsr.Bootstrap (OnClassCondition)

   XADataSourceAutoConfiguration
      - @ConditionalOnClass classes found: javax.sql.DataSource,javax.transaction.TransactionManager,org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)
      - @ConditionalOnBean (types: org.springframework.boot.jta.XADataSourceWrapper; SearchStrategy: all) found no beans (OnBeanCondition)


Exclusions:
-----------

    None



2015-04-17 13:17:45.388  INFO 5124 --- [           main] c.i.rt.execution.junit.JUnitStarter      : Started JUnitStarter in 23.914 seconds (JVM running for 45.382)
2015-04-17 13:17:45.461 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select count(city0_.id) as col_0_0_ from city city0_
Hibernate: select count(city0_.id) as col_0_0_ from city city0_
2015-04-17 13:17:45.468 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select city0_.id as id1_0_, city0_.country as country2_0_, city0_.map as map3_0_, city0_.name as name4_0_, city0_.state as state5_0_ from city city0_ order by city0_.name asc limit ?
Hibernate: select city0_.id as id1_0_, city0_.country as country2_0_, city0_.map as map3_0_, city0_.name as name4_0_, city0_.state as state5_0_ from city city0_ order by city0_.name asc limit ?
2015-04-17 13:17:45.490 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select count(hotel0_.id) as col_0_0_ from hotel hotel0_ left outer join review reviews1_ on hotel0_.id=reviews1_.hotel_id where hotel0_.city_id=? group by hotel0_.id
Hibernate: select count(hotel0_.id) as col_0_0_ from hotel hotel0_ left outer join review reviews1_ on hotel0_.id=reviews1_.hotel_id where hotel0_.city_id=? group by hotel0_.id
2015-04-17 13:17:45.502 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select hotel0_.city_id as col_0_0_, hotel0_.name as col_1_0_, avg(cast(reviews1_.rating as double)) as col_2_0_ from hotel hotel0_ left outer join review reviews1_ on hotel0_.id=reviews1_.hotel_id inner join city city2_ on hotel0_.city_id=city2_.id where hotel0_.city_id=? group by hotel0_.id order by hotel0_.name asc limit ?
Hibernate: select hotel0_.city_id as col_0_0_, hotel0_.name as col_1_0_, avg(cast(reviews1_.rating as double)) as col_2_0_ from hotel hotel0_ left outer join review reviews1_ on hotel0_.id=reviews1_.hotel_id inner join city city2_ on hotel0_.city_id=city2_.id where hotel0_.city_id=? group by hotel0_.id order by hotel0_.name asc limit ?
2015-04-17 13:17:45.515 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select city0_.id as id1_0_0_, city0_.country as country2_0_0_, city0_.map as map3_0_0_, city0_.name as name4_0_0_, city0_.state as state5_0_0_ from city city0_ where city0_.id=?
Hibernate: select city0_.id as id1_0_0_, city0_.country as country2_0_0_, city0_.map as map3_0_0_, city0_.name as name4_0_0_, city0_.state as state5_0_0_ from city city0_ where city0_.id=?
2015-04-17 13:17:45.520  WARN 5124 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Warning Code: -1003, SQLState: 01003
2015-04-17 13:17:45.520  WARN 5124 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : warning: null value eliminated in set function
2015-04-17 13:17:45.528 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select hotel0_.id as id1_1_, hotel0_.address as address2_1_, hotel0_.city_id as city_id5_1_, hotel0_.name as name3_1_, hotel0_.zip as zip4_1_ from hotel hotel0_ where hotel0_.city_id=? and hotel0_.name=?
Hibernate: select hotel0_.id as id1_1_, hotel0_.address as address2_1_, hotel0_.city_id as city_id5_1_, hotel0_.name as name3_1_, hotel0_.zip as zip4_1_ from hotel hotel0_ where hotel0_.city_id=? and hotel0_.name=?
2015-04-17 13:17:45.530 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select city0_.id as id1_0_0_, city0_.country as country2_0_0_, city0_.map as map3_0_0_, city0_.name as name4_0_0_, city0_.state as state5_0_0_ from city city0_ where city0_.id=?
Hibernate: select city0_.id as id1_0_0_, city0_.country as country2_0_0_, city0_.map as map3_0_0_, city0_.name as name4_0_0_, city0_.state as state5_0_0_ from city city0_ where city0_.id=?
2015-04-17 13:17:45.537 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select review0_.rating as col_0_0_, count(review0_.id) as col_1_0_ from review review0_ where review0_.hotel_id=? group by review0_.rating order by review0_.rating DESC
Hibernate: select review0_.rating as col_0_0_, count(review0_.id) as col_1_0_ from review review0_ where review0_.hotel_id=? group by review0_.rating order by review0_.rating DESC
2015-04-17 13:17:45.543  INFO 5124 --- [       Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7050ad86: startup date [Fri Apr 17 13:17:29 GMT+09:00 2015]; root of context hierarchy
2015-04-17 13:17:45.548  INFO 5124 --- [       Thread-1] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'

Process finished with exit code 0

조금 길지만 auto-configuration에 관한 내용을 찬찬히 읽어 보면 어떻게 앱이 자동 설정되었는지 확인할 수 있습니다.

EOF

댓글()

Spring Data JPA - LazyInitializationException

Java|2015. 4. 14. 10:00

개요

요즘 Spring Boot 저장소에 있는 Spring Data JPA 샘플 프로젝트를 살펴 보고 있습니다.

테스트 코드를 작성하면서 하나하나 파악하고 있는데, OneToMany로 엮인 다른 엔티티의 목록을 가져오려고 하면 아래와 같은 오류가 발생합니다.

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: kr.co.javaworld.jpa.domain.Person.cars, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
    at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:155)
    at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:278)
    at org.hamcrest.collection.IsCollectionWithSize.featureValueOf(IsCollectionWithSize.java:21)
    at org.hamcrest.collection.IsCollectionWithSize.featureValueOf(IsCollectionWithSize.java:14)
    at org.hamcrest.FeatureMatcher.matchesSafely(FeatureMatcher.java:40)
    at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55)
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:12)
    at org.junit.Assert.assertThat(Assert.java:956)
    at org.junit.Assert.assertThat(Assert.java:923)
    at kr.co.javaworld.jpa.service.PersonRepositoryIntegrationTests.testFindCars(PersonRepositoryIntegrationTests.java:46)
    ..............
    .... 중략 ....
    ..............
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)

늦은 초기화(Lazy initialization)에 관련된 예외 상황인데, 이에 대한 해결 방법을 정리해 봅니다.

예외가 발생하는 코드

아래의 테스트 코드를 실행하던 중 예외가 발생했습니다. testFindCars 메소드는 Person 객체를 하나 찾은 후, 다시 그 Person이 가진 Car 목록을 조회하는 테스트 코드입니다.

Person.getCars() 호출 후 목록(cars)의 크기를 얻으려고 하니까(assertThat(cars, hasSize(4))) 오류가 발생했습니다.

package kr.co.javaworld.jpa.service;

import kr.co.javaworld.jpa.domain.Car;
import kr.co.javaworld.jpa.domain.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import sample.data.jpa.SampleDataJpaApplication;

import javax.transaction.Transactional;
import java.util.List;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
public class PersonRepositoryIntegrationTests {

    @Autowired
    PersonRepository repository;

    ..............
    .... 중략 ....
    ..............

    @Test
    public void testFindCars() {
        Person person = repository.findOne(1L);
        List<Car> cars = person.getCars();

        assertThat(cars, hasSize(4));
        assertThat(cars.get(0).getName(), is("Mercedes"));
    }
}

Person 엔티티의 코드입니다.
cars@OneToMany annotation이 붙어있을 뿐 특별한 점은 없습니다.

package kr.co.javaworld.jpa.domain;

import javax.persistence.*;
import java.util.List;

@Entity
@Table(name = "TB_PERSON_02837")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "PERSON_NAME", length = 100, unique = true, nullable = false)
    private String name;

    @OneToMany
    private List<Car> cars;

    ..............
    .... 중략 ....
    ..............

}

해결 방법

@OneToMany로 엮을 경우 JPA는 늦은 초기화를 통해 Personcars 목록을 가져오는게 기본 설정입니다. 즉, 위 코드의 @OneToMany annotation 선언은 @OneToMany(fetch = FetchType.LAZY)로 대체해도 동일합니다.

따라서 해결 방법은 간단합니다. 패치 타입을 FetchType.EAGER로 변경하여 늦은 초기화 대신 이른 초기화(Eager initialization)를 사용하면 됩니다.

아래 코드와 같이 @OneToMany(fetch = FetchType.EAGER)로 annotation 선언을 변경해 주면 오류가 사라집니다.

package kr.co.javaworld.jpa.domain;

import javax.persistence.*;
import java.util.List;

@Entity
@Table(name = "TB_PERSON_02837")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "PERSON_NAME", length = 100, unique = true, nullable = false)
    private String name;

    @OneToMany(fetch = FetchType.EAGER)
    private List<Car> cars;

    ..............
    .... 중략 ....
    ..............

}

다른 해결 방법

앞서의 해결 방법은 People 엔티티를 얻어 올 때는 언제나 Car 목록도 함께 가져오도록 강제합니다. 따라서 가끔씩만 Car 목록이 필요하다면 불필요한 메모리 낭비나 서버 성능 저하 등의 문제가 발생할 수 있습니다.

늦은 초기화를 사용하면서도 문제를 해결하려면 아래와 같이 트랜잭션을 Person.getCar() 호출 후 관련 동작을 완료할 때까지 유지하면 됩니다.

아래에서는 testFindCars 메소드에 @Transactional annotation을 붙여서 메소드 전체를 하나의 트랜잭션으로 감쌌습니다.

실무에서는 서비스 클래스의 메소드 단위로 트랜잭션을 잡아 주거나, 뷰 단의 서블릿 필터에서 UserTransaction을 이용하여 요청 단위로 트랜잭션을 처리하는 방법을 사용하면 됩니다.

package kr.co.javaworld.jpa.service;

import kr.co.javaworld.jpa.domain.Car;
import kr.co.javaworld.jpa.domain.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import sample.data.jpa.SampleDataJpaApplication;

import javax.transaction.Transactional;
import java.util.List;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
public class PersonRepositoryIntegrationTests {

    @Autowired
    PersonRepository repository;

    ..............
    .... 중략 ....
    ..............

    @Test
    @Transactional
    public void testFindCars() {
        Person person = repository.findOne(1L);
        List<Car> cars = person.getCars();

        assertThat(cars, hasSize(4));
        assertThat(cars.get(0).getName(), is("Mercedes"));
    }
}

EOF

댓글()

PuTTY로 Amazon EC2 인스턴스 접속하기

Developer Tools|2015. 4. 2. 10:00

PuTTYgen 내려 받기

EC2 인스턴스에 PuTTY를 이용해 접속하려면, Key Pair 파일(.pem)을 .ppk 파일로 변환해야 합니다.

.ppk 파일은 PuTTYgen(PuTTY Key Generator)을 이용해서 생성 할 수 있습니다.
아래 링크에서 PuTTYgen을 내려받습니다.

PuTTY Download Page

바로 내려받기

설치 없이 바로 실행하여 사용할 수 있습니다.

Amazon Key Pair(.pem)를 PuTTY Private Key File(.ppk)로 변환

PuTTYgen을 실행한 후 상단 메뉴에서, Conversions > Import key를 클릭합니다.

Load private key 창이 열리면 .pem 파일을 찾아서 엽니다.


Key Pair에 대한 정보가 로딩되면 Save private key를 클릭합니다.


passphrase 없이 키를 저장할 것인지 물어봅니다. 예(Y)를 클릭하여 수락합니다.


Save private key as 창이 열리면, 원하는 경로와 이름을 지정한 후 ppk 파일을 저장합니다.
여기에서는 바탕화면에 aws_hbase.ppk로 저장했습니다.


PuTTY에서 ppk 파일 사용하기

PuTTY 설정창(PuTTY Configuration)의 Category에서 Connection > SSH > Auth로 이동한 후, Browse를 클릭합니다.


위에서 저장한 ppk 파일을 선택합니다.


ppk 파일 선택이 완료됐습니다.


이제 Session Category로 이동한 후 Host Name에 EC2 인스턴스의 주소를 입력한 후 Open을 클릭하여 접속하면 됩니다.


댓글()