最近由于不清楚maven(2.2.x)增量编译的机制,导致应用出现了一个当时觉得非常诡异的一个问题。先描述一下问题。

    背景是应用A有一个公用的base包,版本为1.6.6-SNAPSHOT,应用B依赖于这个公用的base包。我在base包中修改了一个字符串变量的值,该变量是一个缓存的key(如下面代码的Constants类,中的CACHE_KEY)。然后使用mvn deploy 命令把base包上传到中心库中。出现的问题是应用B打包部署,应用上线后,使用后台功能删除"cache.key.new"对应的缓存值,提示删除成功。但是前台展示的还是老的值(前台展示取的数据是从缓存取出的,简化代码后,参考下面的CategoryManager的showCategory()方法,根据key在缓存中取出值,然后前台展示)。
 
  public Interface Constants{
public interface Cache{
String CACHE_KEY = “cache.key.new”;//旧值为"cache.key"
}
}
public Class CategoryManager{
private static Map<int, String> keyMaps = new HashMap<String, String>();
static {
keyMaps.put(1, Constants. Cache. CACHE_KEY);//把缓存的key存到map中
.........
} public Object showCategory(){
return cacheManager.get(keyMaps.get(1));//在缓存中获取数据
}
}
 
    一开始怀疑是包没有成功deploy到中心库中,然后在中心库中把1.6.6-SNAPSHOT的源码包拉了下来,发现里面的代码是新的。
    我的印象中deploy是maven生命周期的最后一步,执行deploy命令是会执行compile编译操作的,当时怀疑自己记错了,以为base包deploy的时候没有走到compile,就把包发到中心库中了,后续把base包的1.6.6-SNAPSHOT的编译后的文件拉下来,并且反编译Constants类,发现CACHE_KEY的确是新的值"cache.key.new",证明这块是被重新编译过了。(后续翻阅了下资料”http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html maven生命周期“发现自己记的的确没错)
    最后把CategoryManager.class反编译过来一看,发现里面的部分代码是这样的:
 
    public Class CategoryManager{
private static Map<int, String> keyMaps = new HashMap<String, String>();
static {
keyMaps.put(1, "cache.key");//问题出在这里,这个"cache.key"没有替换成新的值"cache.key.new"
.........
}
........
}
    发现问题了,这里的"cache.key"并没有替换成新值。也就是说CategoryManager类并没有重新编译。这里的原因是maven的增量编译机制。
    后续找了些资料表明,默认情况下maven是增量编译的,maven在编译的时候会先去比较源文件(.java)文件的修改时间和对应类文件(.class)的修改时间,如果源文件的修改时间比类文件的修改时间要晚的话,重新编译原文件否则不做处理(另外,如果删除了一个java文件,对应的class文件在增量编译时是不会被移除的)。
    在这里CategoryManager的源文件并没有发生过改变,所以不会重新编译。并且这个地方恰好是静态代码块,这段代码  keyMaps.put(1, Constants. Cache. CACHE_KEY); 编译时直接被替换成 keyMaps.put(1, "cache.key"); ,如果是在非静态代码块里面使用的话,这块地方是不会出问题的。所以之前一直使用mvn deploy都没有出现过问题。
    那要怎么避免这个问题呢,使用mvn clean deploy。clean会做一些清理的工作,包括移除上一次构建的文件。这样就能很好的解决这个问题了。
 
参考:

