atomikos 在Windows Tomcat下使用遇到的坑
该问题主要出现在 Windows 环境下. Linux下不会
问题是很这样的:
1. 当在Eclipse 使用 maven的Tomcat 插件启动的时候,是不会报错的;
2. 当将war包放到 tomcat 容器中,启动Tomcat server的时候,就会报错.
eclipse中使用的Tomcat插件如下:
<build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <additionalClasspathDirs> <additionalClasspathDir>D:/config</additionalClasspathDir> </additionalClasspathDirs> <uriEncoding>utf-8</uriEncoding> <path>/gwhz</path> </configuration> </plugin> </plugins> </build>
ISSUE 1: Log already in use?
一开始,问题的描述如下
ERROR: the specified log seems to be in use already. Make sure that no other instance is running, or kill any pending process if needed. java.lang.RuntimeException: Log already in use? at com.atomikos.icatch.standalone.UserTransactionServiceImp.createDefault(UserTransactionServiceImp.java:246) at com.atomikos.icatch.standalone.UserTransactionServiceImp.init(UserTransactionServiceImp.java:306) at com.atomikos.icatch.config.UserTransactionServiceImp.init(UserTransactionServiceImp.java:413) at com.atomikos.icatch.jta.UserTransactionManager.checkSetup(UserTransactionManager.java:90) at com.atomikos.icatch.jta.UserTransactionManager.init(UserTransactionManager.java:140)
从log中可以知道,应该是日志的目录在同一个了
com.atomikos.icatch.log_base_name com.atomikos.icatch.log_base_dir
从Eclipse启动,会发现不同的项目,启动的时候,他们的这个是不一样的:
E:workspace runkgwlogingwlogin-web. mlog.lck E:workspace runkgwhyzgwhyz-web. mlog.lck
然后我们再可以发现如果我们啥都没有配置的话,atomikos的配置是这样的:
com.atomikos.icatch.automatic_resource_registration=true, com.atomikos.icatch.client_demarcation=false, com.atomikos.icatch.threaded_2pc=false, com.atomikos.icatch.serial_jta_transactions=true, com.atomikos.icatch.serializable_logging=true, com.atomikos.icatch.log_base_dir=., com.atomikos.icatch.max_actives=50, com.atomikos.icatch.checkpoint_interval=500, com.atomikos.icatch.enable_logging=true, com.atomikos.icatch.output_dir=., com.atomikos.icatch.log_base_name=tmlog, com.atomikos.icatch.max_timeout=300000, com.atomikos.icatch.tm_unique_name=192.168.158.80.tm, java.naming.factory.initial=com.sun.jndi.rmi.registry.RegistryContextFactory, java.naming.provider.url=rmi://localhost:1099, com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory, com.atomikos.icatch.force_shutdown_on_vm_exit=false, com.atomikos.icatch.default_jta_timeout=10000
从上面可以看到 com.atomikos.icatch.log_base_dir 和 com.atomikos.icatch.output_dir 都是当前目录的
com.atomikos.icatch.log_base_dir=. com.atomikos.icatch.output_dir=.
所以多个项目同时在Tomcat启动的时候,就会报以上的问题. 而且我们可以在Tomcat的bin目录下看到如下的文件:
{your IP}.tm0.epoch
tmlog.lck
tmlog0.log
然后发现这个问题之后,就试着去修改配置文件. 可是配置文件需要放在那儿呢?
通过log中的类
com.atomikos.icatch.standalone.UserTransactionServiceImp.createDefault
我们可以发现,atomikos的配置 最终是从两个文件中读取过来的
1. transactions.properties 2. jta.properties
顺序是,先尝试读取 transactions.properties文件,如果没有读取到,就去读取jta.properties.
如果都没有读取到,那么就使用默认的配置.
ISSUE2: Error in init of UserTransactionServiceImp
然后兴致冲冲的在classpath中,将debug获取到的 默认配置放上去,然后再重启tomcat. 配置如下
com.atomikos.icatch.automatic_resource_registration=true, com.atomikos.icatch.client_demarcation=false, com.atomikos.icatch.threaded_2pc=false, com.atomikos.icatch.serial_jta_transactions=true, com.atomikos.icatch.serializable_logging=true, com.atomikos.icatch.log_base_dir=D:logsatomikosgwhyz, com.atomikos.icatch.max_actives=50, com.atomikos.icatch.checkpoint_interval=500, com.atomikos.icatch.enable_logging=true, com.atomikos.icatch.output_dir=D:logsatomikosgwhyz, com.atomikos.icatch.log_base_name=tmlog, com.atomikos.icatch.max_timeout=300000, com.atomikos.icatch.tm_unique_name=192.168.158.80.tm, java.naming.factory.initial=com.sun.jndi.rmi.registry.RegistryContextFactory, java.naming.provider.url=rmi://localhost:1099, com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory, com.atomikos.icatch.force_shutdown_on_vm_exit=false, com.atomikos.icatch.default_jta_timeout=10000
然后重启,发现还是有错误,不过跟之前那个不一样了:
四月 17, 2017 4:51:33 下午 org.apache.catalina.core.StandardContext loadOnStartup 严重: Servlet [dispatcher] in web application [/gwhyz] threw load() exception com.atomikos.icatch.SysException: Error in init of UserTransactionServiceImp: com.atomikos.icatch.standalone.UserTransactionServiceFactory, at com.atomikos.icatch.config.UserTransactionServiceImp.checkInit(UserTransactionServiceImp.java:350) at com.atomikos.icatch.config.UserTransactionServiceImp.createTSInitInfo(UserTransactionServiceImp.java:362) at com.atomikos.icatch.config.UserTransactionServiceImp.init(UserTransactionServiceImp.java:568) at com.atomikos.icatch.jta.UserTransactionManager.startupTransactionService(UserTransactionManager.java:89) at com.atomikos.icatch.jta.UserTransactionManager.checkSetup(UserTransactionManager.java:77) at com.atomikos.icatch.jta.UserTransactionManager.init(UserTransactionManager.java:142) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) ....
从源码中可以发现,是加载的时候报错了:
private void checkInit () { if ( delegate_ != null ) return; String factoryClassName = getOrFindProperty ( "com.atomikos.icatch.service" ); if ( factoryClassName == null ) throw new SysException ( "UserTransactionServiceImp: property not defined: com.atomikos.icatch.service" ); try { Class factoryClass = ClassLoadingHelper.loadClass ( factoryClassName ); UserTransactionServiceFactory factory = ( UserTransactionServiceFactory ) factoryClass.newInstance (); delegate_ = factory.getUserTransactionService ( properties_ ); //This should initialize the properties with whatever is specified and //use SYSTEM_DEPENDENT DEFAULT values for others } catch ( Exception e ) { Stack<Exception> errors = new Stack<Exception> (); errors.push ( e ); throw new SysException ( "Error in init of UserTransactionServiceImp: " + e.getMessage() , errors ); } }
这个找啊找啊。一开始以为是lib没加载进去,然后就讲 对应的jar包放到 classpath中,可是还是这样
最后实在没辙了,就从 官网上将jta.properties 放进来,不用 transactions.properties了.
下载的地址为:
https://www.atomikos.com/pub/Documentation/Tomcat7Integration35/jta.properties
然后竟然可以了.
然后再去对比了下 transactions.properties文件,发现自己竟然每一行多了一个逗号.真的快吐血了; 将逗号去掉就可以了
最后的配置如下:
transactions.properties
com.atomikos.icatch.automatic_resource_registration=true com.atomikos.icatch.client_demarcation=false com.atomikos.icatch.threaded_2pc=false com.atomikos.icatch.serial_jta_transactions=true com.atomikos.icatch.serializable_logging=true com.atomikos.icatch.log_base_dir=D:logsatomikosgwhyz com.atomikos.icatch.max_actives=50 com.atomikos.icatch.checkpoint_interval=500 com.atomikos.icatch.enable_logging=true com.atomikos.icatch.output_dir=D:logsatomikosgwhyz com.atomikos.icatch.log_base_name=tmlog com.atomikos.icatch.max_timeout=300000 com.atomikos.icatch.tm_unique_name=192.168.158.80.tm java.naming.factory.initial=com.sun.jndi.rmi.registry.RegistryContextFactory java.naming.provider.url=rmi://localhost:1099 com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory com.atomikos.icatch.force_shutdown_on_vm_exit=false com.atomikos.icatch.default_jta_timeout=10000
将 log_base_dir 和 output_dir 的地址指向别的地方,Tomcat下的bin目录中就不会有以下三个文件了,他们会被放到 配置文件中指定的目录中去的
{your IP}.tm0.epoch
tmlog.lck
tmlog0.log