A Scheme for Incremental Automated Deployment of Old Java Web Applications

    If you also have an old Java web application, the code in the code base is incomplete for various reasons, so you can only deploy incrementally every time you go online, or the R&D specification requires incremental deployment. In this case How to automate compilation and deployment? A possible solution is given below:

    1. Before deployment, merge the code to be deployed into the deliver branch

    2. Compare the differences between the deliver branch and the master branch, and get the difference list for subsequent compilation

    3. When compiling the difference file, you need to add the jar that the application depends on, the deployed class file, etc. to the CLASSPATH

    4. If each test environment also uses this set of automatic deployment solutions, it may also be necessary to consider stripping the configuration related to the environment into the configuration file, and store them in directories according to the environment. For details, please refer to the profile mechanism of maven

    Core code (please optimize the code structure yourself :D):

    1. Compare the differences between the two branches (ignoring the differences caused by whitespace):

        try (Git git = Git.open(gitRepoFile);
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                DiffFormatter df = new DiffFormatter(out);) {

            Repository repository = git.getRepository();
            ObjectReader reader = repository.newObjectReader();

            String branchName = repository.getBranch();

            ObjectId masterId = repository.resolve("remotes/origin/master^{tree}");
            ObjectId branchId = repository.resolve(branchName + "^{tree}");

            CanonicalTreeParser masterTreeParser = new CanonicalTreeParser();
            masterTreeParser.reset(reader, masterId);

            CanonicalTreeParser branchTreeParser = new CanonicalTreeParser();
            branchTreeParser.reset(reader, branchId);

            List<DiffEntry> diffs = git.diff()
                    .setNewTree(branchTreeParser)
                    .setOldTree(masterTreeParser)
                    .call();

            Map<String, List<String>> diffFileMap = new HashMap<>();
            List<String> changeFileList = new ArrayList<>();
            List<String> deleteFileList = new ArrayList<>();

            df.setDiffComparator(RawTextComparator.WS_IGNORE_ALL);
            df.setRepository(git.getRepository());

            for (DiffEntry diffEntry : diffs) {
                df.format(diffEntry);
                FileHeader fileHeader = df.toFileHeader(diffEntry);

                @SuppressWarnings("unchecked")
                List<HunkHeader> hunks = (List<HunkHeader>) fileHeader.getHunks();
                int changedSize = 0;
                for (HunkHeader hunkHeader : hunks) {
                    EditList editList = hunkHeader.toEditList();
                    for (Edit edit : editList) {
                        changedSize += edit.getLengthA() + edit.getLengthB();
                    }
                }

                if (changedSize > 0) {
                    ChangeType changeType = diffEntry.getChangeType();
                    if (ChangeType.DELETE.equals(changeType)) {
                        String oldFilePath = diffEntry.getOldPath();
                        log.info("{}|{}", changeType.name(), oldFilePath);
                        deleteFileList.add(oldFilePath);
                    } else {
                        String newFilePath = diffEntry.getNewPath();
                        log.info("{}|{}", changeType.name(), newFilePath);
                        changeFileList.add(newFilePath);
                    }
                }
            }
            diffFileMap.put("change", changeFileList);
            diffFileMap.put("delete", deleteFileList);

            return diffFileMap;
        }

    2. Compile:

        Iterable<String> options = Arrays.asList(
                "-classpath", classpath,
                "-encoding", encoding,
                "-source", jdkVersion,
                "-target", jdkVersion,
                "-d", targetPath);

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        log.info("classpath:{}", classpath);
        log.info("targetPath:{}", targetPath);

        try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);) {

            Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(fileList);

            DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();

            CompilationTask compilationTask = compiler
                    .getTask(null, fileManager, diagnostics, options, null, compilationUnits);

            if (!compilationTask.call()) {
                log.error("JavaCompiler Build failed:");

                for (Diagnostic<?> diagnostic : diagnostics.getDiagnostics()) {
                    long line = diagnostic.getLineNumber();
                    String source = diagnostic.getSource() != null ? diagnostic.getSource().toString() : "";
                    String kind = diagnostic.getKind().name();
                    String message = diagnostic.getMessage(null);
                    log.info("{} on line:{} in {}.", kind, line, source);
                    log.info("message:{}", message);
                }
                return false;
            }
        }

    To achieve complete functions, it is necessary to improve according to the specific conditions of the application, such as: synchronously delete files deleted from the code base from the runtime environment; when pulling files from the code base, use fetch and reset methods; you can also use Marathon, Mesos , Docker to run applications, etc.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325048693&siteId=291194637