该问题主要出现在 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\trunk\gwlogin\gwlogin-web\.\tmlog.lck
E:\workspace\trunk\gwhyz\gwhyz-web\.\tmlog.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:\logs\atomikos\gwhyz\,
com.atomikos.icatch.max_actives=50,
com.atomikos.icatch.checkpoint_interval=500,
com.atomikos.icatch.enable_logging=true,
com.atomikos.icatch.output_dir=D:\logs\atomikos\gwhyz\,
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:\\logs\\atomikos\\gwhyz\\
com.atomikos.icatch.max_actives=50
com.atomikos.icatch.checkpoint_interval=500
com.atomikos.icatch.enable_logging=true
com.atomikos.icatch.output_dir=D:\\logs\\atomikos\\gwhyz\\
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