parent
							
								
									270317728f
								
							
						
					
					
						commit
						337e645263
					
				|  | @ -1,5 +1,5 @@ | ||||||
| /* | /* | ||||||
|  * Copyright 2012-2016 the original author or authors. |  * Copyright 2012-2017 the original author or authors. | ||||||
|  * |  * | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  * you may not use this file except in compliance with the License. |  * you may not use this file except in compliance with the License. | ||||||
|  | @ -40,7 +40,6 @@ import org.junit.Rule; | ||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
| import org.junit.rules.ExpectedException; | import org.junit.rules.ExpectedException; | ||||||
| 
 | 
 | ||||||
| import org.springframework.beans.BeansException; |  | ||||||
| import org.springframework.beans.factory.NoSuchBeanDefinitionException; | import org.springframework.beans.factory.NoSuchBeanDefinitionException; | ||||||
| import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; | import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; | ||||||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||||||
|  | @ -166,22 +165,7 @@ public class JtaAutoConfigurationTests { | ||||||
| 				AtomikosJtaConfiguration.class); | 				AtomikosJtaConfiguration.class); | ||||||
| 		this.context.refresh(); | 		this.context.refresh(); | ||||||
| 
 | 
 | ||||||
| 		File epochFile = new File("target/transaction-logs/" | 		File epochFile = new File("target/transaction-logs/tmlog0.log"); | ||||||
| 				+ InetAddress.getLocalHost().getHostAddress() + ".tm0.epoch"); |  | ||||||
| 		assertThat(epochFile.isFile()).isTrue(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Test |  | ||||||
| 	public void customAtomikosTransactionManagerName() throws BeansException, Exception { |  | ||||||
| 		this.context = new AnnotationConfigApplicationContext(); |  | ||||||
| 		TestPropertyValues.of( |  | ||||||
| 				"spring.jta.transactionManagerId:custom", |  | ||||||
| 				"spring.jta.logDir:target/transaction-logs").applyTo(this.context); |  | ||||||
| 		this.context.register(JtaPropertiesConfiguration.class, |  | ||||||
| 				AtomikosJtaConfiguration.class); |  | ||||||
| 		this.context.refresh(); |  | ||||||
| 
 |  | ||||||
| 		File epochFile = new File("target/transaction-logs/custom0.epoch"); |  | ||||||
| 		assertThat(epochFile.isFile()).isTrue(); | 		assertThat(epochFile.isFile()).isTrue(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -52,7 +52,7 @@ | ||||||
| 		<artemis.version>1.5.5</artemis.version> | 		<artemis.version>1.5.5</artemis.version> | ||||||
| 		<aspectj.version>1.8.10</aspectj.version> | 		<aspectj.version>1.8.10</aspectj.version> | ||||||
| 		<assertj.version>3.8.0</assertj.version> | 		<assertj.version>3.8.0</assertj.version> | ||||||
| 		<atomikos.version>3.9.3</atomikos.version> | 		<atomikos.version>4.0.4</atomikos.version> | ||||||
| 		<bitronix.version>2.1.4</bitronix.version> | 		<bitronix.version>2.1.4</bitronix.version> | ||||||
| 		<byte-buddy.version>1.6.14</byte-buddy.version> | 		<byte-buddy.version>1.6.14</byte-buddy.version> | ||||||
| 		<caffeine.version>2.5.1</caffeine.version> | 		<caffeine.version>2.5.1</caffeine.version> | ||||||
|  |  | ||||||
|  | @ -738,6 +738,7 @@ content into your application; rather pick only the properties that you need. | ||||||
| 	spring.jta.atomikos.datasource.reap-timeout=0 # The reap timeout, in seconds, for borrowed connections. 0 denotes no limit. | 	spring.jta.atomikos.datasource.reap-timeout=0 # The reap timeout, in seconds, for borrowed connections. 0 denotes no limit. | ||||||
| 	spring.jta.atomikos.datasource.test-query= # SQL query or statement used to validate a connection before returning it. | 	spring.jta.atomikos.datasource.test-query= # SQL query or statement used to validate a connection before returning it. | ||||||
| 	spring.jta.atomikos.datasource.unique-resource-name=dataSource # The unique name used to identify the resource during recovery. | 	spring.jta.atomikos.datasource.unique-resource-name=dataSource # The unique name used to identify the resource during recovery. | ||||||
|  | 	spring.jta.atomikos.properties.allow-sub-transactions=true # Specify if sub-transactions are allowed. | ||||||
| 	spring.jta.atomikos.properties.checkpoint-interval=500 # Interval between checkpoints. | 	spring.jta.atomikos.properties.checkpoint-interval=500 # Interval between checkpoints. | ||||||
| 	spring.jta.atomikos.properties.console-file-count=1 # Number of debug logs files that can be created. | 	spring.jta.atomikos.properties.console-file-count=1 # Number of debug logs files that can be created. | ||||||
| 	spring.jta.atomikos.properties.console-file-limit=-1 # How many bytes can be stored at most in debug logs files. | 	spring.jta.atomikos.properties.console-file-limit=-1 # How many bytes can be stored at most in debug logs files. | ||||||
|  | @ -751,6 +752,10 @@ content into your application; rather pick only the properties that you need. | ||||||
| 	spring.jta.atomikos.properties.max-actives=50 # Maximum number of active transactions. | 	spring.jta.atomikos.properties.max-actives=50 # Maximum number of active transactions. | ||||||
| 	spring.jta.atomikos.properties.max-timeout=300000 # Maximum timeout (in milliseconds) that can be allowed for transactions. | 	spring.jta.atomikos.properties.max-timeout=300000 # Maximum timeout (in milliseconds) that can be allowed for transactions. | ||||||
| 	spring.jta.atomikos.properties.output-dir= # Directory in which to store the debug log files. | 	spring.jta.atomikos.properties.output-dir= # Directory in which to store the debug log files. | ||||||
|  | 	spring.jta.atomikos.properties.recovery.delay=10000 # Delay between two recovery scans. | ||||||
|  | 	spring.jta.atomikos.properties.recovery.forget-orphaned-log-entries-delay=86400000 # Delay after which recovery can cleanup pending ('orphaned') log entries. | ||||||
|  | 	spring.jta.atomikos.properties.recovery.max-retries=5 # Number of retries attempts to commit the transaction before throwing an exception. | ||||||
|  | 	spring.jta.atomikos.properties.recovery.retry-interval=10000 # Delay between retry attempts. | ||||||
| 	spring.jta.atomikos.properties.serial-jta-transactions=true # Specify if sub-transactions should be joined when possible. | 	spring.jta.atomikos.properties.serial-jta-transactions=true # Specify if sub-transactions should be joined when possible. | ||||||
| 	spring.jta.atomikos.properties.service= # Transaction manager implementation that should be started. | 	spring.jta.atomikos.properties.service= # Transaction manager implementation that should be started. | ||||||
| 	spring.jta.atomikos.properties.threaded-two-phase-commit=false # Use different (and concurrent) threads for two-phase commit on the participating resources. | 	spring.jta.atomikos.properties.threaded-two-phase-commit=false # Use different (and concurrent) threads for two-phase commit on the participating resources. | ||||||
|  |  | ||||||
|  | @ -71,6 +71,11 @@ public class AtomikosProperties { | ||||||
| 	 */ | 	 */ | ||||||
| 	private boolean serialJtaTransactions = true; | 	private boolean serialJtaTransactions = true; | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Specify if sub-transactions are allowed. | ||||||
|  | 	 */ | ||||||
|  | 	private boolean allowSubTransactions = true; | ||||||
|  | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Specify if a VM shutdown should trigger forced shutdown of the transaction core. | 	 * Specify if a VM shutdown should trigger forced shutdown of the transaction core. | ||||||
| 	 */ | 	 */ | ||||||
|  | @ -126,6 +131,8 @@ public class AtomikosProperties { | ||||||
| 	 */ | 	 */ | ||||||
| 	private boolean threadedTwoPhaseCommit; | 	private boolean threadedTwoPhaseCommit; | ||||||
| 
 | 
 | ||||||
|  | 	private final Recovery recovery = new Recovery(); | ||||||
|  | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Specifies the transaction manager implementation that should be started. There is | 	 * Specifies the transaction manager implementation that should be started. There is | ||||||
| 	 * no default value and this must be set. Generally, | 	 * no default value and this must be set. Generally, | ||||||
|  | @ -235,6 +242,14 @@ public class AtomikosProperties { | ||||||
| 		return this.serialJtaTransactions; | 		return this.serialJtaTransactions; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	public void setAllowSubTransactions(boolean allowSubTransactions) { | ||||||
|  | 		this.allowSubTransactions = allowSubTransactions; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public boolean isAllowSubTransactions() { | ||||||
|  | 		return this.allowSubTransactions; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Specifies whether VM shutdown should trigger forced shutdown of the transaction | 	 * Specifies whether VM shutdown should trigger forced shutdown of the transaction | ||||||
| 	 * core. Defaults to false. | 	 * core. Defaults to false. | ||||||
|  | @ -370,6 +385,10 @@ public class AtomikosProperties { | ||||||
| 		return this.threadedTwoPhaseCommit; | 		return this.threadedTwoPhaseCommit; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	public Recovery getRecovery() { | ||||||
|  | 		return this.recovery; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Returns the properties as a {@link Properties} object that can be used with | 	 * Returns the properties as a {@link Properties} object that can be used with | ||||||
| 	 * Atomikos. | 	 * Atomikos. | ||||||
|  | @ -384,6 +403,7 @@ public class AtomikosProperties { | ||||||
| 		set(properties, "enable_logging", isEnableLogging()); | 		set(properties, "enable_logging", isEnableLogging()); | ||||||
| 		set(properties, "tm_unique_name", getTransactionManagerUniqueName()); | 		set(properties, "tm_unique_name", getTransactionManagerUniqueName()); | ||||||
| 		set(properties, "serial_jta_transactions", isSerialJtaTransactions()); | 		set(properties, "serial_jta_transactions", isSerialJtaTransactions()); | ||||||
|  | 		set(properties, "allow_subtransactions", isAllowSubTransactions()); | ||||||
| 		set(properties, "force_shutdown_on_vm_exit", isForceShutdownOnVmExit()); | 		set(properties, "force_shutdown_on_vm_exit", isForceShutdownOnVmExit()); | ||||||
| 		set(properties, "log_base_name", getLogBaseName()); | 		set(properties, "log_base_name", getLogBaseName()); | ||||||
| 		set(properties, "log_base_dir", getLogBaseDir()); | 		set(properties, "log_base_dir", getLogBaseDir()); | ||||||
|  | @ -394,6 +414,12 @@ public class AtomikosProperties { | ||||||
| 		set(properties, "console_file_count", getConsoleFileCount()); | 		set(properties, "console_file_count", getConsoleFileCount()); | ||||||
| 		set(properties, "console_file_limit", getConsoleFileLimit()); | 		set(properties, "console_file_limit", getConsoleFileLimit()); | ||||||
| 		set(properties, "threaded_2pc", isThreadedTwoPhaseCommit()); | 		set(properties, "threaded_2pc", isThreadedTwoPhaseCommit()); | ||||||
|  | 		Recovery recovery = getRecovery(); | ||||||
|  | 		set(properties, "forget_orphaned_log_entries_delay", | ||||||
|  | 				recovery.getForgetOrphanedLogEntriesDelay()); | ||||||
|  | 		set(properties, "recovery_delay", recovery.getDelay()); | ||||||
|  | 		set(properties, "oltp_max_retries", recovery.getMaxRetries()); | ||||||
|  | 		set(properties, "oltp_retry_interval", recovery.getRetryInterval()); | ||||||
| 		return properties; | 		return properties; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -404,4 +430,64 @@ public class AtomikosProperties { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Recovery specific settings. | ||||||
|  | 	 */ | ||||||
|  | 	public static class Recovery { | ||||||
|  | 
 | ||||||
|  | 		/** | ||||||
|  | 		 * Delay after which recovery can cleanup pending ('orphaned') log entries. | ||||||
|  | 		 */ | ||||||
|  | 		private long forgetOrphanedLogEntriesDelay = 86400000; | ||||||
|  | 
 | ||||||
|  | 		/** | ||||||
|  | 		 * Delay between two recovery scans. | ||||||
|  | 		 */ | ||||||
|  | 		private long delay = 10000; | ||||||
|  | 
 | ||||||
|  | 		/** | ||||||
|  | 		 * Number of retries attempts to commit the transaction before throwing an | ||||||
|  | 		 * exception. | ||||||
|  | 		 */ | ||||||
|  | 		private int maxRetries = 5; | ||||||
|  | 
 | ||||||
|  | 		/** | ||||||
|  | 		 * Delay between retry attempts. | ||||||
|  | 		 */ | ||||||
|  | 		private long retryInterval = 10000; | ||||||
|  | 
 | ||||||
|  | 		public long getForgetOrphanedLogEntriesDelay() { | ||||||
|  | 			return this.forgetOrphanedLogEntriesDelay; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public void setForgetOrphanedLogEntriesDelay(long forgetOrphanedLogEntriesDelay) { | ||||||
|  | 			this.forgetOrphanedLogEntriesDelay = forgetOrphanedLogEntriesDelay; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public long getDelay() { | ||||||
|  | 			return this.delay; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public void setDelay(long delay) { | ||||||
|  | 			this.delay = delay; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public int getMaxRetries() { | ||||||
|  | 			return this.maxRetries; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public void setMaxRetries(int maxRetries) { | ||||||
|  | 			this.maxRetries = maxRetries; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public long getRetryInterval() { | ||||||
|  | 			return this.retryInterval; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public void setRetryInterval(long retryInterval) { | ||||||
|  | 			this.retryInterval = retryInterval; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -16,14 +16,13 @@ | ||||||
| 
 | 
 | ||||||
| package org.springframework.boot.jta.atomikos; | package org.springframework.boot.jta.atomikos; | ||||||
| 
 | 
 | ||||||
| import java.lang.reflect.Method; |  | ||||||
| import java.util.Properties; | import java.util.Properties; | ||||||
| 
 | 
 | ||||||
| import org.assertj.core.data.MapEntry; | import org.assertj.core.data.MapEntry; | ||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
| 
 | 
 | ||||||
| import org.springframework.util.ClassUtils; | import org.springframework.core.io.ClassPathResource; | ||||||
| import org.springframework.util.ReflectionUtils; | import org.springframework.core.io.support.PropertiesLoaderUtils; | ||||||
| 
 | 
 | ||||||
| import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||||
| import static org.assertj.core.api.Assertions.entry; | import static org.assertj.core.api.Assertions.entry; | ||||||
|  | @ -47,6 +46,7 @@ public class AtomikosPropertiesTests { | ||||||
| 		this.properties.setEnableLogging(true); | 		this.properties.setEnableLogging(true); | ||||||
| 		this.properties.setTransactionManagerUniqueName("uniqueName"); | 		this.properties.setTransactionManagerUniqueName("uniqueName"); | ||||||
| 		this.properties.setSerialJtaTransactions(true); | 		this.properties.setSerialJtaTransactions(true); | ||||||
|  | 		this.properties.setAllowSubTransactions(false); | ||||||
| 		this.properties.setForceShutdownOnVmExit(true); | 		this.properties.setForceShutdownOnVmExit(true); | ||||||
| 		this.properties.setLogBaseName("logBaseName"); | 		this.properties.setLogBaseName("logBaseName"); | ||||||
| 		this.properties.setLogBaseDir("logBaseDir"); | 		this.properties.setLogBaseDir("logBaseDir"); | ||||||
|  | @ -57,8 +57,12 @@ public class AtomikosPropertiesTests { | ||||||
| 		this.properties.setConsoleFileCount(5); | 		this.properties.setConsoleFileCount(5); | ||||||
| 		this.properties.setConsoleFileLimit(6); | 		this.properties.setConsoleFileLimit(6); | ||||||
| 		this.properties.setThreadedTwoPhaseCommit(true); | 		this.properties.setThreadedTwoPhaseCommit(true); | ||||||
|  | 		this.properties.getRecovery().setForgetOrphanedLogEntriesDelay(2000); | ||||||
|  | 		this.properties.getRecovery().setDelay(3000); | ||||||
|  | 		this.properties.getRecovery().setMaxRetries(10); | ||||||
|  | 		this.properties.getRecovery().setRetryInterval(4000); | ||||||
| 
 | 
 | ||||||
| 		assertThat(this.properties.asProperties().size()).isEqualTo(17); | 		assertThat(this.properties.asProperties().size()).isEqualTo(22); | ||||||
| 		assertProperty("com.atomikos.icatch.service", "service"); | 		assertProperty("com.atomikos.icatch.service", "service"); | ||||||
| 		assertProperty("com.atomikos.icatch.max_timeout", "1"); | 		assertProperty("com.atomikos.icatch.max_timeout", "1"); | ||||||
| 		assertProperty("com.atomikos.icatch.default_jta_timeout", "2"); | 		assertProperty("com.atomikos.icatch.default_jta_timeout", "2"); | ||||||
|  | @ -66,6 +70,7 @@ public class AtomikosPropertiesTests { | ||||||
| 		assertProperty("com.atomikos.icatch.enable_logging", "true"); | 		assertProperty("com.atomikos.icatch.enable_logging", "true"); | ||||||
| 		assertProperty("com.atomikos.icatch.tm_unique_name", "uniqueName"); | 		assertProperty("com.atomikos.icatch.tm_unique_name", "uniqueName"); | ||||||
| 		assertProperty("com.atomikos.icatch.serial_jta_transactions", "true"); | 		assertProperty("com.atomikos.icatch.serial_jta_transactions", "true"); | ||||||
|  | 		assertProperty("com.atomikos.icatch.allow_subtransactions", "false"); | ||||||
| 		assertProperty("com.atomikos.icatch.force_shutdown_on_vm_exit", "true"); | 		assertProperty("com.atomikos.icatch.force_shutdown_on_vm_exit", "true"); | ||||||
| 		assertProperty("com.atomikos.icatch.log_base_name", "logBaseName"); | 		assertProperty("com.atomikos.icatch.log_base_name", "logBaseName"); | ||||||
| 		assertProperty("com.atomikos.icatch.log_base_dir", "logBaseDir"); | 		assertProperty("com.atomikos.icatch.log_base_dir", "logBaseDir"); | ||||||
|  | @ -76,6 +81,10 @@ public class AtomikosPropertiesTests { | ||||||
| 		assertProperty("com.atomikos.icatch.console_file_count", "5"); | 		assertProperty("com.atomikos.icatch.console_file_count", "5"); | ||||||
| 		assertProperty("com.atomikos.icatch.console_file_limit", "6"); | 		assertProperty("com.atomikos.icatch.console_file_limit", "6"); | ||||||
| 		assertProperty("com.atomikos.icatch.threaded_2pc", "true"); | 		assertProperty("com.atomikos.icatch.threaded_2pc", "true"); | ||||||
|  | 		assertProperty("com.atomikos.icatch.forget_orphaned_log_entries_delay", "2000"); | ||||||
|  | 		assertProperty("com.atomikos.icatch.recovery_delay", "3000"); | ||||||
|  | 		assertProperty("com.atomikos.icatch.oltp_max_retries", "10"); | ||||||
|  | 		assertProperty("com.atomikos.icatch.oltp_retry_interval", "4000"); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Test | 	@Test | ||||||
|  | @ -87,16 +96,22 @@ public class AtomikosPropertiesTests { | ||||||
| 				"com.atomikos.icatch.default_jta_timeout", | 				"com.atomikos.icatch.default_jta_timeout", | ||||||
| 				"com.atomikos.icatch.max_actives", "com.atomikos.icatch.enable_logging", | 				"com.atomikos.icatch.max_actives", "com.atomikos.icatch.enable_logging", | ||||||
| 				"com.atomikos.icatch.serial_jta_transactions", | 				"com.atomikos.icatch.serial_jta_transactions", | ||||||
|  | 				"com.atomikos.icatch.allow_subtransactions", | ||||||
| 				"com.atomikos.icatch.force_shutdown_on_vm_exit", | 				"com.atomikos.icatch.force_shutdown_on_vm_exit", | ||||||
| 				"com.atomikos.icatch.log_base_name", | 				"com.atomikos.icatch.log_base_name", | ||||||
| 				"com.atomikos.icatch.checkpoint_interval", | 				"com.atomikos.icatch.checkpoint_interval", | ||||||
| 				"com.atomikos.icatch.threaded_2pc")); | 				"com.atomikos.icatch.threaded_2pc", | ||||||
|  | 				"com.atomikos.icatch.forget_orphaned_log_entries_delay", | ||||||
|  | 				"com.atomikos.icatch.oltp_max_retries", | ||||||
|  | 				"com.atomikos.icatch.oltp_retry_interval")); | ||||||
| 		assertThat(properties).contains( | 		assertThat(properties).contains( | ||||||
|  | 				entry("com.atomikos.icatch.recovery_delay", defaultSettings.get( | ||||||
|  | 						"com.atomikos.icatch.default_jta_timeout")), | ||||||
| 				entry("com.atomikos.icatch.console_log_level", "WARN"), | 				entry("com.atomikos.icatch.console_log_level", "WARN"), | ||||||
| 				entry("com.atomikos.icatch.console_file_name", "tm.out"), | 				entry("com.atomikos.icatch.console_file_name", "tm.out"), | ||||||
| 				entry("com.atomikos.icatch.console_file_count", "1"), | 				entry("com.atomikos.icatch.console_file_count", "1"), | ||||||
| 				entry("com.atomikos.icatch.console_file_limit", "-1")); | 				entry("com.atomikos.icatch.console_file_limit", "-1")); | ||||||
| 		assertThat(properties).hasSize(13); | 		assertThat(properties).hasSize(18); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private MapEntry<?, ?>[] defaultOf(Properties defaultSettings, String... keys) { | 	private MapEntry<?, ?>[] defaultOf(Properties defaultSettings, String... keys) { | ||||||
|  | @ -110,12 +125,9 @@ public class AtomikosPropertiesTests { | ||||||
| 
 | 
 | ||||||
| 	private Properties loadDefaultSettings() { | 	private Properties loadDefaultSettings() { | ||||||
| 		try { | 		try { | ||||||
| 			Class<?> target = ClassUtils.forName( | 
 | ||||||
| 					"com.atomikos.icatch.standalone.UserTransactionServiceImp", | 			return PropertiesLoaderUtils.loadProperties( | ||||||
| 					getClass().getClassLoader()); | 					new ClassPathResource("transactions-defaults.properties")); | ||||||
| 			Method m = target.getMethod("getDefaultProperties"); |  | ||||||
| 			m.setAccessible(true); |  | ||||||
| 			return (Properties) ReflectionUtils.invokeMethod(m, null); |  | ||||||
| 		} | 		} | ||||||
| 		catch (Exception ex) { | 		catch (Exception ex) { | ||||||
| 			throw new IllegalStateException("Failed to get default from Atomikos", ex); | 			throw new IllegalStateException("Failed to get default from Atomikos", ex); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue