diff --git a/.gitignore b/.gitignore index 499bd94ad24e509499bde09c3abf4f8c3044e749..fe3e44c14fde858ba13d1dcdb6afc6f64fa9ddd5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,757 @@ -.cache -scalastyle-output.xml -.classpath -.idea -.idea/** +.scratch/ +/vote-db-boot/src/main/resources/static/ +.mvn/repository +.jpb + +# Created by https://www.gitignore.io/api/vim,node,java,linux,macos,emacs,nanoc,eclipse,windows,java-web,visualstudio,jetbrains+iml,visualstudiocode,maven,gradle + +### Eclipse ### + .metadata -.settings +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +### Eclipse Patch ### +# Eclipse Core .project -.version.properties -filter.properties -logs.zip -/**/target -target -tmp + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Annotation Processing +.apt_generated + +### Emacs ### +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +### Java ### +# Compiled class file *.class -*.iml -*.swp -*.jar + +# Log file *.log -.DS_Store -build-target + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +# *.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Java-Web ### +## ignoring target file +target/ + +### JetBrains+iml ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +### JetBrains+iml Patch ### +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +.idea/misc.xml *.ipr -*.iws +### Linux ### + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Maven ### +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar + +### Nanoc ### +# For projects using Nanoc (http://nanoc.ws/) + +# Default location for output (needs to match output_dir's value found in nanoc.yaml) +output/ + +# Temporary file directory +tmp/nanoc/ + +# Crash Log +crash.log + +### Node ### +# Logs +logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim + +# Temporary +.netrwhist +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +### VisualStudioCode ### +.vscode/* +# !.vscode/settings.json +# !.vscode/tasks.json +# !.vscode/launch.json +# !.vscode/extensions.json + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Gradle ### +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +### VisualStudio ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp_proj +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + + +# End of https://www.gitignore.io/api/vim,node,java,linux,macos,emacs,nanoc,eclipse,windows,java-web,visualstudio,jetbrains+iml,visualstudiocode,maven,gradle + +!charts/*/charts/*.tgz \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..de4fb832027ae6d59072888e54e9b12bac32ba6b --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,45 @@ +include: + - https://repos.iec.io/gitlab-ci/template/experimental/.standard-maven-project.yml + + + +variables: + # Java + JAVA_DOCKER_IMAGE: registry.inspures.com/public/docker.io/library/eclipse-temurin:8-jdk + # Maven + ALLOW_PUBLISHING_TO_MAVEN_REPO: "true" + POSTGRES_PASSWORD: postgres + + # Review + ALLOW_UPGRADE_REVIEW_ENVIRONMENT: "true" + ALLOW_REMOVE_REVIEW_ENVIRONMENT: "false" + +.services-for-maven-tests: + services: + # - name: redis:latest + # alias: redis + - name: postgres:11 + alias: postgres + +.refs-to-review: + only: + refs: + - main +# - 42-pipeline + +# .refs-to-publish-snapshot: +# only: +# refs: +# - main + +# .refs-to-publish-release: +# only: +# refs: +# - tags + + +.refs-to-publish: + only: + refs: + - main + - tags \ No newline at end of file diff --git a/.mvn/settings.xml b/.mvn/settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..c1a2a190d4d8746e64fb54bca6df8b338a9698dd --- /dev/null +++ b/.mvn/settings.xml @@ -0,0 +1,113 @@ + + .mvn/repository + + + caf-repo + ${env.ARTIFACTS_REPO_USERNAME} + ${env.ARTIFACTS_REPO_PASSWORD} + + + caf-snapshots-repo + ${env.ARTIFACTS_REPO_USERNAME} + ${env.ARTIFACTS_REPO_PASSWORD} + + + caf-releases-repo + ${env.ARTIFACTS_REPO_USERNAME} + ${env.ARTIFACTS_REPO_PASSWORD} + + + gsp-repo + ${env.ARTIFACTS_REPO_USERNAME} + ${env.ARTIFACTS_REPO_PASSWORD} + + + gsp-snapshots-repo + ${env.ARTIFACTS_REPO_USERNAME} + ${env.ARTIFACTS_REPO_PASSWORD} + + + gsp-releases-repo + ${env.ARTIFACTS_REPO_USERNAME} + ${env.ARTIFACTS_REPO_PASSWORD} + + + + + gsp-repo + gsp-rep + gsp-repo + https://repos.iec.io/repository/maven-gsp/ + + + gsp-releases-repo + gsp-rep + gsp-releases-repo + https://repos.iec.io/repository/maven-gsp-releases/ + + + gsp-snapshots-repo + gsp-rep + gsp-snapshots + https://repos.iec.io/repository/maven-gsp-snapshots/ + + + + + caf-repo + caf-rep + https://repos.iec.io/repository/maven-caf/ + + + caf-releases-repo + caf-rep + caf-releases-repo + https://repos.iec.io/repository/maven-caf-releases/ + + + caf-snapshots-repo + caf-rep + caf-snapshots-repo + https://repos.iec.io/repository/maven-caf-snapshots/ + + + + + repos.iec.io-caf + + + caf-rep + https://repos.iec.io/repository/maven-caf/ + + true + + + true + always + + + + + + repos.iec.io-gsp + + + gsp-rep + https://repos.iec.io/repository/maven-gsp/ + + true + + + true + always + + + + + + + + repos.iec.io-caf + repos.iec.io-gsp + + diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000000000000000000000000000000000000..c788ef118992410ccceffa90ace2ec5cb4796c15 --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,117 @@ +/* + * Copyright 2007-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.5"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} \ No newline at end of file diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..7882bbb72688b28388f7abf9e59ebf33bdc95c2b --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repos.iec.io/repository/maven-public/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repos.iec.io/repository/maven-public/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/mvnw b/mvnw new file mode 100755 index 0000000000000000000000000000000000000000..41056d43f63a1e4537e8abfe61837444f49b6706 --- /dev/null +++ b/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" \ No newline at end of file diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000000000000000000000000000000000000..32bde6aedce3b46eaec0a6086a7414499f705858 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2b8b678445398d0c8ea37bc44974978e24bdf590..c7a3957da3509ab442c33ce4cd7ff63988dab430 100644 --- a/pom.xml +++ b/pom.xml @@ -27,14 +27,86 @@ io.iec.edp caf-boot-parent - 0.3.7 + 2.0.0-rc.2 rest-api-engine com.inspur.edp pom - 1.0.2 + 1.0.3-SNAPSHOT + + + + + org.apache.commons + commons-lang3 + 3.9 + + + commons-io + commons-io + 2.16.1 + + + + org.junit.jupiter + junit-jupiter + 5.5.2 + + + org.junit.jupiter + junit-jupiter-api + 5.5.2 + + + org.junit.jupiter + junit-jupiter-engine + 5.5.2 + + + org.junit.jupiter + junit-jupiter-params + 5.5.2 + + + org.junit.platform + junit-platform-commons + 1.5.2 + + + org.junit.platform + junit-platform-engine + 1.5.2 + + + + + org.mockito + mockito-core + 3.1.0 + + + org.mockito + mockito-junit-jupiter + 3.1.0 + + + + org.powermock + powermock-api-mockito2 + 2.0.9 + test + + + + + + scm:git:ssh://git@git.iec.io:6060/gsp-cloud-ds/cdp/jit.git + scm:git:ssh://git@git.iec.io:6060/gsp-cloud-ds/cdp/jit.git + https://git.iec.io/gsp-cloud-ds/cdp/jit + HEAD + @@ -46,6 +118,11 @@ false + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + @@ -59,5 +136,4 @@ https://repos.iec.io/repository/maven-gsp-releases/ - diff --git a/rest-api-jit-api/pom.xml b/rest-api-jit-api/pom.xml index f2a2950be9997f7a957237ff4c35a147579cf4a0..5f8ba4ef383ad223bc9e8b620191a60b73010490 100644 --- a/rest-api-jit-api/pom.xml +++ b/rest-api-jit-api/pom.xml @@ -21,13 +21,12 @@ rest-api-engine com.inspur.edp - 1.0.2 + 1.0.3-SNAPSHOT 4.0.0 rest-api-jit-api - @@ -46,4 +45,4 @@ - \ No newline at end of file + diff --git a/rest-api-jit-core/pom.xml b/rest-api-jit-core/pom.xml index 651671e221f49534ba7dbf0ff0f106158b7873ff..d7d78d0b8aceb41a66f64b9a982dbe645e0aecab 100644 --- a/rest-api-jit-core/pom.xml +++ b/rest-api-jit-core/pom.xml @@ -21,7 +21,7 @@ rest-api-engine com.inspur.edp - 1.0.2 + 1.0.3-SNAPSHOT 4.0.0 @@ -29,41 +29,35 @@ io.iec.edp - caf-boot-commons-environment + caf-boot-starter-base com.inspur.edp rest-api-jit-api ${project.version} - compile - - - commons-io - commons-io - 2.6 - - - org.slf4j - slf4j-api org.apache.commons commons-lang3 - org.springframework.boot - spring-boot - - - io.iec.edp - caf-boot-commons-json + commons-io + commons-io com.inspur.edp rest-api-jit-spi ${project.version} - compile + + + org.junit.jupiter + junit-jupiter-api + + + org.powermock + powermock-api-mockito2 + test - \ No newline at end of file + diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/common/DirectoryManager.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/common/DirectoryManager.java index 24069d6cbd872a3613296ad6c5583ccd6dabf7e1..73c65288f133ce26c6f77f61ef2114305697ccb9 100644 --- a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/common/DirectoryManager.java +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/common/DirectoryManager.java @@ -17,6 +17,7 @@ package com.inspur.edp.jit.core.common; import io.iec.edp.caf.common.environment.EnvironmentUtil; +import io.iec.edp.caf.commons.runtime.CafEnvironment; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -27,22 +28,25 @@ import java.util.List; @Slf4j public class DirectoryManager { - private static final String BOOT_LIB_DIRECTORY_NAME = "bootlibs"; - private static String JIT_BASE_DIR = "var" + File.separator + "jit"; + private static final String JIT_DIR = "jit"; + private static final String JIT_BASE_DIR; private static String HOME_DIR = null; - private static Object lockObj = new Object(); - - public static String getUnZipBootJarDirectory() { - return getHomeDir() + File.separator + JIT_BASE_DIR + File.separator + BOOT_LIB_DIRECTORY_NAME; + private static final Object lockObj = new Object(); + + static { + String deployUnitName = CafEnvironment.getCurrentDeployunitName(); + String jitBaseDir = "var" + File.separator; + if (StringUtils.isBlank(deployUnitName)) { + JIT_BASE_DIR = jitBaseDir + JIT_DIR; + } else { + // 同一份安装盘会同时启动多个进程来加载多个程序,通过deployUnitName区分不同进程,保证每个进程读写自己的文件 + JIT_BASE_DIR = jitBaseDir + deployUnitName + File.separator + JIT_DIR; + } } public static String getHomeDir() { if (HOME_DIR == null) { - String cafHome = EnvironmentUtil.getServerRTPath(); - if (cafHome == null || cafHome.length() == 0) { - throw new RuntimeException("获取server目录异常,获取的值为null"); - } - HOME_DIR = cafHome; + HOME_DIR = EnvironmentUtil.getServerRTPath(); } return HOME_DIR; } @@ -59,12 +63,8 @@ public class DirectoryManager { return getJitDirectory(functionType) + File.separator + functionId; } - public static void removeFunctionDir(String functionType, String functionId) { - String dir = getJitDirectory(functionType, functionId); - File file = new File(dir); - if (file.exists()) { - file.delete(); - } + public static String get3rdDirectory() { + return getHomeDir() + File.separator + "runtime" + File.separator + "3rd"; } /** @@ -103,22 +103,12 @@ public class DirectoryManager { return result; } - public static void clean() { - String dir = getJitBaseDirectory(); - File file = new File(dir); - if (file.exists()) { - file.delete(); - } - } - - public static boolean createDir(String creatingDir) { File file = new File(creatingDir); if (!file.exists()) { synchronized (lockObj) { if (!file.exists()) { - file.mkdirs(); - return true; + return file.mkdirs(); } } } diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/common/StartManager.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/common/StartManager.java index 2f82ad322bc2421915eef3ae64550b1fdedff8f7..4bbdf73daa7bd9e1cf2fdef11f790717fdcb1e8f 100644 --- a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/common/StartManager.java +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/common/StartManager.java @@ -32,8 +32,6 @@ public class StartManager implements ApplicationListener { if (event instanceof ApplicationStartedEvent) { String jitBaseDirectory = DirectoryManager.getJitBaseDirectory(); DirectoryManager.createDir(jitBaseDirectory); - String bootLibsDirectory = DirectoryManager.getUnZipBootJarDirectory(); - DirectoryManager.createDir(bootLibsDirectory); ApplicationContext applicationContext = ((ApplicationStartedEvent) event).getApplicationContext(); Map eventMap = applicationContext.getBeansOfType(StartEvent.class); diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/common/UnZipManager.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/common/UnZipManager.java deleted file mode 100644 index 0d393a6d0093d02b9553f6bccada874c3e63b9d7..0000000000000000000000000000000000000000 --- a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/common/UnZipManager.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.inspur.edp.jit.core.common; - -import org.apache.commons.io.IOUtils; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -public class UnZipManager { - - private static Object lockObj = new Object(); - private static List UNZIPED_LIST = new ArrayList<>(); - - public static List unZip(List jarNames) throws IOException { - List realyJars = new ArrayList<>(); - List needJars = getNeedJars(jarNames, realyJars); - if (needJars.size() == 0) { - return realyJars; - } - synchronized (lockObj) { - JarFile jar = new JarFile(getBootJarDirectory()); - Enumeration entryEnumeration = jar.entries(); - List entries = new ArrayList<>(); - while (entryEnumeration.hasMoreElements()) { - entries.add(entryEnumeration.nextElement()); - } - final String entryLibPrefix = "BOOT-INF/lib/"; - String bootlibs = DirectoryManager.getUnZipBootJarDirectory(); - - for (String jarPrefixName : needJars) { - String entryNamePrefix = entryLibPrefix + jarPrefixName; - boolean isFind = false; - for (JarEntry entry : entries) { - String entryName = entry.getName(); - if (entryName.startsWith(entryNamePrefix) && entryName.endsWith(".jar")) { - //找到后保存jar包 - String jarFileName = entryName.substring(entryLibPrefix.length()); - File jarFile = new File(bootlibs, jarFileName); - if (!jarFile.exists()) { - try { - FileOutputStream fos = new FileOutputStream(jarFile); - IOUtils.copy(jar.getInputStream(entry), fos); - fos.close(); - } catch (Exception ex) { - throw new RuntimeException("spring boot unzip error:", ex); - } - //增加到缓存 - UNZIPED_LIST.add(entryName); - } - realyJars.add(jarFileName); - isFind = true; - } - } - if (!isFind) { - throw new RuntimeException("SpringBoot无法找到【" + jarPrefixName + "】"); - } - } - } - return realyJars; - } - - /** - * 得到未缓存的jar包。已经存在的jar包路径存入入参realyNames中。 - * - * @param jarNames 所有需要的jar包列表 - * @param realyNames 已经存在的jar包路径。在方法中被填入值 - * @return 未缓存的jar包名称 - */ - private static List getNeedJars(List jarNames, List realyNames) { - List needJars = new ArrayList<>(); - for (String jarName : jarNames) { - boolean unZiped = false; - for (String unZipName : UNZIPED_LIST) { - if (unZipName.toLowerCase().startsWith(jarName.toLowerCase())) { - unZiped = true; - realyNames.add(unZipName); - //此处不break,避免引用具有相同前缀的错误的jar包 - } - } - if (!unZiped) { - needJars.add(jarName); - } - } - return needJars; - } - - public static String getBootJarDirectory() { - return DirectoryManager.getHomeDir() + File.separator + "runtime" + File.separator + "caf-bootstrap.jar"; - } - -} diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/BytesJavaFileObject.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/BytesJavaFileObject.java new file mode 100644 index 0000000000000000000000000000000000000000..e24bc6b20409c5aac1e1c618e8954acf5c9154cd --- /dev/null +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/BytesJavaFileObject.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.inspur.edp.jit.core.compile; + +import javax.tools.SimpleJavaFileObject; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * @author Kaixuan Shi + * @since 2023/8/24 + */ +public class BytesJavaFileObject extends SimpleJavaFileObject { + private final String className; + private ByteArrayOutputStream classBytesOs; + + public BytesJavaFileObject(String className, Kind kind) { + super(fromClassName(className), kind); + this.className = className; + } + + private static URI fromClassName(String className) { + try { + return new URI(className); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(className, e); + } + } + + /** + * 编译结果回调的OutputStream,回调成功后通过getClassBytes()方法获取目标类编译后的字节码字节数组 + */ + @Override + public OutputStream openOutputStream() { + return classBytesOs = new ByteArrayOutputStream(); + } + + public byte[] getClassBytes() { + return classBytesOs.toByteArray(); + } + + public String getClassName() { + return className; + } + +} diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/CompileServiceImpl.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/CompileServiceImpl.java index 1e5b82245b5a22ccf5a2a81e4d8be02455fb5f8a..06d150f5f77e665d6d189ba6a22b0489f7f1cebe 100644 --- a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/CompileServiceImpl.java +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/CompileServiceImpl.java @@ -20,8 +20,9 @@ import com.inspur.edp.jit.api.compile.CompileContext; import com.inspur.edp.jit.api.compile.CompileService; import com.inspur.edp.jit.api.compile.JavaSourceCode; import com.inspur.edp.jit.core.common.DirectoryManager; -import com.inspur.edp.jit.core.common.UnZipManager; import com.inspur.edp.jit.core.load.ClassLoadManager; +import com.inspur.edp.jit.core.util.JarUtil; +import com.inspur.edp.jit.core.util.JitIOException; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; @@ -38,15 +39,17 @@ import java.io.File; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; public class CompileServiceImpl implements CompileService { - private static Logger logger = LoggerFactory.getLogger(CompileServiceImpl.class); - private JavaCompiler compiler; + private static final Logger logger = LoggerFactory.getLogger(CompileServiceImpl.class); + private final JavaCompiler compiler; public CompileServiceImpl() { logger.info("new CompileServiceImpl"); @@ -59,152 +62,82 @@ public class CompileServiceImpl implements CompileService { //构造StringJavaFileObject List javaFileObjects = new ArrayList<>(); - context.getSourceCodes().forEach(sourceCode -> { - javaFileObjects.add(new StringJavaFileObject(sourceCode.getFullClassName(), sourceCode.getSourceCode())); - }); - - //创建目录 - String destDir = getOutDirPath(context); - DirectoryManager.createDir(destDir); + context.getSourceCodes().forEach( + sourceCode -> + javaFileObjects.add( + new StringJavaFileObject(sourceCode.getFullClassName(), sourceCode.getSourceCode()) + ) + ); //编译 - try { - compile(destDir, referJars, javaFileObjects); - } catch (Exception e) { - //编译出错时移除空文件夹 - //如果之前存在编译结果,则不移除 - deleteEmptyDirWithoutThrows(destDir); - throw e; - } + JitJavaFileManager javaFileManager = compile(referJars, javaFileObjects); - //更新manifest.json - ManifestUtil.updateManifest(context); + //获取编译结果 + List compiledClasses = getJavaFileObject(context, javaFileManager); + //更新ClassLoader + ClassLoadManager.put(context.getFunctionType(), context.getFunctionId(), compiledClasses); - //卸载ClassLoader - ClassLoadManager.unLoad(context.getFunctionType(), context.getFunctionId()); + //更新功能包缓存 + updateFunctionCache(context, compiledClasses); + } + + /** + * 更新功能包缓存 + */ + private void updateFunctionCache(CompileContext context, List compiledClasses) { + String functionDir = DirectoryManager.getJitDirectory(context.getFunctionType(), context.getFunctionId()); + DirectoryManager.createDir(functionDir); + //更新jar包 + JarUtil.write(functionDir, context.getFunctionId(), compiledClasses); + //更新Manifest文件 + ManifestUtil.updateManifest(context); } @Override public void batchCompile(List contexts) { //按照类名分组,类名不同的分在同一组,相同的分在不同组 - List> compileListGroup = buildCompileGroups(contexts); + List> compileGroups = buildCompileGroups(contexts); - logger.info("bat compile {} split to {} groups", contexts.size(), compileListGroup.size()); - compileListGroup.forEach(group -> { - //编译到默认位置(第一个compileContext目录中) - CompileContext firstContext = group.get(0); - String destDir = getOutDirPath(firstContext); - DirectoryManager.createDir(destDir); + logger.info("bat compile {} split to {} groups", contexts.size(), compileGroups.size()); + compileGroups.forEach(group -> { //合并依赖 List referJars = mergeAndParseClassPathList(group); //合并java文件 - List javaFileObjects = new ArrayList<>(); - group.forEach(context -> { - context.getSourceCodes().forEach(sourceCode -> { - javaFileObjects.add(new StringJavaFileObject(sourceCode.getFullClassName(), sourceCode.getSourceCode())); - }); - }); + List javaFileObjects = new ArrayList<>(group.size()); + group.forEach(context -> + context.getSourceCodes().forEach(sourceCode -> + javaFileObjects.add( + new StringJavaFileObject(sourceCode.getFullClassName(), sourceCode.getSourceCode()) + ) + ) + ); //批量编译 - try { - compile(destDir, referJars, javaFileObjects); - } catch (Exception e) { - //编译出错时移除空文件夹 - //如果之前存在编译结果,则不移除 - deleteEmptyDirWithoutThrows(destDir); - throw e; - } - - //处理除第一个外的所有CompileContext - //提取文件,将编译后的类从默认位置转移到功能包位置 - for (int i = 1; i < group.size(); i++) { - CompileContext context = group.get(i); - context.getSourceCodes().forEach(javaSourceCode -> { - String oldDirPath = getJavaSourceCodeCompileDir(firstContext, javaSourceCode); - String newDirPath = getJavaSourceCodeCompileDir(context, javaSourceCode); - - File oldDir = new File(oldDirPath); - File newDir = new File(newDirPath); - - String simpleClassName = getSimpleClassName(javaSourceCode); - String classFileName = simpleClassName + ".class"; - String innerClassPrefixFileName = simpleClassName + "$"; + JitJavaFileManager javaFileManager = compile(referJars, javaFileObjects); - if (!oldDir.exists()) { - logger.warn("目标路径【{}】不存在", oldDirPath); - return; - } - File[] files = oldDir.listFiles(); - for (File file : files) { - if (file.isDirectory()) { - continue; - } - - String fileName = file.getName(); - if (fileName.equals(classFileName) || fileName.startsWith(innerClassPrefixFileName)) { - //转移类本身及其内部类 - try { - //复制到目标位置 - File newFile = new File(newDir, file.getName()); - if (newFile.exists()) { - newFile.delete(); - } - FileUtils.moveFile(file, newFile); - } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - } - recursiveDeleteEmptyDirWithoutThrows(oldDir); - }); - } + group.forEach(context -> { + List compiledClasses = getJavaFileObject(context, javaFileManager); + //更新classLoader + ClassLoadManager.put(context.getFunctionType(), context.getFunctionId(), compiledClasses); + //更新功能包缓存 + updateFunctionCache(context, compiledClasses); + }); }); - - //更新manifest.json - contexts.forEach(ManifestUtil::updateManifest); - - //卸载classLoader - contexts.forEach(context -> ClassLoadManager.unLoad(context.getFunctionType(), context.getFunctionId())); - } - - private void deleteEmptyDirWithoutThrows(String dirPath) { - try { - File dir = new File(dirPath); - String[] list = dir.list(); - if (list != null && list.length == 0) { - dir.delete(); - } - } catch (Exception e) { - logger.error("删除文件夹【" + dirPath + "】出错:" + e.getMessage(), e); - } } /** - * 递归删除空文件夹 + * 从JitJavaFileManager中获取编译后的字节码 */ - private void recursiveDeleteEmptyDirWithoutThrows(File dir) { - try { - String[] list = dir.list(); - if (list != null && list.length == 0) { - File parentFile = dir.getParentFile(); - dir.delete(); - recursiveDeleteEmptyDirWithoutThrows(parentFile); - } - } catch (Exception e) { - logger.error("删除文件夹【" + dir.getAbsolutePath() + "】出错:" + e.getMessage(), e); - } - } + private List getJavaFileObject(CompileContext context, JitJavaFileManager javaFileManager) { - private String getSimpleClassName(JavaSourceCode javaSourceCode) { - String fullClassName = javaSourceCode.getFullClassName(); - int index = fullClassName.lastIndexOf("."); - if (index >= 0) { - return fullClassName.substring(index + 1); - } else { - return fullClassName; - } + List javaFileObjects = new ArrayList<>(); + context.getSourceCodes().forEach(javaSourceCode -> { + //内部类会被编译成多个class字节码,所以需要addAll + javaFileObjects.addAll(javaFileManager.getCompiledJavaFileObject(javaSourceCode.getFullClassName())); + }); + return javaFileObjects; } /** @@ -226,6 +159,9 @@ public class CompileServiceImpl implements CompileService { return parseClassPathList(new ArrayList<>(referBootSet), new ArrayList<>(referSet)); } + /** + * 将编译上下文里的类按照类名分组,类名不同的分在同一组,相同的分在不同组 + */ private List> buildCompileGroups(List contexts) { List> classNameSetGroup = new ArrayList<>(); List> compileListGroup = new ArrayList<>(); @@ -266,43 +202,6 @@ public class CompileServiceImpl implements CompileService { return compileListGroup; } - /** - * 得到在编译上下文中,指定的Java源文件的编译结果class文件的最终存放目录。 - * - * @param context 编译上下文 - * @param javaSourceCode 编译上下文 - * @return class文件实际存放目录 - */ - private String getJavaSourceCodeCompileDir(CompileContext context, JavaSourceCode javaSourceCode) { - String packageName = getPackage(javaSourceCode); - String packagePath = packageName.replace(".", File.separator); - String rootPath = DirectoryManager.getJitDirectory(context.getFunctionType(), context.getFunctionId()); - return rootPath + File.separator + packagePath; - } - - /** - * 得到源文件的包名 - * - * @param javaSourceCode java类源文件 - * @return 包名 - */ - private String getPackage(JavaSourceCode javaSourceCode) { - String fullClassName = javaSourceCode.getFullClassName(); - int index = fullClassName.lastIndexOf('.'); - String packageName = fullClassName.substring(0, index); - return packageName; - } - - /** - * 得到编译上下文的编译结果存放目录 - * - * @param context 编译上下文 - * @return 结果存放目录 - */ - private String getOutDirPath(CompileContext context) { - return DirectoryManager.getJitDirectory(context.getFunctionType(), context.getFunctionId()); - } - /** * 解析所有的依赖jar包,将其转换为jar包的绝对路径列表。 * @@ -312,29 +211,18 @@ public class CompileServiceImpl implements CompileService { private List parseClassPathList(CompileContext context) { List refers = context.getRefers(); List referBoots = context.getReferBoots(); - List referJars = parseClassPathList(referBoots, refers); - return referJars; + return parseClassPathList(referBoots, refers); } /** * 解析所有的依赖jar包,将其转换为jar包的绝对路径列表。 - * - * @param referBoots - * @param refers - * @return */ private List parseClassPathList(List referBoots, List refers) { List referJars = new ArrayList<>(); //jar包解压 if (referBoots != null && referBoots.size() > 0) { - try { - List zips = UnZipManager.unZip(referBoots); - zips.forEach(name -> { - referJars.add(DirectoryManager.getUnZipBootJarDirectory() + File.separator + name); - }); - } catch (Exception ex) { - throw new RuntimeException("编译时解压boot包出错:", ex); - } + //从3rd目录下寻找第三方jar包 + referJars.addAll(findIn3rdDir(referBoots)); } if (refers != null && refers.size() > 0) { refers.forEach(name -> { @@ -344,32 +232,67 @@ public class CompileServiceImpl implements CompileService { return referJars; } - public void compile(String destDir, List refers, List javaFiles) { + /** + * 从3rd中找到依赖的jar并返回绝对路径 + */ + private Collection findIn3rdDir(List referBoots) { + List refers = new ArrayList<>(referBoots.size()); + String thirdDir = DirectoryManager.get3rdDirectory(); + Collection jarFiles = FileUtils.listFiles(new File(thirdDir), new String[]{"jar"}, false); + List refersBootsCopy = new ArrayList<>(referBoots); + for (File file : jarFiles) { + if (refersBootsCopy.isEmpty()) { + break; + } + Iterator iterator = refersBootsCopy.iterator(); + while (iterator.hasNext()) { + String referBoot = iterator.next(); + if (file.getName().startsWith(referBoot)) { + refers.add(thirdDir + File.separator + file.getName()); + iterator.remove(); + break; + } + } + } + if (!refersBootsCopy.isEmpty()) { + StringBuilder builder = new StringBuilder("未在目录中找到依赖的第三方jar包:"); + builder.append(thirdDir); + for (String refer : referBoots) { + builder.append(",").append(refer); + } + throw new JitCompileException(builder.toString()); + } + return refers; + } + + private JitJavaFileManager compile(List refers, List javaFiles) { DiagnosticCollector diagnosticCollector = new DiagnosticCollector<>(); - StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnosticCollector, null, null); + // 获取标准的Java文件管理器实例 + StandardJavaFileManager standardJavaFileManager = compiler.getStandardFileManager(diagnosticCollector, null, null); + // 初始化自定义Java文件管理器实例 + JitJavaFileManager jitJavaFileManager = new JitJavaFileManager(standardJavaFileManager); String classPath = StringUtils.join(refers, File.pathSeparator); + List options = new ArrayList<>(); - options.add("-d"); - options.add(destDir); options.add("-classpath"); options.add(classPath); - logger.info("compile outPath: {}", destDir); logger.info("compile classPath: {}", classPath); - boolean isSuccess = compiler.getTask(null, fileManager, diagnosticCollector, options, null, javaFiles).call(); + boolean isSuccess = compiler.getTask(null, jitJavaFileManager, diagnosticCollector, options, null, javaFiles).call(); logger.info("compile end: {}", isSuccess); try { - fileManager.close(); - } catch (Exception e) { - throw new RuntimeException(e.getMessage(), e); + jitJavaFileManager.close(); + } catch (IOException e) { + throw new JitIOException(e.getMessage(), e); } if (!isSuccess) { List> compileError = diagnosticCollector.getDiagnostics(); String errorInfo = getCompileErrorInfo(compileError); logCompileErrorClassSourceCode(compileError); - throw new RuntimeException("编译Java文件出错:" + errorInfo); + throw new JitCompileException("编译Java文件出错:" + errorInfo); } + return jitJavaFileManager; } private String getCompileErrorInfo(List> compileError) { @@ -417,7 +340,7 @@ public class CompileServiceImpl implements CompileService { } } } - logger.error("编译Java文件出错,涉及的类源码有:" + System.lineSeparator() + compileErrorRes.toString()); + logger.error("编译Java文件出错,涉及的类源码有:" + System.lineSeparator() + compileErrorRes); } } diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/JitCompileException.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/JitCompileException.java new file mode 100644 index 0000000000000000000000000000000000000000..60e0b7ef7caf7a717d86af9bcb514cec27803112 --- /dev/null +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/JitCompileException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.inspur.edp.jit.core.compile; + +import io.iec.edp.caf.commons.exception.CAFRuntimeException; +import io.iec.edp.caf.commons.exception.ExceptionLevel; + +/** + * @author Kaixuan Shi + * @since 2023/8/30 + */ +public class JitCompileException extends CAFRuntimeException { + + private static final String SERVICE_UNIT_CODE = "pfcommon"; + private static final String EXCEPTION_CODE = "GSP_JIT_COMPILE_0001"; + + public JitCompileException(String compileErrorMsg) { + super(SERVICE_UNIT_CODE, EXCEPTION_CODE, compileErrorMsg, null, ExceptionLevel.Error, false); + } +} diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/JitJavaFileManager.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/JitJavaFileManager.java new file mode 100644 index 0000000000000000000000000000000000000000..d96182091993894fffabbaae1f5001c923f596fc --- /dev/null +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/JitJavaFileManager.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.inspur.edp.jit.core.compile; + +import javax.tools.FileObject; +import javax.tools.ForwardingJavaFileManager; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author Kaixuan Shi + * @since 2023/7/7 + */ +public class JitJavaFileManager extends ForwardingJavaFileManager { + + //存放编译后的class + private final Map outputJavaFileObjectMap = new ConcurrentHashMap<>(); + + //存放编译后的类名及其对应的内部class的类名 + private final List innerClassNames = new ArrayList<>(); + + //返回类及其内部类 + public List getCompiledJavaFileObject(String className) { + List fileObjects = new ArrayList<>(); + BytesJavaFileObject bytesJavaFileObject = outputJavaFileObjectMap.get(className); + if (bytesJavaFileObject != null) { + fileObjects.add(bytesJavaFileObject); + innerClassNames.forEach(innerClassName -> { + if (innerClassName.startsWith(className)) { + fileObjects.add(outputJavaFileObjectMap.get(innerClassName)); + } + }); + } + return fileObjects; + } + + public JitJavaFileManager(JavaFileManager fileManager) { + super(fileManager); + } + + /** + * 这里是编译器返回的同(源)Java文件对象,替换为StringJavaFileObject实现 + */ + @Override + public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) { + BytesJavaFileObject javaFileObject = new BytesJavaFileObject(className, kind); + outputJavaFileObjectMap.put(className, javaFileObject); + if (className.contains("$")) { + innerClassNames.add(className); + } + return javaFileObject; + } + +} diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/Manifest.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/Manifest.java index a9866dab6f4d4b69278fac62bd61aa530a129367..894e4a50cf0c51ae9eb1ea8046b6c83dd69f69dd 100644 --- a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/Manifest.java +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/Manifest.java @@ -23,10 +23,18 @@ import java.util.Map; @Data public class Manifest { + /** + * 当前程序的JIT编译器版本 + */ + public static final String currentJitVersion = "2.0"; /** * 版本 */ private String version; + /** + * JIT编译器版本 + */ + private String jitVersion; /** * 编译时间 */ diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/ManifestUtil.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/ManifestUtil.java index 49bc96447d962fb510a2eed10dcaf21a0a60addf..1f7e5ca0a841d2febe0e203898efa57c2033dcbc 100644 --- a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/ManifestUtil.java +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/ManifestUtil.java @@ -27,6 +27,7 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.inspur.edp.jit.api.compile.CompileContext; import com.inspur.edp.jit.core.common.DirectoryManager; +import com.inspur.edp.jit.core.util.JitIOException; import io.iec.edp.caf.common.JSONSerializer; import org.apache.commons.io.FileUtils; @@ -47,6 +48,7 @@ public class ManifestUtil { public static void updateManifest(CompileContext context) { Manifest manifest = new Manifest(); manifest.setVersion(context.getVersion()); + manifest.setJitVersion(Manifest.currentJitVersion); manifest.setCompileTime(new Date()); manifest.setDescription(context.getDescription()); manifest.setExtendProperties(context.getExtendProperties()); @@ -55,16 +57,16 @@ public class ManifestUtil { File file = getManifestJsonFile(context.getFunctionType(), context.getFunctionId()); FileUtils.write(file, content, "utf-8", false); } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); + throw new JitIOException(e.getMessage(), e); } } /** - * 得到功能包的Manifest信息,如果功能包不存在或者manifest.json文件不存在,则返回null。 + * 得到功能包的Manifest信息,如果功能包不存在或者manifest.json文件不存在或者JIT版本不一致,则返回null。 * * @param functionType 功能包类型 * @param functionId 功能包Id - * @return 功能包的Manifest信息,如果功能包不存在或者manifest.json文件不存在,则返回null + * @return 功能包的Manifest信息,如果功能包不存在或者manifest.json文件不存在或者JIT版本不一致,则返回null */ public static Manifest getManifest(String functionType, String functionId) { File file = getManifestJsonFile(functionType, functionId); @@ -77,10 +79,11 @@ public class ManifestUtil { if (content.isEmpty()) { return new Manifest(); } - - return JSONSerializer.deserialize(content, Manifest.class); + //若jit版本不一致,则返回空manifest,通知外层该功能包缓存已不可用 + Manifest manifest = JSONSerializer.deserialize(content, Manifest.class); + return Manifest.currentJitVersion.equals(manifest.getJitVersion()) ? manifest : null; } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); + throw new JitIOException(e.getMessage(), e); } } diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/StringJavaFileObject.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/StringJavaFileObject.java index 02fc698900c49289be2197d4848186f04dc3bfd4..04af1a5c214e422d1a6d7f9fac89eca8994a1b84 100644 --- a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/StringJavaFileObject.java +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/compile/StringJavaFileObject.java @@ -15,9 +15,8 @@ */ package com.inspur.edp.jit.core.compile; - -import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; +import javax.tools.JavaFileObject; import java.net.URI; public class StringJavaFileObject extends SimpleJavaFileObject { diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/config/JitConfig.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/config/JitConfig.java index b44fc1ee7acc7a885217ce4d1ea03730b28da9bc..c763b22f7fb6f19b4cbcea0a1699bbb0a2c34ed6 100644 --- a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/config/JitConfig.java +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/config/JitConfig.java @@ -29,10 +29,9 @@ import org.springframework.context.annotation.Configuration; /** * 功能描述: * - * @ClassName: JitConfig - * @Author: Fynn Qi - * @Date: 2021/1/25 16:52 - * @Version: V1.0 + * @author Fynn Qi + * @version 1.0 + * @since 2021/1/25 16:52 */ @Configuration(value = "com.inspur.edp.jit.core.config.JitConfig", proxyBeanMethods = false) public class JitConfig { diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/ClassLoadManager.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/ClassLoadManager.java index 99e0ce59d88b3e02a14fe3e8276ccb31a159393a..2bba87dc6b8f513087dc9847f8c8f8b172c30c36 100644 --- a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/ClassLoadManager.java +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/ClassLoadManager.java @@ -17,45 +17,56 @@ package com.inspur.edp.jit.core.load; import com.inspur.edp.jit.core.common.DirectoryManager; +import com.inspur.edp.jit.core.compile.BytesJavaFileObject; +import com.inspur.edp.jit.core.util.JarUtil; -import java.io.IOException; -import java.util.HashMap; +import java.io.FileNotFoundException; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.stream.Collectors; public class ClassLoadManager { - private static Map> classLoaderMap = new ConcurrentHashMap<>(); + private static final ConcurrentMap> classLoaderMap = new ConcurrentHashMap<>(); + + public static void put(String functionType, String functionId, List javaFileObjects) { + Map classBytesMap = javaFileObjects.stream().collect(Collectors + .toConcurrentMap(BytesJavaFileObject::getClassName, BytesJavaFileObject::getClassBytes)); + + ConcurrentMap functionTypeMap = classLoaderMap + .computeIfAbsent(functionType, key -> new ConcurrentHashMap<>()); + functionTypeMap.put(functionId, new JitClassLoader(classBytesMap)); + } + + public static Class load(String functionType, String functionId, String className) { + classLoaderMap.computeIfAbsent(functionType, key -> new ConcurrentHashMap<>()); + JitClassLoader classLoader = classLoaderMap.get(functionType).computeIfAbsent(functionId, key -> { + Map classBytes = null; + try { + classBytes = getClassBytesFromCache(functionType, functionId); + } catch (FileNotFoundException e) { + throw new JitClassNotFoundException(functionType, functionId, className, e); + } + return new JitClassLoader(classBytes); + }); - public static Class load(String functionType, String functionId, String fullName) { - if (!classLoaderMap.containsKey(functionType)) { - classLoaderMap.put(functionType, new HashMap<>()); - } - JitClassLoader classLoader = null; - if (!classLoaderMap.get(functionType).containsKey(functionId)) { - String jitDirectory = DirectoryManager.getJitDirectory(functionType, functionId); - classLoader = new JitClassLoader(jitDirectory); - classLoaderMap.get(functionType).put(functionId, classLoader); - } else { - classLoader = classLoaderMap.get(functionType).get(functionId); - } try { - return classLoader.loadClass(fullName); + return classLoader.loadClass(className); } catch (ClassNotFoundException e) { - throw new RuntimeException("load class error ", e); + throw new JitClassNotFoundException(functionType, functionId, className, e); } } + private static Map getClassBytesFromCache(String functionType, String functionId) throws FileNotFoundException { + String jitDirectory = DirectoryManager.getJitDirectory(functionType, functionId); + return JarUtil.read(jitDirectory, functionId); + } public static void unLoad(String functionType, String functionId) { - if (classLoaderMap.containsKey(functionType) && classLoaderMap.get(functionType).containsKey(functionId)) { - JitClassLoader loader = classLoaderMap.get(functionType).get(functionId); + if (classLoaderMap.containsKey(functionType)) { classLoaderMap.get(functionType).remove(functionId); - try { - loader.close(); - } catch (IOException e) { - throw new RuntimeException("close class loader failure:", e); - } } } diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/ClassLoadServiceImpl.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/ClassLoadServiceImpl.java index 7b96854cbf589735865592aafd153e81b68c09c0..c42699a07a136e7ed1f96324b5678f96eac5949e 100644 --- a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/ClassLoadServiceImpl.java +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/ClassLoadServiceImpl.java @@ -20,7 +20,7 @@ import com.inspur.edp.jit.api.load.ClassloaderService; public class ClassLoadServiceImpl implements ClassloaderService { @Override - public Class load(String functionType, String functionId, String fullName) { + public Class load(String functionType, String functionId, String fullName) { return ClassLoadManager.load(functionType, functionId, fullName); } diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/JitClassLoader.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/JitClassLoader.java index 93d82fced915f1f9ddbd2a55a637331513b7f869..98742b1c55836b79d1a317b3eb4c511d02430fe8 100644 --- a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/JitClassLoader.java +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/JitClassLoader.java @@ -16,25 +16,43 @@ package com.inspur.edp.jit.core.load; -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.Map; -public class JitClassLoader extends URLClassLoader { +/** + * 加载StringJavaFileObject + */ +public class JitClassLoader extends ClassLoader { + + private final Map classBytesMap; + + //class字节码初始化JitClassLoader,入参不允许为null或空集合 + public JitClassLoader(Map classBytes) { + super(ClassLoadManager.class.getClassLoader()); + if (classBytes == null || classBytes.isEmpty()) { + throw new IllegalArgumentException("构造JitClassLoader的字节码集合不允许为空"); + } + this.classBytesMap = classBytes; + } - public JitClassLoader(String path) { - super(getURLsByPath(path), ClassLoadManager.class.getClassLoader()); + @Override + protected Class findClass(String className) throws ClassNotFoundException { + if (!classBytesMap.containsKey(className)) { + throw new ClassNotFoundException( + MessageFormat.format("the class to load:{0},current classes:{1}", className, getClassNames()) + ); + } + byte[] classBytes = this.classBytesMap.get(className); + return defineClass(className, classBytes, 0, classBytes.length); } - private static URL[] getURLsByPath(String path) { - File programRootDir = new File(path); - URL[] urls = new URL[1]; - try { - urls[0] = programRootDir.toURI().toURL(); - } catch (MalformedURLException e) { - throw new RuntimeException(e.getMessage(), e); + private String getClassNames() { + String[] names = classBytesMap.keySet().toArray(new String[0]); + StringBuilder builder = new StringBuilder(); + for (String name : names) { + builder.append(name).append(", "); } - return urls; + builder.delete(builder.length() - 2, builder.length()); + return builder.toString(); } } diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/JitClassNotFoundException.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/JitClassNotFoundException.java new file mode 100644 index 0000000000000000000000000000000000000000..6c7d7bcaa7f23d428fb6c56495bea90c4049b154 --- /dev/null +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/load/JitClassNotFoundException.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.inspur.edp.jit.core.load; + +import io.iec.edp.caf.commons.exception.CAFRuntimeException; +import io.iec.edp.caf.commons.exception.ExceptionLevel; + +import java.text.MessageFormat; + +/** + * @author Kaixuan Shi + * @since 2023/7/11 + */ +public class JitClassNotFoundException extends CAFRuntimeException { + + private static final String SERVICE_UNIT_CODE = "pfcommon"; + private static final String EXCEPTION_CODE = "GSP_JIT_LOAD_0001"; + + public JitClassNotFoundException(String functionType, String functionId, String className, Exception e) { + super(SERVICE_UNIT_CODE, EXCEPTION_CODE, MessageFormat.format("functionType:{0}, functionId:{1}, className:{2}", + functionType, functionId, className), e, ExceptionLevel.Error, false); + } + + public JitClassNotFoundException(String functionType, String functionId, String className) { + this(functionType, functionId, className, null); + } + +} diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/query/QueryServiceImpl.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/query/QueryServiceImpl.java index 98cf1fa0ba0ccccc58ac7445e60257d55d4ce360..0007787d5da687b4ebecbf0dcf76fa5d0a7068eb 100644 --- a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/query/QueryServiceImpl.java +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/query/QueryServiceImpl.java @@ -21,6 +21,7 @@ import com.inspur.edp.jit.api.query.QueryService; import com.inspur.edp.jit.core.common.DirectoryManager; import com.inspur.edp.jit.core.compile.Manifest; import com.inspur.edp.jit.core.compile.ManifestUtil; +import com.inspur.edp.jit.core.util.JitIOException; import org.apache.commons.io.FileUtils; import java.io.File; @@ -80,7 +81,7 @@ public class QueryServiceImpl implements QueryService { FileUtils.forceDelete(dir); } } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); + throw new JitIOException(e.getMessage(), e); } } @@ -93,7 +94,7 @@ public class QueryServiceImpl implements QueryService { FileUtils.forceDelete(dir); } } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); + throw new JitIOException(e.getMessage(), e); } } diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/util/JarUtil.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/util/JarUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..b8b4a82db37f16b173d395426947815ab45ed9f2 --- /dev/null +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/util/JarUtil.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.inspur.edp.jit.core.util; + +import com.inspur.edp.jit.core.common.DirectoryManager; +import com.inspur.edp.jit.core.compile.BytesJavaFileObject; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; +import java.util.jar.JarOutputStream; + +/** + * @author Kaixuan Shi + * @since 2023/8/24 + */ +public class JarUtil { + + //JAR文件后缀,避免采用.jar被轻易识别 + private final static String JAR_FILE_EXTENSION = ".jit"; + //JAR文件中目录分隔符,正斜杠(/),不区分操作系统 + private final static char JAR_FILE_SEPARATOR = '/'; + private final static String CLASS_FILE_EXTENSION = ".class"; + + private final static Logger logger = LoggerFactory.getLogger(JarUtil.class); + + /** + * 保存class字节码至目录的jar类型文件中 + * + * @param dir 文件目录 + * @param fileName 文件名,不带后缀 + * @param compiledClasses 编译后的class字节码 + */ + public static void write(String dir, String fileName, List compiledClasses) { + String jarFileName = getJARFileName(dir, fileName); + try (JarOutputStream jarOutputStream = new JarOutputStream(Files.newOutputStream(Paths.get(jarFileName)))) { + for (BytesJavaFileObject javaFileObject : compiledClasses) { + // 写入类的字节码到JAR文件 + jarOutputStream.putNextEntry(new JarEntry(getJARFileEntryName(javaFileObject.getClassName()))); + jarOutputStream.write(javaFileObject.getClassBytes()); + jarOutputStream.closeEntry(); + } + } catch (IOException e) { + throw new JitIOException(e.getMessage(), e); + } + } + + /** + * 从JAR中读取类字节码 + * + * @param dir 文件目录 + * @param fileName 文件名,不带后缀 + * @return 类名及对应的字节码。文件不存在则返回null + * @throws FileNotFoundException 文件不存在 + */ + public static Map read(String dir, String fileName) throws FileNotFoundException { + String jarFileName = getJARFileName(dir, fileName); + File jarFile = new File(jarFileName); + if (!jarFile.exists()) { + throw new FileNotFoundException(jarFileName); + } + try (JarInputStream jarInputStream = new JarInputStream(Files.newInputStream(Paths.get(jarFileName)))) { + Map classMap = new HashMap<>(); + JarEntry jarEntry; + while ((jarEntry = jarInputStream.getNextJarEntry()) != null) { + if (!jarEntry.isDirectory() && jarEntry.getName().endsWith(CLASS_FILE_EXTENSION)) { + String className = jarEntry.getName() + .substring(0, jarEntry.getName().length() - CLASS_FILE_EXTENSION.length()) + .replace(JAR_FILE_SEPARATOR, '.'); + byte[] classBytes = IOUtils.toByteArray(jarInputStream); + classMap.put(className, classBytes); + } + } + return classMap; + } catch (IOException e) { + throw new JitIOException(e.getMessage(), e); + } + } + + /** + * 根据全限定类名获取其在JAR文件中的路径 + */ + private static String getJARFileEntryName(String className) { + return className.replace('.', JAR_FILE_SEPARATOR) + CLASS_FILE_EXTENSION; + } + + /** + * @param dir 文件目录 + * @param fileName 文件名,不带后缀 + * @return 完整文件路径,文件名带后缀 + */ + private static String getJARFileName(String dir, String fileName) { + return DirectoryManager.joinFilePath(dir, fileName + JAR_FILE_EXTENSION); + } +} diff --git a/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/util/JitIOException.java b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/util/JitIOException.java new file mode 100644 index 0000000000000000000000000000000000000000..9ac81493a73e2e6a737c5fa7c77c0ff2541612b3 --- /dev/null +++ b/rest-api-jit-core/src/main/java/com/inspur/edp/jit/core/util/JitIOException.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.inspur.edp.jit.core.util; + +import io.iec.edp.caf.commons.exception.CAFRuntimeException; +import io.iec.edp.caf.commons.exception.ExceptionLevel; + +import java.io.IOException; + +/** + * @author Kaixuan Shi + * @since 2023/8/24 + */ +public class JitIOException extends CAFRuntimeException { + + private static final String SERVICE_UNIT_CODE = "pfcommon"; + private static final String EXCEPTION_CODE = "GSP_JIT_IO_0001"; + + public JitIOException(String path, IOException ioException) { + super(SERVICE_UNIT_CODE, EXCEPTION_CODE, path, ioException, ExceptionLevel.Error, false); + } + +} diff --git a/rest-api-jit-core/src/test/java/com/inspur/edp/jit/core/load/ClassLoadServiceTest.java b/rest-api-jit-core/src/test/java/com/inspur/edp/jit/core/load/ClassLoadServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d77e4ce4d3b75d24e97858ff54eb05f601031aac --- /dev/null +++ b/rest-api-jit-core/src/test/java/com/inspur/edp/jit/core/load/ClassLoadServiceTest.java @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.inspur.edp.jit.core.load; + +import com.inspur.edp.jit.api.compile.CompileContext; +import com.inspur.edp.jit.api.compile.CompileService; +import com.inspur.edp.jit.api.compile.JavaSourceCode; +import com.inspur.edp.jit.api.load.ClassloaderService; +import com.inspur.edp.jit.api.query.FunctionSummaryInfo; +import com.inspur.edp.jit.api.query.QueryService; +import com.inspur.edp.jit.core.common.DirectoryManager; +import com.inspur.edp.jit.core.compile.CompileServiceImpl; +import com.inspur.edp.jit.core.query.QueryServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.commons.lang3.reflect.MethodUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.RepeatedTest; +import org.junit.jupiter.api.Test; +import org.springframework.core.io.ClassPathResource; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentMap; +import java.util.stream.Collectors; + +/** + * @author Kaixuan Shi + * @since 2023/8/21 + */ +@Slf4j +public class ClassLoadServiceTest { + + private final CompileService compileService = new CompileServiceImpl(); + private final ClassloaderService classloaderService = new ClassLoadServiceImpl(); + private final QueryService queryService = new QueryServiceImpl(); + private final static String FUNCTION_TYPE = "eapi"; + private final static String HISTORY_FUNCTION_TYPE = "oldJit"; + private final static String HISTORY_FUNCTION_ID = "5f88f4a7-ee63-4e00-8cd3-8c5f90c85355"; + + @BeforeAll + public static void prepare() throws IllegalAccessException { + log.info("执行测试前初始化"); + //将根目录设置为当前resources目录 + FieldUtils.writeDeclaredStaticField(DirectoryManager.class, "HOME_DIR", Paths.get(System.getProperty("user.dir"), "src", "test", "resources").toString(), true); + //将启动中事件创建的目录创建一下,见:com.inspur.edp.jit.core.common.StartManager + String jitBaseDirectory = DirectoryManager.getJitBaseDirectory(); + DirectoryManager.createDir(jitBaseDirectory); + } + + /** + * 测试QueryService的query及历史jit版本生成的cache能否正确查询并返回指定结果 + */ + @Test + public void testOldJitVersionFunctionCache() { + List functionSummaryInfos = queryService.query(HISTORY_FUNCTION_TYPE); + Assertions.assertEquals(functionSummaryInfos.size(), 1); + FunctionSummaryInfo functionSummaryInfo = queryService.query(HISTORY_FUNCTION_TYPE, HISTORY_FUNCTION_ID); + functionSummaryInfos.add(functionSummaryInfo); + for (FunctionSummaryInfo summaryInfo : functionSummaryInfos) { + Assertions.assertEquals(summaryInfo.getFunctionType(), HISTORY_FUNCTION_TYPE); + Assertions.assertEquals(summaryInfo.getFunctionId(), HISTORY_FUNCTION_ID); + Assertions.assertNull(summaryInfo.getDescription()); + Assertions.assertNull(summaryInfo.getCompileTime()); + Assertions.assertNull(summaryInfo.getVersion()); + } + } + + /** + * 测试CompileService#compile(CompileContext)的编译并加载类 + */ + @RepeatedTest(2) + public void testSingleContextCompile() throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + //编译类 + JavaSourceCode javaSourceCode = new JavaSourceCode(); + javaSourceCode.setFullClassName("com.inspur.demo.Hello"); + javaSourceCode.setSourceCode(getSourceCode("Hello.java")); + JavaSourceCode interfaceSource = new JavaSourceCode(); + interfaceSource.setFullClassName("com.inspur.gs.scm.sd.salesorder.rest.ZUserVoExtend1Service"); + interfaceSource.setSourceCode(getSourceCode("ZUserVoExtend1Service.java")); + JavaSourceCode implSource = new JavaSourceCode(); + implSource.setFullClassName("com.inspur.gs.scm.sd.salesorder.rest.ZUserVoExtend1ServiceImpl"); + implSource.setSourceCode(getSourceCode("ZUserVoExtend1ServiceImpl.java")); + + List sourceCodes = new ArrayList<>(); + sourceCodes.add(javaSourceCode); + sourceCodes.add(interfaceSource); + sourceCodes.add(implSource); + + CompileContext compileContext = new CompileContext(); + compileContext.setFunctionType(FUNCTION_TYPE); + compileContext.setFunctionId(UUID.randomUUID().toString()); + compileContext.setVersion(compileContext.getFunctionId() + "#1.0.2"); + compileContext.setDescription("测试生成"); + compileContext.setSourceCodes(sourceCodes); + compileContext.setRefers(getRefers()); + compileContext.setReferBoots(getReferBoots()); + Map extendProperties = new HashMap<>(); + extendProperties.put(FUNCTION_TYPE, HISTORY_FUNCTION_ID); + compileContext.setExtendProperties(extendProperties); + + compileService.compile(compileContext); + + //1、加载类 + { + Class clazz0 = classloaderService.load(compileContext.getFunctionType(), compileContext.getFunctionId(), + compileContext.getSourceCodes().get(0).getFullClassName()); + Assertions.assertEquals( + MethodUtils.invokeMethod(clazz0.newInstance(), "createSession"), "createSession"); + Class clazz2 = classloaderService.load(compileContext.getFunctionType(), compileContext.getFunctionId(), + compileContext.getSourceCodes().get(2).getFullClassName()); + Assertions.assertEquals( + MethodUtils.invokeMethod(clazz2.newInstance(), "createSession"), "createSession"); + + //加载内部类 + Class innerClazz = classloaderService.load(compileContext.getFunctionType(), compileContext.getFunctionId(), + compileContext.getSourceCodes().get(0).getFullClassName() + "$InnerClass"); + Assertions.assertEquals( + MethodUtils.invokeMethod( + innerClazz.getDeclaredConstructors()[0] + .newInstance(clazz0.newInstance()), "createSession" + ), "createSession" + ); + //加载不存在的类 + Assertions.assertThrows(JitClassNotFoundException.class, () -> + classloaderService.load("notExist", "no", "this.is.a.not.exist.class") + ); + } + + //测试类卸载接口 + testUnLoadService(compileContext); + + //测试从功能包缓存中加载类 + FunctionSummaryInfo functionSummaryInfo = queryService.query(compileContext.getFunctionType(), compileContext.getFunctionId()); + Assertions.assertEquals(functionSummaryInfo.getVersion(), compileContext.getVersion()); + Assertions.assertEquals(functionSummaryInfo.getExtendProperties().get(FUNCTION_TYPE), HISTORY_FUNCTION_ID); + //2、加载类,从1中复制 + { + Class clazz0 = classloaderService.load(compileContext.getFunctionType(), compileContext.getFunctionId(), + compileContext.getSourceCodes().get(0).getFullClassName()); + Assertions.assertEquals( + MethodUtils.invokeMethod(clazz0.newInstance(), "createSession"), "createSession"); + Class clazz2 = classloaderService.load(compileContext.getFunctionType(), compileContext.getFunctionId(), + compileContext.getSourceCodes().get(2).getFullClassName()); + Assertions.assertEquals( + MethodUtils.invokeMethod(clazz2.newInstance(), "createSession"), "createSession"); + + //加载内部类 + Class innerClazz = classloaderService.load(compileContext.getFunctionType(), compileContext.getFunctionId(), + compileContext.getSourceCodes().get(0).getFullClassName() + "$InnerClass"); + Assertions.assertEquals( + MethodUtils.invokeMethod( + innerClazz.getDeclaredConstructors()[0] + .newInstance(clazz0.newInstance()), "createSession" + ), "createSession" + ); + //加载不存在的类 + Assertions.assertThrows(JitClassNotFoundException.class, () -> + classloaderService.load("notExist", "no", "this.is.a.not.exist.class") + ); + } + + } + + /** + * 测试CompileServiceImpl#batchCompile(List)的批量编译并加载类 + */ + @RepeatedTest(2) + public void testMultiContextsBatchCompile() throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + //编译类 + JavaSourceCode javaSourceCode = new JavaSourceCode(); + javaSourceCode.setFullClassName("com.inspur.demo.Hello"); + javaSourceCode.setSourceCode(getSourceCode("Hello.java")); + + List sourceCodes1 = new ArrayList<>(); + sourceCodes1.add(javaSourceCode); + + JavaSourceCode interfaceSource = new JavaSourceCode(); + interfaceSource.setFullClassName("com.inspur.gs.scm.sd.salesorder.rest.ZUserVoExtend1Service"); + interfaceSource.setSourceCode(getSourceCode("ZUserVoExtend1Service.java")); + JavaSourceCode implSource = new JavaSourceCode(); + implSource.setFullClassName("com.inspur.gs.scm.sd.salesorder.rest.ZUserVoExtend1ServiceImpl"); + implSource.setSourceCode(getSourceCode("ZUserVoExtend1ServiceImpl.java")); + + List sourceCodes2 = new ArrayList<>(); + sourceCodes2.add(interfaceSource); + sourceCodes2.add(implSource); + + List referBoots = getReferBoots(); + List refers = getRefers(); + + CompileContext compileContext1 = new CompileContext(); + compileContext1.setFunctionType(FUNCTION_TYPE); + compileContext1.setFunctionId("context1"); + compileContext1.setVersion(compileContext1.getFunctionId() + "#1.0.2"); + compileContext1.setDescription("测试生成1"); + compileContext1.setSourceCodes(sourceCodes1); + compileContext1.setRefers(refers); + compileContext1.setReferBoots(referBoots); + + CompileContext compileContext2 = new CompileContext(); + compileContext2.setFunctionType(FUNCTION_TYPE); + compileContext2.setFunctionId("context2"); + compileContext2.setVersion(compileContext2.getFunctionId() + "#1.0.2"); + compileContext2.setDescription("测试生成2"); + compileContext2.setSourceCodes(sourceCodes2); + compileContext2.setRefers(refers); + compileContext2.setReferBoots(referBoots); + //测试不同Context下相同类名的隔离性 + CompileContext compileContext3 = new CompileContext(); + compileContext3.setFunctionType(FUNCTION_TYPE); + compileContext3.setFunctionId("context3"); + compileContext3.setVersion(compileContext3.getFunctionId() + "#1.0.2"); + compileContext3.setDescription("测试生成3"); + compileContext3.setSourceCodes(sourceCodes2); + compileContext3.setRefers(refers); + compileContext3.setReferBoots(referBoots); + + List contexts = new ArrayList<>(); + contexts.add(compileContext1); + contexts.add(compileContext2); + contexts.add(compileContext3); + + compileService.batchCompile(contexts); + + //1、加载类 + { + Class clazz1 = classloaderService.load(compileContext1.getFunctionType(), compileContext1.getFunctionId(), + compileContext1.getSourceCodes().get(0).getFullClassName()); + Assertions.assertEquals( + MethodUtils.invokeMethod(clazz1.newInstance(), "createSession"), "createSession" + ); + Class clazz2 = classloaderService.load(compileContext2.getFunctionType(), compileContext2.getFunctionId(), + compileContext2.getSourceCodes().get(1).getFullClassName()); + Assertions.assertEquals( + MethodUtils.invokeMethod(clazz2.newInstance(), "createSession"), "createSession" + ); + Class clazz3 = classloaderService.load(compileContext3.getFunctionType(), compileContext3.getFunctionId(), + compileContext3.getSourceCodes().get(1).getFullClassName()); + Assertions.assertEquals( + MethodUtils.invokeMethod(clazz3.newInstance(), "createSession"), "createSession" + ); + + //加载内部类 + Class innerClazz = classloaderService.load(compileContext1.getFunctionType(), compileContext1.getFunctionId(), + compileContext1.getSourceCodes().get(0).getFullClassName() + "$InnerClass"); + Assertions.assertEquals( + MethodUtils.invokeMethod( + innerClazz.getDeclaredConstructors()[0] + .newInstance(clazz1.newInstance()), "createSession" + ), "createSession" + ); + //测试不同FunctionId的类隔离性 + Assertions.assertThrows(JitClassNotFoundException.class, + () -> classloaderService.load(compileContext2.getFunctionType(), compileContext2.getFunctionId(), + compileContext1.getSourceCodes().get(0).getFullClassName())); + } + //测试卸载类接口 + for (CompileContext context : contexts) { + testUnLoadService(context); + } + //测试从功能包中加载类 + List summaryInfos = queryService.query(FUNCTION_TYPE); + //过滤出该测试类中的contexts对应的功能包 + for (CompileContext context : contexts) { + FunctionSummaryInfo contextSummaryInfo = summaryInfos.stream().filter(summaryInfo -> + summaryInfo.getFunctionId().equals(context.getFunctionId())).collect(Collectors.toList()) + .get(0); + Assertions.assertEquals(contextSummaryInfo.getVersion(), context.getVersion()); + } + + //2、加载类 + { + Class clazz1 = classloaderService.load(compileContext1.getFunctionType(), compileContext1.getFunctionId(), + compileContext1.getSourceCodes().get(0).getFullClassName()); + Assertions.assertEquals( + MethodUtils.invokeMethod(clazz1.newInstance(), "createSession"), "createSession" + ); + Class clazz2 = classloaderService.load(compileContext2.getFunctionType(), compileContext2.getFunctionId(), + compileContext2.getSourceCodes().get(1).getFullClassName()); + Assertions.assertEquals( + MethodUtils.invokeMethod(clazz2.newInstance(), "createSession"), "createSession" + ); + Class clazz3 = classloaderService.load(compileContext3.getFunctionType(), compileContext3.getFunctionId(), + compileContext3.getSourceCodes().get(1).getFullClassName()); + Assertions.assertEquals( + MethodUtils.invokeMethod(clazz3.newInstance(), "createSession"), "createSession" + ); + + //加载内部类 + Class innerClazz = classloaderService.load(compileContext1.getFunctionType(), compileContext1.getFunctionId(), + compileContext1.getSourceCodes().get(0).getFullClassName() + "$InnerClass"); + Assertions.assertEquals( + MethodUtils.invokeMethod( + innerClazz.getDeclaredConstructors()[0] + .newInstance(clazz1.newInstance()), "createSession" + ), "createSession" + ); + //测试不同FunctionId的类隔离性 + Assertions.assertThrows(JitClassNotFoundException.class, + () -> classloaderService.load(compileContext2.getFunctionType(), compileContext2.getFunctionId(), + compileContext1.getSourceCodes().get(0).getFullClassName())); + } + + } + + @AfterAll + public static void deleteCreatedFiles() throws IOException { + String generatedFunctionDir = DirectoryManager.getJitDirectory(FUNCTION_TYPE); + log.info("清理测试生成文件夹:" + generatedFunctionDir); + if (new File(generatedFunctionDir).exists()) { + FileUtils.forceDelete(new File(generatedFunctionDir)); + } + } + + /** + * 测试类卸载接口 + */ + @SuppressWarnings("unchecked") + private void testUnLoadService(CompileContext compileContext) throws IllegalAccessException { + Map> classLoadMap = + (ConcurrentMap>) FieldUtils + .readStaticField(ClassLoadManager.class, "classLoaderMap", true); + Assertions.assertTrue(classLoadMap.get(compileContext.getFunctionType()).containsKey(compileContext.getFunctionId())); + classloaderService.unload(compileContext.getFunctionType(), compileContext.getFunctionId()); + Assertions.assertFalse(classLoadMap.get(compileContext.getFunctionType()).containsKey(compileContext.getFunctionId())); + } + + private List getReferBoots() { + List referBoots = new ArrayList<>(); + referBoots.add("jackson-databind"); + referBoots.add("jackson-core"); + referBoots.add("jakarta.ws.rs-api"); + referBoots.add("lombok"); + return referBoots; + } + + private List getRefers() { + List refers = new ArrayList<>(); + refers.add("refers" + File.separator + "cdp-sgf-base.jar"); + refers.add("refers" + File.separator + "cdp-sgf-api.jar"); + refers.add("refers" + File.separator + "jit-api-1.0.2.jar"); + return refers; + } + + public static String getSourceCode(String fileName) { + String resourceLocation = "source_code" + File.separator + fileName; + ClassPathResource classPathResource = new ClassPathResource(resourceLocation); + try { + InputStream inputStream = classPathResource.getInputStream(); + String code = IOUtils.toString(inputStream, StandardCharsets.UTF_8); + inputStream.close(); + return code; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + +} diff --git a/rest-api-jit-core/src/test/java/com/inspur/edp/jit/core/load/ExceptionTest.java b/rest-api-jit-core/src/test/java/com/inspur/edp/jit/core/load/ExceptionTest.java new file mode 100644 index 0000000000000000000000000000000000000000..02eb75971061d7393c7041f39b16d5be6cee3016 --- /dev/null +++ b/rest-api-jit-core/src/test/java/com/inspur/edp/jit/core/load/ExceptionTest.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.inspur.edp.jit.core.load; + +import com.inspur.edp.jit.api.compile.CompileContext; +import com.inspur.edp.jit.api.compile.CompileService; +import com.inspur.edp.jit.api.compile.JavaSourceCode; +import com.inspur.edp.jit.core.compile.CompileServiceImpl; +import com.inspur.edp.jit.core.util.JitIOException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * @author Kaixuan Shi + * @since 2023/8/30 + */ +public class ExceptionTest { + private final CompileService compileService = new CompileServiceImpl(); + private final static String FUNCTION_TYPE = "eapi"; + + + @Test + public void testCompileException() { + //编译类 + JavaSourceCode javaSourceCode = new JavaSourceCode(); + javaSourceCode.setFullClassName("com.inspur.demo.Hello"); + javaSourceCode.setSourceCode(ClassLoadServiceTest.getSourceCode("Hello.java")); + + List sourceCodes = new ArrayList<>(); + sourceCodes.add(javaSourceCode); + + CompileContext compileContext = new CompileContext(); + compileContext.setFunctionType(FUNCTION_TYPE); + compileContext.setFunctionId(UUID.randomUUID().toString()); + compileContext.setVersion(compileContext.getFunctionId() + "#1.0.2"); + compileContext.setDescription("测试生成"); + compileContext.setSourceCodes(sourceCodes); + + Assertions.assertThrows(RuntimeException.class, () -> compileService.compile(compileContext)); + } + + @Test + public void testIOException() { + String errorMessage = "path"; + try { + throw new JitIOException(errorMessage, new IOException("innerException")); + + } catch (Exception e) { + Assertions.assertTrue(e instanceof JitIOException); + Assertions.assertEquals(errorMessage, e.getMessage()); + Assertions.assertTrue(e.getCause() instanceof IOException); + } + } +} diff --git a/rest-api-jit-core/src/test/resources/refers/cdp-sgf-api.jar b/rest-api-jit-core/src/test/resources/refers/cdp-sgf-api.jar new file mode 100644 index 0000000000000000000000000000000000000000..168e50aee60f8002119e618627aa9798494e4f44 Binary files /dev/null and b/rest-api-jit-core/src/test/resources/refers/cdp-sgf-api.jar differ diff --git a/rest-api-jit-core/src/test/resources/refers/cdp-sgf-base.jar b/rest-api-jit-core/src/test/resources/refers/cdp-sgf-base.jar new file mode 100644 index 0000000000000000000000000000000000000000..7dbe194b5c40ce85d7755e7bc377212c2280575a Binary files /dev/null and b/rest-api-jit-core/src/test/resources/refers/cdp-sgf-base.jar differ diff --git a/rest-api-jit-core/src/test/resources/refers/jit-api-1.0.2.jar b/rest-api-jit-core/src/test/resources/refers/jit-api-1.0.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..c0b7cc4ecfa93c510bfcfc8c355496f4d3a46d28 Binary files /dev/null and b/rest-api-jit-core/src/test/resources/refers/jit-api-1.0.2.jar differ diff --git a/rest-api-jit-core/src/test/resources/runtime/3rd/jackson-core-2.14.1.jar b/rest-api-jit-core/src/test/resources/runtime/3rd/jackson-core-2.14.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..cc025836227e860986d604a1d763d981fc465787 Binary files /dev/null and b/rest-api-jit-core/src/test/resources/runtime/3rd/jackson-core-2.14.1.jar differ diff --git a/rest-api-jit-core/src/test/resources/runtime/3rd/jackson-databind-2.14.1.jar b/rest-api-jit-core/src/test/resources/runtime/3rd/jackson-databind-2.14.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..1ac8096422b80872cf7b5f7de413ae985f5e5c6e Binary files /dev/null and b/rest-api-jit-core/src/test/resources/runtime/3rd/jackson-databind-2.14.1.jar differ diff --git a/rest-api-jit-core/src/test/resources/runtime/3rd/jakarta.ws.rs-api-2.1.6.jar b/rest-api-jit-core/src/test/resources/runtime/3rd/jakarta.ws.rs-api-2.1.6.jar new file mode 100644 index 0000000000000000000000000000000000000000..4850659bb6c9f2872836f4d0d5f4600da774d440 Binary files /dev/null and b/rest-api-jit-core/src/test/resources/runtime/3rd/jakarta.ws.rs-api-2.1.6.jar differ diff --git a/rest-api-jit-core/src/test/resources/runtime/3rd/lombok-1.18.16.jar b/rest-api-jit-core/src/test/resources/runtime/3rd/lombok-1.18.16.jar new file mode 100644 index 0000000000000000000000000000000000000000..20f85ff2e00325f61d3987233be813794c30986b Binary files /dev/null and b/rest-api-jit-core/src/test/resources/runtime/3rd/lombok-1.18.16.jar differ diff --git a/rest-api-jit-core/src/test/resources/source_code/ErrorClass.java b/rest-api-jit-core/src/test/resources/source_code/ErrorClass.java new file mode 100644 index 0000000000000000000000000000000000000000..aebede3c0a4efa26c9cd5ec8e039ef4d54407c03 --- /dev/null +++ b/rest-api-jit-core/src/test/resources/source_code/ErrorClass.java @@ -0,0 +1,11 @@ +package com.inspur.demo; + +/** + * 该类存在语法错误,用于测试编译异常 + */ +public class ErrorClass { + public createSession() { + return "createSession"; + } + +} \ No newline at end of file diff --git a/rest-api-jit-core/src/test/resources/source_code/Hello.java b/rest-api-jit-core/src/test/resources/source_code/Hello.java new file mode 100644 index 0000000000000000000000000000000000000000..2b2f391bdd09e952861a8dd32071709bca79007d --- /dev/null +++ b/rest-api-jit-core/src/test/resources/source_code/Hello.java @@ -0,0 +1,18 @@ +package com.inspur.demo; + +import com.inspur.edp.jit.api.compile.CompileContext; + +/** + * 此类继承测试运行时环境中已有的一个类,判断继承的父类是否能被正确找到 + */ +public class Hello extends CompileContext { + public String createSession() { + return "createSession"; + } + + public class InnerClass { + public String createSession() { + return "createSession"; + } + } +} \ No newline at end of file diff --git a/rest-api-jit-core/src/test/resources/source_code/ZUserVoExtend1Service.java b/rest-api-jit-core/src/test/resources/source_code/ZUserVoExtend1Service.java new file mode 100644 index 0000000000000000000000000000000000000000..b099de62c96ff4ef0fe9264ee662f7a83d8f40db --- /dev/null +++ b/rest-api-jit-core/src/test/resources/source_code/ZUserVoExtend1Service.java @@ -0,0 +1,112 @@ +package com.inspur.gs.scm.sd.salesorder.rest; + +import com.fasterxml.jackson.databind.JsonNode; +import com.inspur.edp.sgf.api.annotation.EapiService; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; + +@EapiService(id = "8ac64c96-5c03-45ff-bd0b-0fa2aefa9f90", code = "ZUserVoExtend1") +@Path("/") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface ZUserVoExtend1Service { + + @POST + @Path("/service/createsession") + @Produces(MediaType.TEXT_PLAIN) + public String createSession(); + + @POST + @Path("/") + public Object create(JsonNode node); + + @PUT + @Path("/service/edit/{dataId}") + public Object edit(@PathParam("dataId") String dataId, JsonNode node); + + @DELETE + @Path("/{dataId}") + public void delete(); + + @DELETE + @Path("/") + public void batchDelete(@QueryParam("ids") String ids); + + @PATCH + @Path("/") + public Object update(JsonNode node); + + @GET + @Path("/{dataId}") + public Object retrieve(@PathParam("dataId") String dataId); + + @PUT + @Path("/service/retrieve/{dataId}") + public Object retrieveWithChildPagination(@PathParam("dataId") String dataId, JsonNode node); + + @PUT + @Path("/service/querychild") + public Object queryChild(JsonNode node); + + @GET + @Path("/") + public Object query(@QueryParam("entityFilter") String entityFilter); + + @PUT + @Path("/") + public Object save(JsonNode node); + + @POST + @Path("/service/cancel") + public void cancel(); + + @GET + @Path("/elementhelps/{labelId}") + public Object getElementHelp(@PathParam("labelId") String labelId, @QueryParam("nodeCode") String nodeCode, @QueryParam("queryParam") String queryParam); + + @POST + @Path("/{rootId}/userdetail") + public Object createChildUserDetail(@PathParam("rootId") String rootId, JsonNode node); + + @DELETE + @Path("/{rootId}/userdetail/{userDetail}Id") + public void deleteChildUserDetail(@PathParam("rootId") String rootId, @PathParam("userDetailId") String userDetailId); + + @PUT + @Path("/extension/delete/{dataId}") + public Object extend_Delete(JsonNode node); + + @PUT + @Path("/extension/batchdelete") + public Object extend_BatchDelete(@QueryParam("ids") String ids, JsonNode node); + + @PUT + @Path("/extension/retrieve/{dataId}") + public Object extend_Retrieve(@PathParam("dataId") String dataId, JsonNode node); + + @PUT + @Path("/extension/query") + public Object extend_Query(@QueryParam("entityFilter") String entityFilter, JsonNode node); + + @PUT + @Path("/extension/elementhelps") + public Object extend_GetElementHelp(JsonNode node); + + @PUT + @Path("/extension/{rootId}/userdetail/{userDetailId}") + public Object extend_DeleteChildUserDetail(@PathParam("rootId") String rootId, @PathParam("userDetailId") String userDetailId, JsonNode node); + + @PUT + @Path("/service/datadeser") + public Object dataDeser(JsonNode node); + + @PUT + @Path("/service/submit") + public Object submit(JsonNode node); + + @PUT + @Path("/service/t1") + public Object t1(JsonNode node); + +} \ No newline at end of file diff --git a/rest-api-jit-core/src/test/resources/source_code/ZUserVoExtend1ServiceImpl.java b/rest-api-jit-core/src/test/resources/source_code/ZUserVoExtend1ServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..8825eef4d52c4d26d6d09142b460a8d5e4c04543 --- /dev/null +++ b/rest-api-jit-core/src/test/resources/source_code/ZUserVoExtend1ServiceImpl.java @@ -0,0 +1,318 @@ +package com.inspur.gs.scm.sd.salesorder.rest; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.inspur.edp.sgf.api.service.ServiceInvoker; +import lombok.Data; + +import java.util.ArrayList; +import java.util.Objects; + +@Data +public class ZUserVoExtend1ServiceImpl implements ZUserVoExtend1Service { + + protected String voId = "8ac64c96-5c03-45ff-bd0b-0fa2aefa9f90"; + + protected String voCode = "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1"; + + @Override + public String createSession() { + return "createSession"; + } + + @Override + public Object create(JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(Objects.isNull(node) ? null : node.get("requestInfo")); + jsonNodes.add(Objects.isNull(node) ? null : node.get("defaultValue")); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Create", jsonNodes); + } + + @Override + public Object edit(String dataId, JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(node); + jsonNodes.add(mapper.valueToTree(dataId)); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Edit", jsonNodes); + } + + @Override + public void delete() { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + } catch (Exception e) { + throw new RuntimeException(e); + } + ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Delete", jsonNodes); + } + + @Override + public void batchDelete(String ids) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(mapper.valueToTree(ids)); + } catch (Exception e) { + throw new RuntimeException(e); + } + ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&BatchDelete", jsonNodes); + } + + @Override + public Object update(JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(Objects.isNull(node) ? null : node.get("requestInfo")); + jsonNodes.add(Objects.isNull(node) ? null : node.get("changeDetail")); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Update", jsonNodes); + } + + @Override + public Object retrieve(String dataId) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(mapper.valueToTree(dataId)); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Retrieve", jsonNodes); + } + + @Override + public Object retrieveWithChildPagination(String dataId, JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(Objects.isNull(node) ? null : node.get("requestInfo")); + jsonNodes.add(mapper.valueToTree(dataId)); + jsonNodes.add(Objects.isNull(node) ? null : node.get("retrieveParam")); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&RetrieveWithChildPagination", jsonNodes); + } + + @Override + public Object queryChild(JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(Objects.isNull(node) ? null : node.get("requestInfo")); + jsonNodes.add(Objects.isNull(node) ? null : node.get("nodeCodes")); + jsonNodes.add(Objects.isNull(node) ? null : node.get("ids")); + jsonNodes.add(Objects.isNull(node) ? null : node.get("pagination")); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&QueryChild", jsonNodes); + } + + @Override + public Object query(String entityFilter) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(mapper.valueToTree(entityFilter)); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Query", jsonNodes); + } + + @Override + public Object save(JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(node); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&保存", jsonNodes); + } + + @Override + public void cancel() { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + } catch (Exception e) { + throw new RuntimeException(e); + } + ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Cancel", jsonNodes); + } + + @Override + public Object getElementHelp(String labelId, String nodeCode, String queryParam) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(mapper.valueToTree(labelId)); + jsonNodes.add(mapper.valueToTree(nodeCode)); + jsonNodes.add(mapper.valueToTree(queryParam)); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&ElementHelp", jsonNodes); + } + + @Override + public Object createChildUserDetail(String rootId, JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(node); + jsonNodes.add(mapper.valueToTree(rootId)); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&CreateChild##UserDetail", jsonNodes); + } + + @Override + public void deleteChildUserDetail(String rootId, String userDetailId) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(mapper.valueToTree(rootId)); + jsonNodes.add(mapper.valueToTree(userDetailId)); + } catch (Exception e) { + throw new RuntimeException(e); + } + ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&DeleteChild##UserDetail", jsonNodes); + } + + @Override + public Object extend_Delete(JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(Objects.isNull(node) ? null : node.get("requestInfo")); + jsonNodes.add(Objects.isNull(node) ? null : node.get("dataId")); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Extend_Delete", jsonNodes); + } + + @Override + public Object extend_BatchDelete(String ids, JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(node); + jsonNodes.add(mapper.valueToTree(ids)); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Extend_BatchDelete", jsonNodes); + } + + @Override + public Object extend_Retrieve(String dataId, JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(node); + jsonNodes.add(mapper.valueToTree(dataId)); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Extend_Retrieve", jsonNodes); + } + + @Override + public Object extend_Query(String entityFilter, JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(node); + jsonNodes.add(mapper.valueToTree(entityFilter)); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Extend_Query", jsonNodes); + } + + @Override + public Object extend_GetElementHelp(JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(Objects.isNull(node) ? null : node.get("requestInfo")); + jsonNodes.add(Objects.isNull(node) ? null : node.get("labelId")); + jsonNodes.add(Objects.isNull(node) ? null : node.get("nodeCode")); + jsonNodes.add(Objects.isNull(node) ? null : node.get("queryParam")); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Extend_ElementHelp", jsonNodes); + } + + @Override + public Object extend_DeleteChildUserDetail(String rootId, String userDetailId, JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(node); + jsonNodes.add(mapper.valueToTree(rootId)); + jsonNodes.add(mapper.valueToTree(userDetailId)); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "c1a294b7-9407-4c6a-bc9c-c56f14210e08&^^&Extend_DeleteChild##UserDetail", jsonNodes); + } + + @Override + public Object dataDeser(JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(node); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "b8385dd6-f1b7-4e5d-84a6-18a6ceb78396&^^&DataDeser", jsonNodes); + } + + @Override + public Object submit(JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(node); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "48c6a5ad-7f9b-405e-a623-627254c9bb64&^^&Submit", jsonNodes); + } + + @Override + public Object t1(JsonNode node) { + ArrayList jsonNodes = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + try { + jsonNodes.add(node); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ServiceInvoker.invokeByJsonNode("VO", "com.inspur.gs.scm.sd.salesorder.vo.ZUserVoExtend1", "358cb06d-7be8-40cb-bc3c-957d4c9359a2&^^&T1", jsonNodes); + } + +} \ No newline at end of file diff --git a/rest-api-jit-core/src/test/resources/var/jit/oldJit/5f88f4a7-ee63-4e00-8cd3-8c5f90c85355/manifest.json b/rest-api-jit-core/src/test/resources/var/jit/oldJit/5f88f4a7-ee63-4e00-8cd3-8c5f90c85355/manifest.json new file mode 100644 index 0000000000000000000000000000000000000000..dc70332b3955495e7a6d2384fc967d995da9e09b --- /dev/null +++ b/rest-api-jit-core/src/test/resources/var/jit/oldJit/5f88f4a7-ee63-4e00-8cd3-8c5f90c85355/manifest.json @@ -0,0 +1,9 @@ +{ + "version": "9e495821-3f08-448f-af1f-2476775d0fdb#1.0.2", + "compileTime": "2022-09-20T07:47:33.431+00:00", + "description": "1.0版本jit生成的缓存", + "extendProperties": { + "endpointAddress": "/apporder/df/v1.0/merchantform_frm", + "className": "com.inspur.gs.apporder.df.merchant.merchant.front.rest.MerchantForm_frmDynamicService" + } +} \ No newline at end of file diff --git a/rest-api-jit-spi/pom.xml b/rest-api-jit-spi/pom.xml index 7d199c026ffb22e9e61f2478a76c6e96a66d21b8..b1554d929272667cf8eb92c913dfae2f4a6259b2 100644 --- a/rest-api-jit-spi/pom.xml +++ b/rest-api-jit-spi/pom.xml @@ -21,11 +21,11 @@ rest-api-engine com.inspur.edp - 1.0.2 + 1.0.3-SNAPSHOT 4.0.0 rest-api-jit-spi - \ No newline at end of file + diff --git a/toout.bat b/toout.bat new file mode 100644 index 0000000000000000000000000000000000000000..18c1db8664cd0060dadb01f1dd28f24a24b26b7a --- /dev/null +++ b/toout.bat @@ -0,0 +1,14 @@ +@echo off + +for /f "tokens=*" %%i in ('CALL .\xpath0.1.bat pom.xml "/project/version"') do set version=%%i +ECHO version=%version% + +DEL /S/Q .\out + +MKDIR .\out\server\platform\common\libs + +COPY .\rest-api-jit-api\target\rest-api-jit-api-%version%.jar .\out\server\platform\common\libs\jit-api.jar +COPY .\rest-api-jit-core\target\rest-api-jit-core-%version%.jar .\out\server\platform\common\libs\jit-core.jar +COPY .\rest-api-jit-spi\target\rest-api-jit-spi-%version%.jar .\out\server\platform\common\libs\jit-spi.jar + +::pause diff --git a/xpath0.1.bat b/xpath0.1.bat new file mode 100644 index 0000000000000000000000000000000000000000..630822c99a4c6dd92d6db5202d62f437261c920a --- /dev/null +++ b/xpath0.1.bat @@ -0,0 +1,122 @@ +@if (@X)==(@Y) @end /* JScript comment + @echo off + + set "file=%~f1" + set "xpath=%~2" + set "option=%~3" + set "node=%~4" + + if "%~2" equ "" ( + goto :printHelp + ) + + for %%# in ("-h" "-help" "/h" "/help" "") do ( + if /i "%~1" equ %%# ( + goto :printHelp + ) + ) + + if exist "%file%\" ( + echo file "%~1" does not exist + exit /b 3 + ) + if not exist "%file%" ( + echo file "%~1" does not exist + exit /b 4 + ) + + + cscript //E:JScript //nologo "%~f0" /file:"%file%" /xpath:"%xpath%" /option:"%option%" /node:%node% + + exit /b %errorlevel% + + :printHelp + echo %~nx0 prints the value (or list of values) + echo of xml attribute/node in xml by given xpath expression + echo( + echo Usage: + echo( + echo call %~nx0 "filePath" "xpathExpression" + exit /b %errorlevel% + +@if (@X)==(@Y) @end JScript comment */ + +if (WScript.Arguments.length<2) +{ + WScript.Echo("Not enough arguments"); + WScript.Quit(3); +} + + +function escapeRegExp(str) { + return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); +} + +function replaceAll(str, find, replace) { + return str.replace(new RegExp(escapeRegExp(find), 'g'), replace); +} + +var xp=WScript.Arguments.Named.Item("xpath"); +xp=replaceAll(xp,"'",'"'); + +var option=WScript.Arguments.Named.Item("option"); +var node_n=parseInt(WScript.Arguments.Named.Item("node")); + + +var objDoc; +var objNodes; +var loaded; + +try { + objDoc = WScript.CreateObject("MSXML.DOMDocument"); + loaded=objDoc.load(WScript.Arguments.Named.Item("file")); +} catch (err){ + WScript.Echo("Error while parsing the xml"); + WScript.Echo(err.message); + WScript.Quit(1); +} + +if(!loaded){ + WScript.Echo("Error while parsing the xml"); + WScript.Echo(""); + WScript.Echo("Error Code:"+objDoc.parseError.errorCode); + WScript.Echo(""); + WScript.Echo("Line:"+objDoc.parseError.line+" Posotion:"+objDoc.parseError.filepos); + WScript.Echo(""); + WScript.Echo("Reason:"+objDoc.parseError.reason); + WScript.Echo(""); + WScript.Echo("URL:"+objDoc.parseError.url); + WScript.Echo(""); + WScript.Echo(objDoc.parseError.srcText); + WScript.Quit(5); +} + +try { + var objNodes = objDoc.selectNodes(xp); +} catch (err){ + WScript.Echo("invalid xpath expression"); + WScript.Echo(err.message); + WScript.Quit(2); +} + +if(!isNaN(node_n)) { + if(node_n>=objNodes.length){ + WScript.Echo("Out of nodes range"); + WScript.Echo("Nodes length is: "+objNodes.length); + WScript.Quit(35); + } + if(option.toLowerCase()=="xml"){ + WScript.Echo(objNodes.item(node_n).xml); + } else { + WScript.Echo(objNodes.item(node_n).text); + } +} else { + for (var i=0;i