spring batch 뜬금포 에러 

문제 

spring batch 를 테스트 하고 있는데 아래와 같은 뜬금없는에러 발생. 

에러 내용

java.lang.IllegalStateException: Failed to deserialize object type
	at org.springframework.util.SerializationUtils.deserialize(SerializationUtils.java:73)
	at org.springframework.batch.core.repository.dao.MapJobExecutionDao.copy(MapJobExecutionDao.java:50)
	at org.springframework.batch.core.repository.dao.MapJobExecutionDao.saveJobExecution(MapJobExecutionDao.java:60)
	at org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:149)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1427)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean$1.invoke(AbstractJobRepositoryFactoryBean.java:181)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	at com.sun.proxy.$Proxy60.createJobExecution(Unknown Source)
	at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:131)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1427)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	at com.sun.proxy.$Proxy77.run(Unknown Source)
	at com.penta.job.jobs.QuartzJob.executeInternal(QuartzJob.java:52)
	at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75)
	at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: java.lang.ClassNotFoundException: org.springframework.batch.core.JobParameter
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	at java.lang.Class.forName0(Native Method)

 

원인 

이클립스에서  톰캣 재기동 없이 웹어플리케이션를 개발할려고 개발 중간에 spring-loaded 를 적용 시켰는데  

이 모듈 적용후 위와 같은 에러가 발생. 

 

해결.

spring-loaded 설정을 제거 하면 해결. 

-javaagent:C:/zzz/springloaded-1.2.8.RELEASE.jar -noverify

 위 부분 제거. 

문제 

spring batch quartz 설정중에 . jndiURl로 설정하면  spring-batch-infrastructure.jar (org.springframework.batch.support.DatabaseType)에서 지원하지 않는 DB는 아래와 같이 오류가 발생한다. 

java.lang.IllegalArgumentException: DatabaseType not found for product name: [CUBRID]
	at org.springframework.batch.support.DatabaseType.fromProductName(DatabaseType.java:82)
	at org.springframework.batch.support.DatabaseType.fromMetaData(DatabaseType.java:121)

1차 문제 해결 

import javax.sql.DataSource;

import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;

@Configuration
@EnableBatchProcessing
public class BatchConfigurer extends DefaultBatchConfigurer {
	
	@Autowired
	@Qualifier("datasource")
	private DataSource dataSource;
	
	@Autowired
	@Qualifier("dataSourceTx")
	private PlatformTransactionManager transactionManager;

	public BatchConfigurer() {
		super();
	}

	@Override
	protected JobRepository createJobRepository() throws Exception {
		JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
		factory.setDataSource(dataSource);
		factory.setDatabaseType("H2"); // 지원하지 않는 DB와 유사한 지원되는 DB를 지정해준다. 
		factory.setTransactionManager(transactionManager);
		factory.afterPropertiesSet();
		return factory.getObject();
	}

}

 

2차 문제  

quartz  만 사용해서 batch 를 사용하려고 했는데 jndi 를 사용하니 quartz db & batch 관련 db까지 만들어서 사용하는 문제가 발생

Caused by: cubrid.jdbc.driver.CUBRIDException: Syntax: Unknown class "batch_job_instance". select JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE whe...[CAS INFO-192.168.56.101:30000,2,3728],[SESSION-13900],[URL-jdbc:cubrid:192.168.56.101:30000:pencake:pencake:********:].
	at cubrid.jdbc.jci.UConnection.createJciException(UConnection.java:2220)
	at cubrid.jdbc.jci.UInputBuffer.<init>(UInputBuffer.java:117)
	at cubrid.jdbc.jci.UConnection.send_recv_msg(UConnection.java:1785)
	at cubrid.jdbc.jci.UConnection.send_recv_msg(UConnection.java:1797)
	at cubrid.jdbc.jci.UConnection.prepareInternal(UConnection.java:997)
	at cubrid.jdbc.jci.UConnection.prepare(UConnection.java:1035)
	at cubrid.jdbc.jci.UConnection.prepare(UConnection.java:1016)
	at cubrid.jdbc.driver.CUBRIDConnection.prepare(CUBRIDConnection.java:642)
	at cubrid.jdbc.driver.CUBRIDConnection.prepare(CUBRIDConnection.java:811)
	at cubrid.jdbc.driver.CUBRIDConnection.prepareStatement(CUBRIDConnection.java:162)
	at org.apache.tomcat.dbcp.dbcp2.DelegatingConnection.prepareStatement(DelegatingConnection.java:302)
	at org.apache.tomcat.dbcp.dbcp2.DelegatingConnection.prepareStatement(DelegatingConnection.java:302)

 

2차 해결 

이렇게 하면 batch 테이블을 체크 하지 않음. 

package com.ytech.gain.app.job.config;

import javax.sql.DataSource;

import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;

@Configuration
@EnableBatchProcessing
public class BatchConfigurer extends DefaultBatchConfigurer {
	
	@Autowired
	@Qualifier("datasource")
	private DataSource dataSource;
	
	@Autowired
	@Qualifier("dataSourceTx")
	private PlatformTransactionManager transactionManager;

	public BatchConfigurer() {
		super();
	}

	@Override
	protected JobRepository createJobRepository() throws Exception {
		JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
		factory.setDataSource(dataSource);
		factory.setDatabaseType("H2"); // 지원하지 않는 DB와 유사한 지원되는 DB를 지정해준다. 
		factory.setTransactionManager(transactionManager);
		factory.afterPropertiesSet();
		return factory.getObject();
	}
	
