将Maven工程打包成可执行JAR包的方法

如果项目中有需要后台执行的任务,但是主要的逻辑都在Java代码中,那么我采用的方式是单独建立一个maven模块打成jar包,然后在linux后台通过命令执行Jar包的Main函数:

于是就有个前提,得将maven模块打包成jar包,原本很简单的事情,却出现了很多问题。

原始打包方式:使用maven-assembly-plugin

POM配置片段为:

这种打包方式,可以生成/target/mdm-v3-backtasks-1.0.0.2.jar的Jar包,在有些工程中是没有问题的,但是我的新工程打包后,却在运行时出现了如下问题:

网上搜了很多文章,发现首先大家都支持的,是maven-assembly-plugin插件,替换成maven-shade-plugin插件。

但是替换成maven-shade-plugin之后,仍然遇到了很多问题:

使用maven-shade-plugin逐步解决问题

使用maven-shade-plugin插件,并没有一下子就把问题解决了,也经过了很多步骤:

1、修改spring.xml的schema编写方式

原始的声明是这样的:

作如下修改,把xsd的版本加上:

2、引入maven-shade-plugin插件的打包方式遇到的问题

将原来的maven-assembly-plugin替换成新的打包方式:

然后就报了下面的错:

在http://zhentao-li.blogspot.com/2012/06/maven-shade-plugin-invalid-signature.html找到了解决方法:

于是加入以上的filter,新的POM内容为:

修改后提交,不幸的是,又爆出了下面的错误:

最后在http://robert-reiz.com/2011/11/14/832/页面找到了答案:

这是因为项目中包含了很多的Spring Jar,不同的Spring Jar会有相同的文件名称,他们相互冲突,为了避免元数据文件的相互覆盖,应该合并他们,如果使用maven shade plugin的话,可以在POM中加上下面的信息来解决:

对该问题,官方的解释位于:http://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html

在“Merging Content of Specific Files with AppendingTransformer and XmlAppendingTransformer”小节,解释为:

问题终于找到了,原来在这里,看下官方贴出来的POM:

最终的解决方案

最终的POM文件如下所示:

使用本POM配置,打包、运行均成功没有出错。

参考链接:

官方:http://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html

安全问题:http://zhentao-li.blogspot.com/2012/06/maven-shade-plugin-invalid-signature.html

Context问题:http://robert-reiz.com/2011/11/14/832/

 

本文地址:http://www.crazyant.net/1886.html,转载请注明来源

 

Java线程死亡的几种情况

Java线程会议如下三种方式结束,结束后就处于死亡状态

1、run()或者call()方法执行完成,线程正常结束;

2、线程抛出一个未捕获的Exception或Error;

3、直接调用该线程的stop()方法来结束该线程;

 

注意:当主线程结束时,其他线程不受任何影响,并不会随之结束。一旦子线程启动起来后,它就拥有和主线程相同的地位,不会受到主线程结束的影响。

为了测试某个线程是否已经死亡,可以调用线程对象的isAlive()方法,当线程处于就绪、运行、阻塞三种状态时,该方法将返回true;当线程处于新建、死亡两种状态时,该方法就返回false。

如下对线程死亡情况的1和2进行测试。主线程的代码如下:

测试1:线程正常结束后,isAlive()返回False

编写线程正常结束的线程执行代码:

两个线程的输出结果如下所示,显示子线程正常执行结束后,使用Thread.isAlive()就返回False了。

测试2:子线程抛出异常之后,线程的isAlive()返回False

修改子线程的代码,加入异常抛出:

再次执行,观察输出:

可以看到,抛出异常后,子线程直接终止,变成了Flase状态;

 

总结:线程正常结束后或者线程抛出了未捕获的异常,线程变成死亡状态,使用isAlive()函数返回False。

本文地址:http://www.crazyant.net/1861.html,转载请注明来源

通过JVM堆栈分析出现大量线程的原因

最近收到线上Tomcat线程数目超出的报警,于是想要分析下问题的原因:

首先进入线上,使用ps -aux命令,查看jvm进程,可以得到运行tomcat的jdk的地址:

/home/work/app/.jdk/bin/java

于是就知道了jdk的jstack、jps等命令的目录,然后找到jvm进程

得到了jvm的tomcat进程是208;

把堆栈导出,下载到本地:

下载后,发现线程堆栈中,有大量的这样的日志:

可以看到,线程处于WAITING状态,阻塞在试图从任务队列中取任务(LinkedBlockingQueue.take),这个任务队列指的是ThreadPoolExecutor的线程池启动的线程任务队列;

也就是说,这些线程都是空闲状态,在等着任务的到来呢!

补充下LinkedBlockingQueue的知识:

定位到问题就简单了,查找代码,发现有个位置启动了线程池提交了任务,但是任务执行完返回后,线程池没有关闭导致的;

问题总结:

1、使用ExecutorService提交的线程任务,也要记得关闭;

2、启动新线程的时候,最好给线程起个名字,这样线程堆栈的问题排查更加容易;

 

文章地址:http://www.crazyant.net/1858.html,转载请注明来源