Author: ChinSyun Pang
Weibo: arthinking_plus
Posted in: http://www.itzhai.com
Maven项目目录结构如下:
1 | project |
mklink /j “D:\dev\project\src\main\webapp\WEB-INF\lib” “D:\dev\project\target\project-snapshot\WEB-INF\lib”1
2
3
4
5
6
7
8
9
10
11
这样就把maven下载的lib目录联接到部署目录webapp下了;
对于class目录,也是同样的方法,另外需要设置IDE的自动编译输出目录到:
> target/project-snapshot/WEB-INF/classes
右击项目 -> properties -> Java Build Path -> 右边面板底部设置Default output folder;
## 直接运行main方法的问题
但是这样Eclipse下会有个问题,直接运行某个类的main方法,会提示如下错误:
java.lang.NoClassDefFoundError: me/arthinking/test/Demo
Caused by: java.lang.ClassNotFoundException: me.arthinking.test.Demo
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Exception in thread “main”1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22原因是没有读取到输出的classes文件,为此,我们可以把class编译输出目录设置为:
> project/target/classes
这样就可以正常执行main方法了
把这个目录联接到webapp/WEB-INF/classes目录下即可。
编译目录设置如图:
![](https://raw.githubusercontent.com/arthinking/informal-essay/master/images/2014/12/20141204-java01.png)
其他的配置文件目录需要联接到webapp目录,同上操作。
## 关于IDEA集成开发环境
据[Ryan](https://github.com/mojunbin "Ryan")介绍,IDEA集成开发环境是不会存在找不到main方法的问题的;
另外我们也可以在pom.xml中配置classes文件的输出目录,把classes文件输出到webapp目录下,这样改写了Java文件之后需要使用maven编译下项目了。:sunglasses:
pom.xml
```xml
<outputDirectory>D:\dev\project\webapp\WEB-INF\classes</outputDirectory>
Resin中的配置
现在我用着Resin,恰巧,resin里面提供了一个
1 | <web-app id="/" root-directory="D:\dev\project\src\main\webapp"> |
进一步查看官方文档可以发现有这样的介绍:
automatically compiles Java code into .class files before loading them.
首先这里class-loader实现了热部署(类似的一般的Servlet容器都提供了JSP的加载器,如Tomcat的JasperLoader,当容器检测到JSP文件被修改的时候,会自动替换掉原来的JSP加载器的Class实例,并创建一个新的,从而实现热部署。关于Resin中的类加载器执行问题),那么如果会在加载class文件之前重新编译源代码,就需要提供源代码的目录,查看文档,可以发现source这样的一个属性,添加上之后配置如下:
1 | <compiling-loader path="D:\dev\project\target\classes" source="D:\dev\project\src\main\java"/> |
这样就会在加载class前先自动编译Java代码了,这对于Eclipse没有开启自动编译功能的环境尤其有用(Eclipse的自动编译功能也是需要一定的资源开销的,有时候会导致Eclipse卡住,如果关闭了该功能,可以尝试以上配置)。
其他的热部署方案
热部署神器JRebel
这里是JRebel和JVM Hot Swap的区别
另外,这里有一个JVM hotswap的补丁
说到HotSwap特性,是在2002年的时候,Sun在Java 1.4的JVM中引入的实验性技术。这一技术被合成到了DebuggerAPI的内部。
《HotSwap和JRebel——幕后的故事》
Resin中的热部署
在resin.conf中添加如下的JVM启动参数:1
<jvm-arg>-Xdebug</jvm-arg>
表示启动debug模式,当更新了类中的方法的时候,控制台会提示reloading class,这是通过JVM的HotSwap功能动态更新的。
1 | ... Reloading ... |
由于JVM的HotSwap不支持新增属性,方法和类的修改,所以进行了这些操作之后,是无法实现热部署的,Resin会自动改用Hot deploy的方式进行应用更新。
当去掉该启动参数的时候,修改一个类,控制台会提示如下的内容:
1 | ... WebApp[...] stopping |