maven增量编译的更多相关文章

  1. Spark 1.0 开发环境构建:maven/sbt/idea

    因为我原来对maven和sbt都不熟悉,因此使用两种方法都编译了一下.下面记录一下编译时候遇到的问题.然后介绍一下如果使用IntelliJ IDEA 13.1构建开发环境. 首先准备java环境和sc ...

  2. IntelliJ IDEA使用心得之Maven项目篇(转)

    IntelliJ IDEA使用心得之Maven项目篇   今天和大家分享下,在IDEA中打开Maven项目的方法. 对于新版的IDEA可以直接打开Maven项目,但是对于旧版的IDEA需要使用Mave ...

  3. IntelliJ IDEA使用心得之Maven项目篇

    今天和大家分享下,在IDEA中打开Maven项目的方法. 对于新版的IDEA可以直接打开Maven项目,但是对于旧版的IDEA需要使用Maven命令生成项目的IDEA配置文件. 在项目的根目录(即po ...

  4. idea中使用maven

    转:https://www.cnblogs.com/kagome2014/p/8431064.html 对于新版的IDEA可以直接打开Maven项目,但是对于旧版的IDEA需要使用Maven命令生成项 ...

  5. Mac配置环境变量(Java,Android,Gradle,Nodejs,MongoDB,Maven,Hosts)

    JAVA_HOME 配置环境变量 # 使用vim打开.bash_profile文件.加入java环境变量 $ vim .bash_profile export JAVA_HOME=$(/usr/lib ...

  6. 深入了解gradle和maven的区别

    目录 简介 gradle和maven的比较 可扩展性 性能比较 依赖的区别 从maven迁移到gradle 自动转换 转换依赖 转换repositories仓库 控制依赖的版本 多模块项目 profi ...

  7. 【分享】标准springMVC+mybatis项目maven搭建最精简教程

    文章由来:公司有个实习同学需要做毕业设计,不会搭建环境,我就代劳了,顺便分享给刚入门的小伙伴,我是自学的JAVA,所以我懂的.... (大图直接观看显示很模糊,请在图片上点击右键然后在新窗口打开看) ...

  8. 理解Maven中的SNAPSHOT版本和正式版本

    Maven中建立的依赖管理方式基本已成为Java语言依赖管理的事实标准,Maven的替代者Gradle也基本沿用了Maven的依赖管理机制.在Maven依赖管理中,唯一标识一个依赖项是由该依赖项的三个 ...

  9. 【微框架】Maven +SpringBoot 集成 阿里大鱼 短信接口详解与Demo

    Maven+springboot+阿里大于短信验证服务 纠结点:Maven库没有sdk,需要解决 Maven打包找不到相关类,需要解决 ps:最近好久没有写点东西了,项目太紧,今天来一篇 一.本文简介 ...

随机推荐

  1. 文件尾存在EOF吗?

    参考:http://bbs.csdn.net/topics/290027166 我們先一起來看看FILE是怎么定義的:   FILE                          <STDI ...

  2. oracle数据库元数据SQL查询

    oracle数据库经典SQL查询 .查看表空间的名称及大小 select t.tablespace_name, round(sum(bytes/(1024*1024)),0) ts_size from ...

  3. Android 字体颜色在一些机型上不适配(textcolor失效)

    最近在参加一个创业项目的开发,其中在适配Android4.4版本时候遇到一个问题,本身title是白色字体,并且标签栏里面的字是绿色的,但是到了4.4手机上就变成了黑色. 也就是说textcolor并 ...

  4. 解决Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in

    php 5个版本,5.2.5.3.5.4.5.5,怕跟不上时代,新的服务器直接上5.5,但是程序出现如下错误:Deprecated: mysql_connect(): The mysql extens ...

  5. [改善Java代码]不能初始化泛型参数和数组

    泛型类型在编译期被擦除,我们在类初始化时将无法获得泛型的具体参数,比如这样的代码: class Foo<T>{ //private T t =new T();//报错Cannot inst ...

  6. 【数论】UVa 10586 - Polynomial Remains

    Problem F: Polynomial Remains Given the polynomial a(x) = an xn + ... + a1 x + a0, compute the remai ...

  7. poj 2449 第k短路径

    思路: 利用一个估计函数g[i]=dis[i]+len.其中len为队列出来的点当前已经走了的距离.dis[i]为该点到终点的最短路径.这样我们只要将点按g[i]的升序在队列你排序,每次取出最小的g[ ...

  8. 截图技巧——鼠标按着不懂,同时点击截图快捷键(QQ为ctrl+alt+a)即可避免按下快捷键鼠标按下等操作消失截不到的尴尬。

    截图技巧--鼠标按着不懂,同时点击截图快捷键(QQ为ctrl+alt+a)即可避免按下快捷键鼠标按下等操作消失截不到的尴尬.

  9. React Native 实现MQTT 推送调研 (1)

    一.推送几种实现方式: (1)通过SMS(Short Message Service,短信群发服务系统) 进行服务器端和客户端的交流通信.在Android平台上,可以通过拦截SMS消息并解析内容来了解 ...

  10. Git - Eclipse 提交工程至 GitHub

    1. 在 GitHub 新建一个工程 hello-world,repository 地址是 https://github.com/username/hello-world.git 2. 在 Eclip ...