`

关于代码编译打包和版本管理的一些事情

阅读更多
最近对于代码编译、打包以及版本的管理有一些想法,虽然比较简单,也先记录下来,以后再逐步完善

1、项目参与的人比较多,大概是200个人一起开发,经常发生提交到SVN上的代码编译不通过的情况,浪费了很多时间。

分析了一下,大部分是由于以下2个原因:

第一种情况:开发人员本地机器上有代码A和代码B,但是代码A在SVN上已经是比较新的版本,删除了某个方法,然后开发人员在本地修改代码B,调用了这个在SVN上已经不存在的方法(但是在本地的代码A上还是有的)。然后本地开发环境当然是编译通过的,于是开发人员就提交了修改后的代码B,这样一来,SVN上的代码肯定就编译无法通过了,报NoSuchMethodException

第二种情况:开发人员在本地修改了很多代码,编译都通过了没有问题,但是提交的时候只提交了部分代码。这样SVN上的代码就不全了,也会造成编译无法通过,报ClassNotFound或者NoSuchMethod

要避免上述第一种情况,就要求开发人员在提交代码之前,先把本地的代码更新一下,这样如果本地编译通过再提交,就会比较少发生提交后SVN代码编译不通过的情况

针对第二种情况,就要求开发人员每次把修改的代码提交完整

2、关于打jar包

打jar包比较简单,通过eclipse的export --> jar的功能就可以,在打包的时候,可以选择具体要打包的代码,或者资源文件,以及依赖的其他jar包。比如一个普通的java工程,里面有一个lib目录,放了很多依赖的其他jar包。那在把这个工程打成jar包的时候,可以把lib目录也打出来,或者不打也是可以的,由自己选择,一般是不会打的

这里说个题外话,为什么有时候从svn上import了一个工程,发现无法编译(红叉叉),报缺少jar包呢。这时候要看一下工程对应的.classpath文件,里面可能是引用了user library,而user library是依赖eclipse的,并不像lib文件夹里的jar包那样,可以上传到svn上再下载下来。也就是说开发人员A机器上自己建了一个user library,开发人员B的机器上是不会自动有的

其他的library也是类似的情况,比如开发人员A引入了tomcat runtime library,那开发人员B如果不对eclipse进行配置,那这个工程也是会报错的

所以多人一起开发的时候,统一开发环境是很重要的,不是说引入的jar包一样就可以,eclipse的配置,容器的配置,user library的配置都需要统一,这个工作应该是和搭建开发框架同时进行的,在开发正式开始之前就应该做好

一个工程是可以打出很多个jar包的,并不是说一个工程就只能有一个jar包。因为本质上jar包就是一大堆类和资源文件的集合而已。比如说大家熟悉的spring框架,其实原始工程只有一个,但是根据模块的不同,最后打出了10多个jar包,不同的项目只需要引入必要的部分就可以了。还有logback也是这样的,发布的版本是有3个jar包的,logback-core.jar、logback-classic.jar、logback-access.jar,但是原始工程也是只有一个。如果把logback-classic单独还原成一个工程,这个工程也是要报编译不通过的,因为logback-core里的很多类都缺失了。

因此工程和jar包可以是一对多的关系。比如开发了一个通用工具类的工程,然后也可以根据需要把这个工程打成多个jar包,比如time-util.jar、string-util.jar等,道理是一样的

3、关于打war包

打war包的情况比较单纯,仅针对web应用。用export --> war的功能,可以很简单地打出一个war包,这个war包的目录结构符合servlet规范,可以扔到容器里直接运行。要注意的是,打包和开发也是不一样的。比如在eclipse上开发一个web应用,首先需要指定一个runtime library,如果选tomcat的话,eclipse会自动给工程引入一个java ee runtime library,这样开发的代码就不会报错了。像Servlet、HttpServletResponse这些类,都是在这个run time library里支持的。

但是到了发布war包的时候,WEB-INF/lib下的依赖jar包,会自动地打到war包里,可是runtime library里的这些jar包是不会的。这也很好理解,因为war包最终是扔到容器里运行的,容器里已经有了这些jar包(如果用tomcat的话,是放在%CATALINA_HOME%/lib里),所以如果应用的.war里还自带这些jar包,那么就重复了。甚至如果开发时依赖tomcat的jar包,最终部署到jboss里,那可能还会有jar包冲突的危险。

顺带一提,开发的时候依赖哪个runtime library一般是问题不大的,因为无论是jboss、tomcat或者其他servlet容器提供的jar包,都是符合serlvet规范的,也就是说这些必须的类都是有的,不会造成开发时编译不通过。但是代码不要依赖容器绑定的类,否则的话代码就和具体的容器耦合了。比如代码里用到了Catalina.class,那这个应用在jboss里就没法跑了

4、关于拉分支

项目做得差不多了,需要拿到2个不同的地方去上线,2个地方分别有一些特殊的需求,这时候代码的维护就要注意了

如果是简单的拉2个分支,那加上原有的主干,就有了3套代码,也就是3个工程。这样就糟糕了,如果发现主干版本上有一个BUG,那就需要在3套代码里一起改,如果有N个分支,那就需要改N+1次

如果选择其中一个版本作为主干,拉1个分支,那情况稍微好一点点,有N个局点的话,就需要维护N套代码,比上面那种情况少1套,但是也没有本质的区别

如果把所有的需求都合并到主干代码里来,这种情况是最理想的,不管有几个局点,都只需要维护1套代码就可以了。不过实际情况往往没有这么理想,比如2个地方的需求有冲突,那要合并成一套代码就比较困难了,需要在设计上做特别的考虑,比如用配置文件做一个开关等等

总结来说,对于多个版本的维护,有以下几条原则(不一定对,请大家指出)

A.条件允许的情况下,尽量保证只有一套代码。即使临时拉了分支,也要尽快(比如一周之内)合并到主版本中

B.对于需求有冲突的情况,或者某些需求这里要那里不要的情况,可以通过配置文件、开关等方式,也合并到一套代码里,避免出现拉分支的情况。这需要设计上多费工夫

C.版本发布要控制住节奏,比如有的地方要求11号实现一批需求,有的地方要求18号实现一批需求,不能盲目地答应。作为项目经理,应该自己心中有一个计划,比如承诺10号交付第一个版本升级补丁,30号交付第二个,那11号要求的那批需求,可以赶一赶落到10号的补丁里;18号那批需求,顶住压力也要落到30号那个版本里去。否则别人要什么就给什么,很容易就把研发团队给拖垮了
分享到:
评论

相关推荐

    如何单独编译Android源代码中的模块

    Android 模块单独编译详解 在 Android 源代码工程中,单独编译某个模块是一件很有必要的事情。...只有当我们熟悉了 Android 源代码工程的目录结构和文件组织方式时,我们才能更好地编译和管理模块。

    未编译的linuxdeployqt.rar文件

    总的来说,linuxdeployqt是QT开发者在Linux环境中部署应用程序的关键工具,无论是从源码编译还是直接使用预编译的二进制版本,都能极大地简化依赖库的管理和分发工作。理解其工作原理和使用方法,将有助于提升QT应用...

    用gradle打包的配置文件

    2. 定义了项目的基本信息,包括组名和版本。 3. 配置了依赖项,这里我们添加了一个Spring的依赖作为例子。 4. 对`jar`任务进行了定制,设置了manifest文件的`Main-Class`属性,这是运行JAR时的主入口点。 5. `from`...

    VB动态的花朵屏幕保护源代码.rar

    7. **程序打包与发布**:将源代码编译成可执行文件,并可能使用安装包工具将其打包以便用户方便安装。 通过对这个VB动态花朵屏幕保护源代码的学习,开发者不仅可以掌握VB的基本语法和图形处理技巧,还能了解到如何...

    C语言学习资料打包下载

    这份"C语言学习资料打包下载"提供了丰富的学习资源,帮助初学者和有经验的开发者进一步提升自己的技能。 首先,"C语言经典案例100例"是学习者实践和理解C语言语法的重要参考资料。这100个案例涵盖了C语言的基础到...

    对外接口的封装、混淆与打包Demo

    在IT行业中,对外接口的封装、混淆与打包是软件开发中的关键步骤,特别是对于SDK(Software Development Kit)的开发者来说,这些技术对于保护代码安全、提高API使用体验以及优化资源管理至关重要。以下将详细讲解...

    Node.js-基于require.js的Node打包方案

    在Node.js场景下,`r.js`也可以用来编译和打包`require.js`模块,使其适应Node.js的CommonJS格式。 2. **配置r.js**:在使用`r.js`之前,需要编写一个配置文件(通常命名为`build.js`),指定输入、输出文件,以及...

    java通讯录(含源码和打包后的jar文件)

    它包括了源代码和已经打包成jar文件的可执行程序,使得用户可以直接运行而无需进行编译。这为学习Java,特别是Swing库以及数据库操作的初学者提供了实践的素材。 【描述】:“一个完整的java通讯录,数据库事access...

    yate-5.3.0-1源码

    其5.3.0-1版本的源码提供给了开发者深入研究和定制的机会,然而,将这一版本的源码适配到Android平台上并非易事,涉及到多个关键的技术环节和挑战。 首先,我们需要了解Yate的基本架构。Yate的核心是用C++编写的,...

    卡iPhone在线软件源码

    编译过程包括了解项目的构建系统(可能是Xcode项目文件)、配置设置、依赖管理和代码逻辑等。 标签"iPhone QQ 全天在线"则揭示了这个软件可能与QQ应用的在线状态保持有关,可能是通过模拟网络活动或者后台运行机制...

    2048Vue写的2048小游戏可打包成app

    标题中的“2048Vue写的2048小游戏可打包成app”表明这是一个使用Vue.js框架开发的2048游戏项目,可以被编译和打包为移动应用程序。Vue.js是一个轻量级的前端JavaScript框架,以其易学易用、组件化开发和高性能著称。...

    TabBars---VC6 IDE增强插件

    Visual C++ 6.0的集成开发环境对项目文件的管理功能比前几个版本有了很大的增强,但是对打开文档窗口的管理和普通的MDI编辑软件一样,只能通过窗口菜单切换,使用起来很不方便。2001年的时候我在网上见到了一款名为...

    软件开发这点事.pdf

    4. 版本控制:版本控制系统用于追踪和管理代码变更的历史。这样可以在软件开发过程中控制各个版本的代码,便于团队协作开发、代码分支管理以及错误回滚。Git和SVN是两个常用的版本控制系统。 5. 测试策略:软件测试...

    yaffs2.0.2.9.tar.gz

    5. **版本管理**:每个软件版本都有其特定的改进和修正,0.2.9可能是经过多次迭代后的稳定版本。 6. **源代码获取**:虽然提供的链接可能已失效,但开发者通常会将源代码迁移至其他托管平台,如GitHub,用户可以...

    maven那些事儿....

    - **构建与打包**:`mvn compile`进行源代码编译,`mvn package`生成可部署的JAR或WAR包。 - **依赖管理**:Maven自动下载并管理项目所需的第三方库,避免了手动管理jar文件的困扰。 - **版本控制**:Maven的版本...

    donetci:.net持续集成工具

    当时部门还用着vs2008用vb.net做项目(现在也是),项目代码极混乱,版本工具用的vss ,,而且用的不怎么顺,很多时候发布项目版本还是通过邮件发送代码vs工具手工编译打包的,并安排了一个所谓的中高级.net开发人员...

    上班摸鱼打卡模拟器微信小程序源码.rar

    这个标题暗示了我们讨论的主题是关于一个微信小程序的源代码,它的功能很有趣——模拟上班打卡,这可能被一些上班族用于娱乐或测试目的。"摸鱼"在中文中通常指的是在工作时间偷偷做自己的事情,这里指的是利用此小...

    apache-maven-3.6.3.rar

    通过POM,Maven可以自动下载项目所需的库,并按照预定义的生命周期和构建阶段来编译、测试、打包和部署项目。 Maven 3.6.3的亮点之一是其改进的性能,包括更快的依赖解析和构建速度。此外,这个版本修复了许多已知...

    android gradle

    在Android Studio中,Gradle负责编译、打包、依赖管理和版本控制等任务。每个Android项目都有一个`build.gradle`文件,用于定义项目的构建规则和配置。主项目的`build.gradle`(位于项目根目录)包含了全局的构建...

    ADTdq-1.0.2-py3-none-any.whl.zip

    开发者通常会将他们的代码打包成`whl`文件发布到PyPI(Python Package Index)上,供其他人下载和使用。同时,`whl`文件也是持续集成和部署流程中不可或缺的一部分,确保代码能在不同的环境中顺利运行。 总的来说,...

Global site tag (gtag.js) - Google Analytics