[Maven]如果改变了所依赖工程的版本,则本工程的版本也应该修改
如果改变了所依赖工程的版本(修改本工程的pom.xml),则本工程的版本也应该修改; 因为 1.本工程已不是以前的那个工程了,应该有个新名字,即新的版本号 2.设本工程为B,它依赖了C,同时又被A依赖。原来B依赖C-1,现在依赖C-2。如果B的版本不改,则A在打包时就不会更新B及其依赖了的C,导致A仍然依赖C-1。 C的升级就不会让A受益
如果改变了所依赖工程的版本(修改本工程的pom.xml),则本工程的版本也应该修改; 因为 1.本工程已不是以前的那个工程了,应该有个新名字,即新的版本号 2.设本工程为B,它依赖了C,同时又被A依赖。原来B依赖C-1,现在依赖C-2。如果B的版本不改,则A在打包时就不会更新B及其依赖了的C,导致A仍然依赖C-1。 C的升级就不会让A受益
java instrument api倒底能不能给一个类添加新方法? 答: 这取决于这个类是否已经被定义过了。 1. 如果还没被定义,就可以,即使这个类是系统类; 2. 如果已经定义了,这时的修改就是二次插桩(retransform),二次插桩时可以修改方法体,但不允许加减方法。 官方文档说: 引用 The retransformation may change method bodies, the constant pool and attributes. The retransformation must not add, remove or rename fields or methods, change the signatures of methods, or change inheritance. These restrictions maybe be lifted in future versions. 不过要注意最后一句: These restrictions maybe …
1. Snapshot版本代表不稳定、尚处于开发中的版本 2. Release版本则代表稳定的版本 3. 什么情况下该用SNAPSHOT? 协同开发时,如果A依赖构件B,由于B会更新,B应该使用SNAPSHOT来标识自己。这种做法的必要性可以反证如下: a.如果B不用SNAPSHOT,而是每次更新后都使用一个稳定的版本,那版本号就会升得太快,每天一升甚至每个小时一升,这就是对版本号的滥用。 b.如果B不用SNAPSHOT, 但一直使用一个单一的Release版本号,那当B更新后,A可能并不会接受到更新。因为A所使用的repository一般不会频繁更新release版本的缓存(即本地repository),所以B以不换版本号的方式更新后,A在拿B时发现本地已有这个版本,就不会去远程Repository下载最新的B 4. 不用Release版本,在所有地方都用SNAPSHOT版本行不行? 不行。 正式环境中不得使用snapshot版本的库。 比如说,今天你依赖某个snapshot版本的第三方库成功构建了自己的应用,明天再构建时可能就会失败,因为今晚第三方可能已经更新了它的snapshot库。你再次构建时,Maven会去远程repository下载snapshot的最新版本,你构建时用的库就是新的jar文件了,这时正确性就很难保证了。
同时使用Ubuntu和Windows: 1.Ubuntu下的五笔字型, Windows下的极点五笔 2.Firefox的插件: a.Autoproxy b.Firebug c.HttpFox d.Remove Cookies 4.Windows下的7zip 5.Windows下的staruml 6.Ubuntu下的gSTM + Firefox Autoproxy 插件 6.1 设置你的vps的SSH超时时间: vi /etc/ssh/sshd_config ClientAliveInterval 60 ClientAliveCountMax 1440 7.Ubuntu下的jdk下载安装及环境变量配置 8.Ubuntu下的chrome 9.Ubuntu下的defuse或meld 10. Ubuntu下的fqterm 11.用VNC让Ubuntu和Windows互联 a.Ubuntu设置好“允许远程登录”,再安装RDSC用作VNC Client b.Windows下安装UltraVNC,包括Client和Server c.windows下安装Insomnia,让windows无法休眠,也就让windows上的vnc server无法休眠 12.用FreeNX从Windows连Ubuntu a.Ubuntu安装FreeNX服务端,可参照Ubuntu官网上的教程 b.Windows安装FreeNX客户端,连接时打开所有能够提高性能的选项,并将连接所需的缓存设高一点 13.Ubuntu下的gnome-connection-manager, 相当于windows下的secureCRT。注意可以用ctrl + shift +c …
配置:Server在ubuntu, Client在windows. VNC 1.若Ubuntu用户已登录,从windows连接可以成功 2.若Ubuntu用户登录后锁屏,从windows连接可以成功 3.若Ubuntu用户登录后选择“休眠”、“挂起”或“注销”,从windows无法连接 4.Ubuntu用户登录后并且操作人从windows连接成功后,若Ubuntu切换用户,原有的windows连接将断开,试图重连也会失败;但可以使用另一个VNC地址(同一IP:1)来连,连好后看到的将是Ubuntu当前用户的界面 上述现象只所以发生,是因为 VNC只是把当前Ubuntu中当前登录用户能看到的东西共享给windows而已 FreeNX 只要Ubuntu开机了,从windows用FreeNX连Ubuntu就能成功,不管当时的Ubuntu有没有人登录,也不管当时有谁登录了; 从windows登录后,用户会感觉自己开机打开了Ubuntu,不会看到已打开的程序,即使相同的登录名已经登录了 这是 因为FreeNX完全基于SSH,每次登录都相当于开了一个新会话 不过,用FreeNX明显慢于VNC(如果你用的软件是UltraVNC的话) 适用场景: 1.Ubuntu不休眠、注销,那用VNC就够了 2.如果远程的Ubuntu被人休眠、注销、重启了,那就再用FreeNX连上去
public class MyServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException { print(Servlet.class.getClassLoader()); //输出org.apache.catalina.loader.StandardClassLoader,它负责加载/common下的类库; Servlet.class就是common/servlet-api.jar里的类 print(HttpServlet.class.getClassLoader()); //同上 //看看它的父加载器 print(HttpServlet.class.getClassLoader().getParent()); //是sun.misc.Launcher$AppClassLoader,即system classloader print(MyServlet.class.getClassLoader());//输出org.apache.catalina.loader.WebappClassLoader,它负责加载当前web-app下的类库; MyServlet.class就是当前web-app下的类 //看看它的父加载器 print(MyServlet.class.getClassLoader().getParent()); //输出 org.apache.catalina.loader.StandardClassLoader //试着找一下 Tomcat启动入口类的加载器 print(this.getClass().getClassLoader().loadClass("org.apache.catalina.startup.Bootstrap").getClassLoader()); //输出sun.misc.Launcher$AppClassLoader,即system classloader //看看当前的context class loader是哪个 print(Thread.currentThread().getContextClassLoader()); //输出org.apache.catalina.loader.WebappClassLoader,即加载当前web-app的加载器 } }
在普通的Main程序中, 某个类是被哪个加载器所加载的? print(String.class.getClassLoader()); //打印null, 这在HotSpot里代表Bootstrap ClassLoader,它负责加载$JAVA_HOME/lib里的类库 print(List.class.getClassLoader()); // 同上 print(learn.classloader.WhoLoadsMe.class.getClassLoader()); // 打印sun.misc.Launcher$AppClassLoader,它在HotSpot里代表System Class Loader, 负责加载用户类路径上的类库 print(learn.classloader.Friend.class.getClassLoader()); //同上 //看看sun.misc.Launcher$AppClassLoader的父加载器和祖父加载器是哪些 print(learn.classloader.Friend.class.getClassLoader().getParent()); //打印sun.misc.Launcher$ExtClassLoader,它在HotSpot里用于加载$JAVA_HOME/lib/ext下的类库 print(learn.classloader.Friend.class.getClassLoader().getParent().getParent()); //打印null, 即Bootstrap ClassLoader Class<?> remoteFriendClass = new learn.classloader.RemoteClassLoader().loadClass( "learn.classloader.RemoteFriend"); print(remoteFriendClass.getClassLoader()); //打印 learn.classloader.RemoteClassLoader,即自写的class loader(后文有这个class loader的代码) //看看自写加载器的父加载器是哪个 print(remoteFriendClass.getClassLoader().getParent()); //打印sun.misc.Launcher$AppClassLoader,即System ClassLoader print(remoteFriendClass.getField("friendOfFriend").getType() .getClassLoader()); //同上, 这意味着在"RemoteFriend"里直接引用的类(后文附上了代码描述这个引用)是由RemoteFriend的加载器所加载的 //最后看下context class loader print(Thread.currentThread().getContextClassLoader()); //打印sun.misc.Launcher$AppClassLoader,即system classloader 附: RemoteClassLoader package learn.classloader; public class …
现在能找到的Visitor模式的讲解大都非常跳跃,问题列出来出后,讲着讲着就突然给出了生涩的UML类图和accept()、visit()等奇怪的方法名,让人非常费解; 读者即使理解了,也有囫囵吞枣的感觉,不能领会其精妙之处。 本文试图以问题为驱动,以代码重构的方式,展示我们是怎么样一步一步地解决问题,并选择visitor模式作为重构的终点。 #1.问题域 visitor模式用于遍历一群对象,这些对象按某种结构组织在一起(List, Set, Tree等)。这种场景常常面临的问题是: 组织里的对象的类型彼此不同,遍历者要根据不同的类型使用不同的逻辑,导致代码里频繁使用if语句,可读性、可维护性都会比较差 //这个方法逐个打印每个Employee的称谓 private static void printTitle(Team team) { //一个Team里面的Employee有两种类型:Manager, 或Worker for (Employee employee : team.getEmployees()) { if (employee instanceof Manager) { System.out.println("Manager " + employee.getName()); } if (employee instanceof Worker) { System.out.println("Worker " + employee.getName()); } } } 代码详见 https://github.com/chenjianjx/learn-visitor-pattern/blob/master/1st-PlainSolution/src/learn/visitor/research/client/EmployeeClient.java 要消除if,最常见的方式就是把各个if里面的逻辑塞入到对象的各个子类中 #2.通过多态解决对象类型不同的问题 public class …
为什么要用git? 1. svn之类的"Centralized Version Control Systems"有什么问题? a.服务器的单点问题。服务器一旦当机,所有人都无法提交改动了。 b.如果服务器硬盘坏了,而又没有备机,那你将损失所有revision history 2. git之类的"Distributed version control system" 如何解决上述问题? 客户端存有的文件并不仅仅是最新版本,而是整个repository的镜像。每次checkout都是一次完整的复制。 a.如果服务器硬盘坏了,可以根据客户端的文件恢复 b.由于你镜像了整个repository,所以很多操作都只需在本地完成,速度很快; 而且如果服务器连不上,照样可以看revision history 基本概念 1. git的三种状态 a.committed — 修改已存入本地数据库 b.modified — 文件被修改,但还没有提交到本地库 c.staged — 文件被修改,并且已经被你标识了“将要”进库 ? 2. 几种文件/目录的定义 a. Git directory — 相当于svn的repository目录,用于存放元数据;既然git是"distributed", 所以你的本地和服务器上都会有这个目录。 …
用java attach api + java instrument api写java agent的注意事项 1. 字节码的transformation一旦发生,就会一直生效;agent的detach或中止,并不会使transformation回滚。 2. 由于#1,对于一个目标进程,在允许retransform的条件下,如果先后两次启动agent,就会导致两次transformation的效果叠加起来。举例来说,如果你的transform是在某方法里插入一条日志语句,那如果你先后两次使用你的agent,就会导致被transform的类在执行时生成两条日志。 待续…..