Cloudfoundry Java-Buildpack源码分析

Java-buildpack介绍

在CloudFoundry中,最后打成的那个可以运行的包,称为droplet,任何一个DEA拿到这个droplet,解压然后start即可。那具体应该如何打包?打包过程应该是运行一系列的脚本吧,这个脚本在哪里?一般来讲,脚本文件为了备份和版本化需求我们一般会放到git或svn上,嗯,现在可以解释什么叫buildpack了:它是一坨脚本,一般是放到git上作为一个project的形态存在,这坨脚本的作用是把用户写好的程序(CloudFoundry中一般称为app)、及其依赖的环境、配置、启动脚本等打包成droplet,这个过程称之为stage。
Java-buildpack是用ruby写的,这里分析的是java-buildpack-offline-v3.1

Java-buildpack源码分析

获取代码

java-buildpack的源码在gitlab上获取:

git clone https://github.com/cloudfoundry/java-buildpack    

目录结构

java-buildpack的主要目录结构如下:

|---bin         
|---config      
|---lib         
|---resource

其中bin下面三个部分:

  • detect 检测阶段主要监测应用类型,应用使用的运行时和组件依赖
  • compile 编译,把应用所需的运行时和依赖的组件和应用进行融合
  • release 打包阶段,并输出应用的启动命令

detect源码分析

$stdout.sync = true  #设置标准输出
$stderr.sync = true  #设置错误输出
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)  #加载lib下面的类库,$LOAD_PATH,功能就是java中的classpath

require 'java_buildpack/buildpack'  #require累似java中的import

build_dir = ARGV[0]  #全局数组ARGV,接受命令行参数

components = JavaBuildpack::Buildpack.with_buildpack(build_dir, 'Detect failed with exception %s') do |buildpack|  
  buildpack.detect  #JavaBuildpack模块Buildpack类with_buildpack方法下执行buildpack的回调函数
end.compact  #删除nil元素

if components.empty?
  abort  #终止进程
else
  str = components.join(' ')
  puts str.length > 255 ? str.slice(0..251) + '...' : str
end

compile源码分析

$stdout.sync = true
$stderr.sync = true
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)

require 'java_buildpack/buildpack'

build_dir = ARGV[0]

JavaBuildpack::Buildpack.with_buildpack(build_dir, 'Compile failed with exception %s') do |buildpack|
  buildpack.compile  #调用buildpack类中的compile方法
end

release源码分析

$stdout.sync = true
$stderr.sync = true
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)

require 'java_buildpack/buildpack'

build_dir = ARGV[0]

output = JavaBuildpack::Buildpack.with_buildpack(build_dir, 'Release failed with exception %s') do |buildpack|
  buildpack.release
end

puts output  #输出返回值