blob: 6f992b62d898e3091d79894a938fe8a633bbd5f9 [file] [log] [blame]
#!/usr/bin/env python
"""Java Action Builder
#
# 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.
#
"""
from __future__ import print_function
from os.path import abspath, exists, dirname
import os, sys, codecs, subprocess, shutil, logging
def copy(src, dst):
with codecs.open(src, 'r', 'utf-8') as s:
body = s.read()
with codecs.open(dst, 'w', 'utf-8') as d:
d.write(body)
def find_with_ext(basedir, ext):
result = []
for root, _, files in os.walk(basedir, topdown=False):
for name in files:
if name.endswith(ext):
result.append(os.path.join(root,name))
return result
def javac(sources, classpath, target_dir):
cmd = [ "javac",
"-encoding", "UTF-8",
"-cp", ":".join(classpath),
"-d", target_dir
]+sources
#print(cmd)
logging.info(" ".join(cmd))
p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(o, e) = p.communicate()
if isinstance(o, bytes) and not isinstance(o, str):
o = o.decode('utf-8')
if isinstance(e, bytes) and not isinstance(e, str):
e = e.decode('utf-8')
ok = True
if o:
ok = False
sys.stdout.write(o)
sys.stdout.flush()
if e:
ok = False
sys.stderr.write(e)
sys.stderr.flush()
return ok
def build(source_dir, classpath, target_dir, mainClass):
# copy exec to <main>.java if it is there
src = "%s/exec" % source_dir
if os.path.isfile(src):
main_java = "%s/%s.java" % (source_dir, mainClass.split(".")[-1])
copy(src,main_java)
logging.info("renamed exec to %s", main_java)
# look for sources and compile
sources = find_with_ext(source_dir, ".java")
if len(sources) > 0:
jars = find_with_ext(source_dir, ".jar")
logging.info("compiling %d sources with %d jars", len(sources),len(jars))
return javac(sources, classpath+jars, source_dir)
return True
def write_exec(target_dir, classpath, main):
launcher = "%s/exec" % target_dir
jars = find_with_ext(target_dir, ".jar")
jars.append(target_dir)
cmd = """#!/bin/bash
cd "%s"
/opt/java/openjdk/bin/java -Dfile.encoding=UTF-8 -cp "%s" Launcher "%s" "$@"
""" %( target_dir, ":".join(classpath+jars), main)
with codecs.open(launcher, 'w', 'utf-8') as d:
d.write(cmd)
os.chmod(launcher, 0o755)
def parseMain(main):
if main == "main":
return "Main", "main"
a = main.split("#")
if(len(a)==1):
return a[0], "main"
return a[0], a[1]
def assemble(argv):
mainClass, mainMethod = parseMain(argv[1])
logging.info("%s %s", mainClass, mainMethod)
source_dir = os.path.abspath(argv[2])
target_dir = os.path.abspath(argv[3])
classpath = ["/usr/java/lib/launcher.jar", "/usr/java/lib/gson-2.8.5.jar"]
# build
if build(source_dir, classpath, target_dir, mainClass):
shutil.rmtree(target_dir)
shutil.move(source_dir, target_dir)
logging.info("moved %s to %s", source_dir, target_dir)
# write the launcher is it is there
write_exec(target_dir, classpath, "%s#%s" % (mainClass, mainMethod))
# launch it to check it can load with immediate exit - it should not produce any output
subprocess.call(["%s/exec" % target_dir, "-exit"])
sys.stdout.flush()
sys.stderr.flush()
if __name__ == '__main__':
if len(sys.argv) < 4:
sys.stdout.write("usage: <main-class> <source-dir> <target-dir>\n")
sys.exit(1)
logging.basicConfig(filename="/var/log/compile.log")
assemble(sys.argv)