    // 이부분을 추가
	@Override
	public void setDataSource(DataSource dataSource) {
		//super.setDataSource(dataSource);
	}
}

 

스프링 시큐리티 alwaysRemember  = false

설정 내용

  http.rememberMe()
               .key(REMEMBERME_KEY)
               .rememberMeParameter(REMEMBERME_PARAMETER)
               .rememberMeCookieName(REMEMBERME_COOKIENAME)
               .tokenValiditySeconds(60 * 60 * 24 * 7)
               .alwaysRemember(false)
               .tokenRepository(rememberMeTokenRepository)
               .userDetailsService(rememberMeUserService).and();

 

문제

checkbox에 체크를 하고 안하고 에 대해서 rememberme 가 작동하고 안하고 해야하는데 작동을 하지 않아서 원일을 찾아본결과 

login.html코드

<form name="f" action="/login" method="post"	class="form-signin" role="form" onsubmit="return false;">

	<input class="form-control"  name="login_id" type="text" placeholder="<spring:message code="login.form.id"/>" style="margin-bottom:5px;"	autofocus autocomplete="off">
	<input class="form-control"  name="login_password" type="password" placeholder="<spring:message code="login.form.pw"/>" value="">
	<div class="checkbox" style="margin-bottom:13px;">
		<label style="padding-top:5px;">
			<input type="checkbox" id="varsqlRememberMe" name="varsqlRememberMe" value="remember"> Remember me
		</label>
	</div>
	<div style="padding-bottom:10px;">
		<button class="btn btn-lg btn-primary btn-block btn-login" type="button">
			<spring:message code="btn.login" />
		</button>
	</div>

</form>

원인

checkbox 의 value에 값이 있어서 발생한 문제 .

<input type="checkbox" id="varsqlRememberMe" name="varsqlRememberMe" value="remember"> Remember me

해결방안

checkbox 에 value를 삭제 하거나  value="on" 이렇게 추가하면 작동함. 

 

에러 내용. 

Caused by: java.lang.IllegalArgumentException: Can not set rememberMeCookieName and custom rememberMeServices.
	at org.springframework.security.config.annotation.web.configurers.RememberMeConfigurer.validateInput(RememberMeConfigurer.java:306)
	at org.springframework.security.config.annotation.web.configurers.RememberMeConfigurer.init(RememberMeConfigurer.java:270)
	at org.springframework.security.config.annotation.web.configurers.RememberMeConfigurer.init(RememberMeConfigurer.java:80)
	at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:370)
	at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:324)
	at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:41)
	at org.springframework.security.config.annotation.web.builders.WebSecurity.performBuild(WebSecurity.java:292)
	at org.springframework.security.config.annotation.web.builders.WebSecurity.performBuild(WebSecurity.java:79)
	at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:333)
	at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:41)
	at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:104)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
	... 27 common frames omitted

설정 내용. 

private void configureRememberMe(HttpSecurity http) throws Exception {
        http.rememberMe()
               .key(REMEMBERME_KEY)
               .rememberMeParameter(REMEMBERME_PARAMETER)
               .rememberMeCookieName(REMEMBERME_COOKIENAME)
               .rememberMeServices(persistentTokenBasedRememberMeServices())
               .tokenValiditySeconds(60 * 60 * 24 * 7)
               .alwaysRemember(true)
               .tokenRepository(rememberMeTokenRepository)
               .userDetailsService(rememberMeUserService);
	}


    @Bean
   	public PersistentTokenBasedRememberMeServices persistentTokenBasedRememberMeServices() {
   	    PersistentTokenBasedRememberMeServices persistenceTokenBasedservice = new PersistentTokenBasedRememberMeServices(REMEMBERME_KEY, userDetailsService(), rememberMeTokenRepository);
   	    persistenceTokenBasedservice.setParameter(REMEMBERME_PARAMETER);
   	    persistenceTokenBasedservice.setAlwaysRemember(false);
   	    persistenceTokenBasedservice.setCookieName(REMEMBERME_COOKIENAME);
   	    persistenceTokenBasedservice.setTokenValiditySeconds(60 * 60 * 24 * 7);		// 토큰 유효시간 1주일 설정
   	    return persistenceTokenBasedservice;
    }

원인 

.rememberMeCookieName(REMEMBERME_COOKIENAME)
.rememberMeServices(persistentTokenBasedRememberMeServices())

설정시 rememberMeServices로 할지 스프링 시큐리트를 가지고 할지를 선택해서 하나만 설정을 해야지 에러가 나지 않는다. 
둘다 하면 에러가 위와 같은 에러 발생. 

해결방안. 

rememberMeServices 또는 스프링 설정 둘중 하나를 선택해서 설정하면 해결완료. 

 

private void configureRememberMe(HttpSecurity http) throws Exception {
        http.rememberMe()
               .key(REMEMBERME_KEY)
               .rememberMeParameter(REMEMBERME_PARAMETER)
               .rememberMeCookieName(REMEMBERME_COOKIENAME)
               .alwaysRemember(true)
               .tokenValiditySeconds(60 * 60 * 24 * 7)
               .tokenRepository(tokenRepository())
               .userDetailsService(userDetailsService());
	}
    
    
  

+ Recent posts