• [ 懒人神器 ] —— OO一键build:.zip -> .jar


    懒人神器


    更新

    大家注意一下,由于在写入MANIFEST的时候,Class-Path路径给的是 ../lib ,即上级目录的lib。 所以在对拍时如果手动移动了 jar包的位置,需要保证 lib/ 文件夹在存放jar包的上一级目录下,否则在运行时会报错 ClassNotFound

    (也可以在源码中直接修改jar包的输出位置)

    一种可能的文件树如下:

    ├──src
    │  ├─ Archer.jar
    │  ├─ Berserker.jar
    │  ├─ Caster.jar
    |  ├─ ....
    |  └─ Alterego.jar
    ├──lib
    │  ├─ elevator-input-hw3-1.4-jar-with-dependencies.jar
    │  └─ timable-output-1.1-raw-jar-with-dependencies.jar
    └──your_pat.py
    

    一键build:zip -> jar
    由于每次互测都要经过重复的操作:

    download -> unzip -> compile -> run

    本着一懒到底的原则,以及想要进一步熟悉一下shell指令,写了一个builder的脚本。

    自己留着没意思,就拿出来分享给大家了,慢慢享用。

    同时要感谢一下 fmh,过程中帮我解决了许多问题,还有 lqq 以身试法帮我测试~

    使用

    • pre

      • 将所有下载的zip压缩包(java源文件)放入src文件夹中
      • 将本次作业的两个官方接口(外部jar包)放入lib文件夹中
      • 2. 中,更改相应的lib文件的绝对路径
    • 保证最后文件目录树如下即可:

    ├──src
    │  ├─ Archer.zip
    │  ├─ Berserker.zip
    │  ├─ Caster.zip
    |  ├─ ....
    |  └─ Alterego.zip
    ├──lib
    │  ├─ elevator-input-hw3-1.4-jar-with-dependencies.jar
    │  └─ timable-output-1.1-raw-jar-with-dependencies.jar
    └──builder.sh
    
    • run

      • 运行 builder.sh
    • 然后就可以愉快地开始对拍啦

    • 注意如果有player上交的src文件有多个main入口,有可能会出错。(但同样的,如果上交文件包含有多个入口,官方评测可能也过不了,这也是为什么rules中规定只能有一个入口)

    实现思路

    1. 解压缩并将lib中的外部包导入相应目录内

    easy

    2. 将src文件夹下的java编译为class文件

    • 编译输出路径为player/out/
    • 注意 lib中的 -classpath 为绝对路径

    3. 将*.class打包成jar

    • 难点(坑点) 在于MANIFEST.mf 的写入
      1. 保证 Main-Class: 带有相应的包路径 ,如 elevator3.Main
      2. 保证 Class-Path: 为相对路径
      3. 保证文件后有两个空行。
    • 因此,为满足上述需求:
      • 由于.class为二进制文件,无法直接解析,但out文件夹下的.class文件结构与.java相同,故可以通过grep检索.java文件,得到Main类包路径,再对得到的路径进行标准格式化操作即可。
      • 相对路径: .表示当前路径;..表示上一目录的路径
      • 需要有空行是真的坑,差点自闭···

    源码

    
    
    #!/bin/bash
    
    # Pre-Condition: 
    # NOTHING
    
    # Attention:
    # *.zip will be deleted
    
    # Procedure:
    # 1. put all *.zip into the src/ folder
    # 2. put the external .jar into lib/ folder
    # 3. run './builder.sh' 
    # 4. the jar-files has been generated in the 'out' folder of the corresponding directory, enjoy!
    
    # file-tree is as follows:
    # dir
    #  ├──src
    #  ├──lib
    #  └──builder.sh
    
    cd src/
    # 1. unzip and copy lib/ to src/
    echo unzip start...
    
    ls *.zip > temp.txt
    sed 's/.zip//g' temp.txt > names.txt # sed 's/src/dst/'
    names=`cat names.txt`   # attention
    
    # echo $names
    for name in ${names[@]}
    do
        mkdir $name
        unzip $name.zip -d $name
        cp -a ../lib $name
    done
    
    rm *.txt
    rm *.zip
    echo unzip successfully...
    
    
    # 2. compile to class
    echo complie start...
    
    prefix="javac -encoding utf-8 -d out/ @srcpath.txt "
    lib="-classpath /C/Users/94831/Desktop/CourseCenter/OO/testShell/lib/elevator-input-hw3-1.4-jar-with-dependencies.jar:/C/Users/94831/Desktop/CourseCenter/OO/testShell/lib/timable-output-1.1-raw-jar-with-dependencies.jar "
    command=${prefix}${lib}
    
    dirs=`ls`
    echo $dirs
    
    for dir in ${dirs[@]}
    do
        # echo $dir
        cd $dir
        mkdir out
        find -name "*.java" > srcpath.txt
        $command
        # rm srcpath.txt
        cd ..
    done
    
    echo compile successfully...
    
    
    # 3. pack to jar
    echo packing to jar...
    
    for dir in ${dirs[@]}
    do
        echo $dir
        cd $dir
        # write config information to MANIFEST.mf
        echo -n 'Main-Class: ' > MANIFEST.mf
        grep -l "public static void main" . -r | sed s/\.\///g | sed s/src\///g | sed s/\.java//g | sed s/\//./g >> MANIFEST.mf
        sed '2, $d' MANIFEST.mf | tee MANIFEST.mf
        echo 'Class-Path: ../lib/elevator-input-hw3-1.4-jar-with-dependencies.jar ../lib/timable-output-1.1-raw-jar-with-dependencies.jar' >> MANIFEST.mf
        echo >> MANIFEST.mf
        mv MANIFEST.mf out
    
        cd out
        find -name "*.class" > classpath.txt
        jar cvfm $dir.jar MANIFEST.mf @classpath.txt
        cd ..   # from out
        cd ..   # from player_dir
    done
    
    echo pack successfully...
    
    
    
    

    如有问题,欢迎留言交流!

  • 相关阅读:
    JavaScript可以做嵌入式开发了
    将指定字符串按指定长度进行剪切
    ASP.NET MVC Controller向View传值的几种方式
    SqlServer将数据库中的表复制到另一个数据库
    PAYPAL 支付,sandbox测试的时候遇到异常:请求被中止: 未能创建 SSL/TLS 安全通道,以及解决方法。
    c# ref与out的区别
    浅谈Tuple之C#4.0新特性
    CentOS7系列学习--修改用户密码
    关于页面多个ajax请求阻塞的问题
    关于overflow的学习
  • 原文地址:https://www.cnblogs.com/puzzledAtticus/p/10717183.html
Copyright © 2020-2023  润新知