I am working in a Java spring boot application, running as a docker container.
The main purose of this application was to execute python scripts.
So inside the docker container, I had to make available python environment. I added the python runtime with this code.
But seems this is very basic python verson and I can not make other important libraries available.
Like, I wanted to add 'asyncpg' library so that I can use connection pool.
But it is not letting me to add asyncpg library.
Below is the docker file.
Note: I have commented '#FROM python:3.6-alpine', if I make this open then java runtime will not be available which is 'FROM openjdk:8u191-jre-alpine3.8'
------- Docker file --------------
*FROM openjdk:8u191-jre-alpine3.8
#FROM python:3.6-alpine
## Install bash
RUN apk add --no-cache curl tar bash
ENV APP_HOME /opt/app
# Create directory structure
RUN mkdir -p ${APP_HOME}/logs
RUN mkdir -p ${APP_HOME}/config
RUN mkdir -p ${APP_HOME}/libs
RUN mkdir -p ${APP_HOME}/scripts
# Add supporting script
ADD start.sh ${APP_HOME}/start.sh
RUN chmod +x ${APP_HOME}/start.sh
ADD wait-for-it.sh ${APP_HOME}/wait-for-it.sh
RUN chmod +x ${APP_HOME}/wait-for-it.sh
ADD load-ext-packages.sh ${APP_HOME}/load-ext-packages.sh
RUN chmod +x ${APP_HOME}/load-ext-packages.sh
## Add Spring Boot runnable jar
ADD *.jar ${APP_HOME}/
WORKDIR ${APP_HOME}
VOLUME [ "${APP_HOME}/logs" ]
VOLUME [ "${APP_HOME}/config" ]
VOLUME [ "${APP_HOME}/libs" ]
VOLUME [ "${APP_HOME}/scripts" ]
# Install Python
RUN apk add build-base
RUN apk add --update gcc
RUN apk --update add gcc build-base freetype-dev libpng-dev openblas-dev
RUN apk add --no-cache python3 python3-dev libevent-dev && \
python3 -m ensurepip && \
rm -r /usr/lib/python*/ensurepip && \
pip3 install --upgrade pip setuptools && \
pip3 install wheel && \
pip3 install --no-cache-dir asyncpg && \
if [ ! -e /usr/bin/pip ]; then ln -s pip3 /usr/bin/pip ; fi && \
if [[ ! -e /usr/bin/python ]]; then ln -sf /usr/bin/python3 /usr/bin/python; fi && \
rm -r /root/.cache
CMD ["./start.sh"]*
I have got one solution .. that at the first line of the docker file, I will first decleare the 'FROM alpine:3.7', and then inside the docker file I will keep adding the required runtimes and the dependent libraries accordingly. This way we can add mutiple runtimes.
Below the working docker compose where I have commented out both the lines for openjdk and python runtime and added FROM alpine:3.7:
Also some trick to add asyncpg library to the python runtime. This way I can now add any dependencies.
I can now work on asyncpg.
-------- Docker file ----------------
*#FROM openjdk:8u191-jre-alpine3.8
#FROM python:3.6-alpine
FROM alpine:3.7
## Install bash
RUN apk add --no-cache curl tar bash
ENV APP_HOME /opt/app
# Create directory structure
RUN mkdir -p ${APP_HOME}/logs
RUN mkdir -p ${APP_HOME}/config
RUN mkdir -p ${APP_HOME}/libs
RUN mkdir -p ${APP_HOME}/scripts
# Add supporting script
ADD start.sh ${APP_HOME}/start.sh
RUN chmod +x ${APP_HOME}/start.sh
ADD wait-for-it.sh ${APP_HOME}/wait-for-it.sh
RUN chmod +x ${APP_HOME}/wait-for-it.sh
ADD load-ext-packages.sh ${APP_HOME}/load-ext-packages.sh
RUN chmod +x ${APP_HOME}/load-ext-packages.sh
## Add Spring Boot runnable jar
ADD *.jar ${APP_HOME}/
WORKDIR ${APP_HOME}
VOLUME [ "${APP_HOME}/logs" ]
VOLUME [ "${APP_HOME}/config" ]
VOLUME [ "${APP_HOME}/libs" ]
VOLUME [ "${APP_HOME}/scripts" ]
RUN apk add build-base --no-cache python3 python3-dev && \
python3 -m ensurepip && \
rm -r /usr/lib/python*/ensurepip && \
pip3 install --upgrade pip setuptools && \
pip3 install --no-cache-dir asyncpg && \
if [ ! -e /usr/bin/pip ]; then ln -s pip3 /usr/bin/pip ; fi && \
if [[ ! -e /usr/bin/python ]]; then ln -sf /usr/bin/python3 /usr/bin/python; fi && \
rm -r /root/.cache
RUN apk update \
&& apk upgrade \
&& apk add --no-cache bash \
&& apk add --no-cache --virtual=build-dependencies unzip \
&& apk add --no-cache curl \
&& apk add --no-cache openjdk8-jre
CMD ["./start.sh"]*
I'm trying to run selenium(headless) as a service on my Ubuntu 14.04 LTS following bash script:
#!/bin/bash
case "${1:-''}" in
'start')
if test -f /tmp/selenium.pid
then
echo "Selenium is already running."
else
export DISPLAY=localhost:99.0
java -jar /opt/selenium-server-standalone-3.3.1.jar -port 4444 > /var/log/selenium/output.log 2> /var/log/selenium/error.log & echo $! > /tmp/selenium.pid
echo "Starting Selenium..."
error=$?
if test $error -gt 0
then
echo "${bon}Error $error! Couldn't start Selenium!${boff}"
fi
fi
;;
'stop')
if test -f /tmp/selenium.pid
then
echo "Stopping Selenium..."
PID=`cat /tmp/selenium.pid`
kill -3 $PID
if kill -9 $PID ;
then
sleep 2
test -f /tmp/selenium.pid && rm -f /tmp/selenium.pid
else
echo "Selenium could not be stopped..."
fi
else
echo "Selenium is not running."
fi
;;
'restart')
if test -f /tmp/selenium.pid
then
kill -HUP `cat /tmp/selenium.pid`
test -f /tmp/selenium.pid && rm -f /tmp/selenium.pid
sleep 1
export DISPLAY=localhost:99.0
java -jar /opt/selenium-server-standalone-3.3.1.jar -port 4444 > /var/log/selenium/output.log 2> /var/log/selenium/error.log & echo $! > /tmp/selenium.pid
echo "Reload Selenium..."
else
echo "Selenium isn't running..."
fi
;;
*) # no parameter specified
echo "Usage: $SELF start|stop|restart"
exit 1
;;
esac
My virtual screen starts as on reboot through the following crontab entry
#reboot sh -c 'Xvfb :99 -ac -screen 0 1024x768x8 > /tmp/xvfb.log 2>&1 &'
I get an error above because it seems like selenium is not running headless.
If I use the code below to start selenium manually, it works as expected.
DISPLAY=:1 xvfb-run java -jar /opt/selenium-server-standalone-3.3.1.jar
How would I run the above command on start-up to set-up the selenium listender?
So after 2 days (yes I'm a complete rookie when it comes to servers) trying to get this working I give up and turn to SO for help :)
I want to start my java app on start, log to a logfile. That's it :)
start on runlevel [2345]
stop on runlevel [!2345]
#Respawn the process if it crashes
#If it respawns more than 10 times in 5 seconds stop
respawn
respawn limit 10 5
expect fork
script
cd /home/ubuntu/admin/
mvn spring-boot:run > /var/log/upstart/admin.log 2>&1
end script
Running "sudo start admin" works and I get "admin start/running" in console.. No log is created and the java app is not started.. ?
What am I missing?
How do I run Java as a service on Ubuntu?
I don't mean to sidetrack, but I've deployed Java applications on Ubuntu in production since 2010 and had very little success with Upstart. I use init.d scripts and start-stop-daemon. Side bonus: it works on more distros.
Create /etc/init.d/my-java-app:
#!/bin/sh
#
# my-java-app My Java App
#
# chkconfig: - 80 05
# description: Enable My Java Application
#
### BEGIN INIT INFO
# Provides: my-java-app
# Required-Start: $remote_fs $network
# Required-Stop: $remote_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: My Java Application
# Short-Description: Enable My Java Application
### END INIT INFO
DESC="my java app"
NAME=my-java-app
PIDFILE=/var/run/$NAME.pid
RUN_AS=ubuntu
WORK_DIR=/home/ubuntu/admin
DAEMON=/usr/bin/mvn
DAEMON_OPTS="spring-boot:run"
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
do_start() {
start-stop-daemon --start --quiet --make-pidfile --pidfile $PIDFILE \
--background \
--chuid $RUN_AS \
--chdir $WORK_DIR \
--exec $DAEMON -- $DAEMON_OPTS
}
do_stop() {
start-stop-daemon --stop --quiet --pidfile $PIDFILE
if [ -e $PIDFILE ]
then rm $PIDFILE
fi
}
case "$1" in
start)
echo -n "Starting $DESC: $NAME"
do_start
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME"
do_stop
echo "."
;;
restart)
echo -n "Restarting $DESC: $NAME"
do_stop
sleep 1
do_start
echo "."
;;
status)
status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
;;
*)
echo "usage: $NAME {start|stop|restart}"
exit 1
;;
esac
Make it belong to root, make it executable, and set it up to run on startup with:
sudo chown root:root /etc/init.d/my-java-app
sudo chmod 755 /etc/init.d/my-java-app
sudo update-rc.d my-java-app defaults
To start the service you can run:
sudo service my-java-app start
To stop the service you can run:
sudo service my-java-app stop
This is based on a simplified version of the /etc/init.d/skeleton file included by Ubuntu.
The man page for start-stop-daemon is worth looking at if you want to tweak this further.b
I am setting tomcat in debug mode. Tomcat server is running on different machine and I am working on different machine.
Before starting tomcat I am executing following linux command.
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 9003 -j ACCEPT
export JPDA_ADDRESS=9003
export JPDA_TRANSPORT=dt_socket
export JPDA_SUSPEND=n
bin/catalina.sh jpda start
In eclipse I am providing IP address of remote machine and port number 9003.
My ./catalina.sh file is given below. But still I am not able to see green color debug pointers at breakpoint. What to do ? Eclipse doesn't throw any exception while connecting to remote machine. Earlier it was throwing 'Connection failed' but once I executed following command it was rectified, but not able to see breakpoints even after I have given breakpoints.
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 9003 -j ACCEPT
my cataline.sh file.
#!/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.
# -----------------------------------------------------------------------------
# Control Script for the CATALINA Server
#
# Environment Variable Prerequisites
#
# Do not set the variables in this script. Instead put them into a script
# setenv.sh in CATALINA_BASE/bin to keep your customizations separate.
#
# CATALINA_HOME May point at your Catalina "build" directory.
#
# CATALINA_BASE (Optional) Base directory for resolving dynamic portions
# of a Catalina installation. If not present, resolves to
# the same directory that CATALINA_HOME points to.
#
# CATALINA_OUT (Optional) Full path to a file where stdout and stderr
# will be redirected.
# Default is $CATALINA_BASE/logs/catalina.out
#
# CATALINA_OPTS (Optional) Java runtime options used when the "start",
# "run" or "debug" command is executed.
# Include here and not in JAVA_OPTS all options, that should
# only be used by Tomcat itself, not by the stop process,
# the version command etc.
# Examples are heap size, GC logging, JMX ports etc.
#
# CATALINA_TMPDIR (Optional) Directory path location of temporary directory
# the JVM should use (java.io.tmpdir). Defaults to
# $CATALINA_BASE/temp.
#
# JAVA_HOME Must point at your Java Development Kit installation.
# Required to run the with the "debug" argument.
#
# JRE_HOME Must point at your Java Runtime installation.
# Defaults to JAVA_HOME if empty. If JRE_HOME and JAVA_HOME
# are both set, JRE_HOME is used.
#
# JAVA_OPTS (Optional) Java runtime options used when any command
# is executed.
# Include here and not in CATALINA_OPTS all options, that
# should be used by Tomcat and also by the stop process,
# the version command etc.
# Most options should go into CATALINA_OPTS.
#
# JAVA_ENDORSED_DIRS (Optional) Lists of of colon separated directories
# containing some jars in order to allow replacement of APIs
# created outside of the JCP (i.e. DOM and SAX from W3C).
# It can also be used to update the XML parser implementation.
# Defaults to $CATALINA_HOME/endorsed.
#
# JPDA_TRANSPORT (Optional) JPDA transport used when the "jpda start"
# command is executed. The default is "dt_socket".
#
# JPDA_ADDRESS (Optional) Java runtime options used when the "jpda start"
# command is executed. The default is 8000.
#
# JPDA_SUSPEND (Optional) Java runtime options used when the "jpda start"
# command is executed. Specifies whether JVM should suspend
# execution immediately after startup. Default is "n".
#
# JPDA_OPTS (Optional) Java runtime options used when the "jpda start"
# command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS,
# and JPDA_SUSPEND are ignored. Thus, all required jpda
# options MUST be specified. The default is:
#
# -agentlib:jdwp=transport=$JPDA_TRANSPORT,
# address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND
#
# CATALINA_PID (Optional) Path of the file which should contains the pid
# of the catalina startup java process, when start (fork) is
# used
#
# LOGGING_CONFIG (Optional) Override Tomcat's logging config file
# Example (all one line)
# LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
#
# LOGGING_MANAGER (Optional) Override Tomcat's logging manager
# Example (all one line)
# LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
# -----------------------------------------------------------------------------
# OS specific support. $var _must_ be set to either true or false.
cygwin=false
darwin=false
os400=false
case "`uname`" in
CYGWIN*) cygwin=true;;
Darwin*) darwin=true;;
OS400*) os400=true;;
esac
# resolve links - $0 may be a softlink
PRG="$0"
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
# Get standard environment variables
PRGDIR=`dirname "$PRG"`
# Only set CATALINA_HOME if not already set
[ -z "$CATALINA_HOME" ] && CATALINA_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`
# Copy CATALINA_BASE from CATALINA_HOME if not already set
[ -z "$CATALINA_BASE" ] && CATALINA_BASE="$CATALINA_HOME"
# Ensure that any user defined CLASSPATH variables are not used on startup,
# but allow them to be specified in setenv.sh, in rare case when it is needed.
CLASSPATH=
if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
. "$CATALINA_BASE/bin/setenv.sh"
elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
. "$CATALINA_HOME/bin/setenv.sh"
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$JRE_HOME" ] && JRE_HOME=`cygpath --unix "$JRE_HOME"`
[ -n "$CATALINA_HOME" ] && CATALINA_HOME=`cygpath --unix "$CATALINA_HOME"`
[ -n "$CATALINA_BASE" ] && CATALINA_BASE=`cygpath --unix "$CATALINA_BASE"`
[ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For OS400
if $os400; then
# Set job priority to standard for interactive (interactive - 6) by using
# the interactive priority - 6, the helper threads that respond to requests
# will be running at the same priority as interactive jobs.
COMMAND='chgjob job('$JOBNAME') runpty(6)'
system $COMMAND
# Enable multi threading
export QIBM_MULTI_THREADED=Y
fi
# Get standard Java environment variables
if $os400; then
# -r will Only work on the os400 if the files are:
# 1. owned by the user
# 2. owned by the PRIMARY group of the user
# this will not work if the user belongs in secondary groups
. "$CATALINA_HOME"/bin/setclasspath.sh
else
if [ -r "$CATALINA_HOME"/bin/setclasspath.sh ]; then
. "$CATALINA_HOME"/bin/setclasspath.sh
else
echo "Cannot find $CATALINA_HOME/bin/setclasspath.sh"
echo "This file is needed to run this program"
exit 1
fi
fi
# Add on extra jar files to CLASSPATH
if [ ! -z "$CLASSPATH" ] ; then
CLASSPATH="$CLASSPATH":
fi
CLASSPATH="$CLASSPATH""$CATALINA_HOME"/bin/bootstrap.jar
if [ -z "$CATALINA_OUT" ] ; then
CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out
fi
if [ -z "$CATALINA_TMPDIR" ] ; then
# Define the java.io.tmpdir to use for Catalina
CATALINA_TMPDIR="$CATALINA_BASE"/temp
fi
# Add tomcat-juli.jar to classpath
# tomcat-juli.jar can be over-ridden per instance
if [ -r "$CATALINA_BASE/bin/tomcat-juli.jar" ] ; then
CLASSPATH=$CLASSPATH:$CATALINA_BASE/bin/tomcat-juli.jar
else
CLASSPATH=$CLASSPATH:$CATALINA_HOME/bin/tomcat-juli.jar
fi
# Bugzilla 37848: When no TTY is available, don't output to console
have_tty=0
if [ "`tty`" != "not a tty" ]; then
have_tty=1
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
JAVA_HOME=`cygpath --absolute --windows "$JAVA_HOME"`
JRE_HOME=`cygpath --absolute --windows "$JRE_HOME"`
CATALINA_HOME=`cygpath --absolute --windows "$CATALINA_HOME"`
CATALINA_BASE=`cygpath --absolute --windows "$CATALINA_BASE"`
CATALINA_TMPDIR=`cygpath --absolute --windows "$CATALINA_TMPDIR"`
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
JAVA_ENDORSED_DIRS=`cygpath --path --windows "$JAVA_ENDORSED_DIRS"`
fi
# Set juli LogManager config file if it is present and an override has not been issued
if [ -z "$LOGGING_CONFIG" ]; then
if [ -r "$CATALINA_BASE"/conf/logging.properties ]; then
LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
else
# Bugzilla 45585
LOGGING_CONFIG="-Dnop"
fi
fi
if [ -z "$LOGGING_MANAGER" ]; then
LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
fi
# Uncomment the following line to make the umask available when using the
# org.apache.catalina.security.SecurityListener
#JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.security.SecurityListener.UMASK=`umask`"
# ----- Execute The Requested Command -----------------------------------------
# Bugzilla 37848: only output this if we have a TTY
if [ $have_tty -eq 1 ]; then
echo "Using CATALINA_BASE: $CATALINA_BASE"
echo "Using CATALINA_HOME: $CATALINA_HOME"
echo "Using CATALINA_TMPDIR: $CATALINA_TMPDIR"
if [ "$1" = "debug" ] ; then
echo "Using JAVA_HOME: $JAVA_HOME"
else
echo "Using JRE_HOME: $JRE_HOME"
fi
echo "Using CLASSPATH: $CLASSPATH"
if [ ! -z "$CATALINA_PID" ]; then
echo "Using CATALINA_PID: $CATALINA_PID"
fi
fi
if [ "$1" = "jpda" ] ; then
if [ -z "$JPDA_TRANSPORT" ]; then
JPDA_TRANSPORT="dt_socket"
fi
if [ -z "$JPDA_ADDRESS" ]; then
JPDA_ADDRESS="8000"
fi
if [ -z "$JPDA_SUSPEND" ]; then
JPDA_SUSPEND="n"
fi
if [ -z "$JPDA_OPTS" ]; then
JPDA_OPTS="-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND"
fi
CATALINA_OPTS="$CATALINA_OPTS $JPDA_OPTS"
shift
fi
if [ "$1" = "debug" ] ; then
if $os400; then
echo "Debug command not available on OS400"
exit 1
else
shift
if [ "$1" = "-security" ] ; then
if [ $have_tty -eq 1 ]; then
echo "Using Security Manager"
fi
shift
exec "$_RUNJDB" "$LOGGING_CONFIG" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
-sourcepath "$CATALINA_HOME"/../../java \
-Djava.security.manager \
-Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$#" start
else
exec "$_RUNJDB" "$LOGGING_CONFIG" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
-sourcepath "$CATALINA_HOME"/../../java \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$#" start
fi
fi
elif [ "$1" = "run" ]; then
shift
if [ "$1" = "-security" ] ; then
if [ $have_tty -eq 1 ]; then
echo "Using Security Manager"
fi
shift
eval exec "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
-Djava.security.manager \
-Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$#" start
else
eval exec "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$#" start
fi
elif [ "$1" = "start" ] ; then
if [ ! -z "$CATALINA_PID" ]; then
if [ -f "$CATALINA_PID" ]; then
if [ -s "$CATALINA_PID" ]; then
echo "Existing PID file found during start."
if [ -r "$CATALINA_PID" ]; then
PID=`cat "$CATALINA_PID"`
ps -p $PID >/dev/null 2>&1
if [ $? -eq 0 ] ; then
echo "Tomcat appears to still be running with PID $PID. Start aborted."
exit 1
else
echo "Removing/clearing stale PID file."
rm -f "$CATALINA_PID" >/dev/null 2>&1
if [ $? != 0 ]; then
if [ -w "$CATALINA_PID" ]; then
cat /dev/null > "$CATALINA_PID"
else
echo "Unable to remove or clear stale PID file. Start aborted."
exit 1
fi
fi
fi
else
echo "Unable to read PID file. Start aborted."
exit 1
fi
else
rm -f "$CATALINA_PID" >/dev/null 2>&1
if [ $? != 0 ]; then
if [ ! -w "$CATALINA_PID" ]; then
echo "Unable to remove or write to empty PID file. Start aborted."
exit 1
fi
fi
fi
fi
fi
shift
touch "$CATALINA_OUT"
if [ "$1" = "-security" ] ; then
if [ $have_tty -eq 1 ]; then
echo "Using Security Manager"
fi
shift
eval "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
-Djava.security.manager \
-Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$#" start \
>> "$CATALINA_OUT" 2>&1 "&"
else
eval "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$#" start \
>> "$CATALINA_OUT" 2>&1 "&"
fi
if [ ! -z "$CATALINA_PID" ]; then
echo $! > "$CATALINA_PID"
fi
echo "Tomcat started."
elif [ "$1" = "stop" ] ; then
shift
SLEEP=5
if [ ! -z "$1" ]; then
echo $1 | grep "[^0-9]" >/dev/null 2>&1
if [ $? -gt 0 ]; then
SLEEP=$1
shift
fi
fi
FORCE=0
if [ "$1" = "-force" ]; then
shift
FORCE=1
fi
if [ ! -z "$CATALINA_PID" ]; then
if [ -f "$CATALINA_PID" ]; then
if [ -s "$CATALINA_PID" ]; then
kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1
if [ $? -gt 0 ]; then
echo "PID file found but no matching process was found. Stop aborted."
exit 1
fi
else
echo "PID file is empty and has been ignored."
fi
else
echo "\$CATALINA_PID was set but the specified file does not exist. Is Tomcat running? Stop aborted."
exit 1
fi
fi
eval "\"$_RUNJAVA\"" $LOGGING_MANAGER $JAVA_OPTS \
-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$#" stop
# stop failed. Shutdown port disabled? Try a normal kill.
if [ $? != 0 ]; then
if [ ! -z "$CATALINA_PID" ]; then
echo "The stop command failed. Attempting to signal the process to stop through OS signal."
kill -15 `cat "$CATALINA_PID"` >/dev/null 2>&1
fi
fi
if [ ! -z "$CATALINA_PID" ]; then
if [ -f "$CATALINA_PID" ]; then
while [ $SLEEP -ge 0 ]; do
kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1
if [ $? -gt 0 ]; then
rm -f "$CATALINA_PID" >/dev/null 2>&1
if [ $? != 0 ]; then
if [ -w "$CATALINA_PID" ]; then
cat /dev/null > "$CATALINA_PID"
# If Tomcat has stopped don't try and force a stop with an empty PID file
FORCE=0
else
echo "The PID file could not be removed or cleared."
fi
fi
echo "Tomcat stopped."
break
fi
if [ $SLEEP -gt 0 ]; then
sleep 1
fi
if [ $SLEEP -eq 0 ]; then
if [ $FORCE -eq 0 ]; then
echo "Tomcat did not stop in time. PID file was not removed. To aid diagnostics a thread dump has been written to standard out."
kill -3 `cat "$CATALINA_PID"`
fi
fi
SLEEP=`expr $SLEEP - 1 `
done
fi
fi
KILL_SLEEP_INTERVAL=5
if [ $FORCE -eq 1 ]; then
if [ -z "$CATALINA_PID" ]; then
echo "Kill failed: \$CATALINA_PID not set"
else
if [ -f "$CATALINA_PID" ]; then
PID=`cat "$CATALINA_PID"`
echo "Killing Tomcat with the PID: $PID"
kill -9 $PID
while [ $KILL_SLEEP_INTERVAL -ge 0 ]; do
kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1
if [ $? -gt 0 ]; then
rm -f "$CATALINA_PID" >/dev/null 2>&1
if [ $? != 0 ]; then
if [ -w "$CATALINA_PID" ]; then
cat /dev/null > "$CATALINA_PID"
else
echo "The PID file could not be removed."
fi
fi
# Set this to zero else a warning will be issued about the process still running
KILL_SLEEP_INTERVAL=0
echo "The Tomcat process has been killed."
break
fi
if [ $KILL_SLEEP_INTERVAL -gt 0 ]; then
sleep 1
fi
KILL_SLEEP_INTERVAL=`expr $KILL_SLEEP_INTERVAL - 1 `
done
if [ $KILL_SLEEP_INTERVAL -gt 0 ]; then
echo "Tomcat has not been killed completely yet. The process might be waiting on some system call or might be UNINTERRUPTIBLE."
fi
fi
fi
fi
elif [ "$1" = "configtest" ] ; then
eval "\"$_RUNJAVA\"" $LOGGING_MANAGER $JAVA_OPTS \
-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap configtest
result=$?
if [ $result -ne 0 ]; then
echo "Configuration error detected!"
fi
exit $result
elif [ "$1" = "version" ] ; then
"$_RUNJAVA" \
-classpath "$CATALINA_HOME/lib/catalina.jar" \
org.apache.catalina.util.ServerInfo
else
echo "Usage: catalina.sh ( commands ... )"
echo "commands:"
if $os400; then
echo " debug Start Catalina in a debugger (not available on OS400)"
echo " debug -security Debug Catalina with a security manager (not available on OS400)"
else
echo " debug Start Catalina in a debugger"
echo " debug -security Debug Catalina with a security manager"
fi
echo " jpda start Start Catalina under JPDA debugger"
echo " run Start Catalina in the current window"
echo " run -security Start in the current window with security manager"
echo " start Start Catalina in a separate window"
echo " start -security Start in a separate window with security manager"
echo " stop Stop Catalina, waiting up to 5 seconds for the process to end"
echo " stop n Stop Catalina, waiting up to n seconds for the process to end"
echo " stop -force Stop Catalina, wait up to 5 seconds and then use kill -KILL if still running"
echo " stop n -force Stop Catalina, wait up to n seconds and then use kill -KILL if still running"
echo " configtest Run a basic syntax check on server.xml - check exit code for result"
echo " version What version of tomcat are you running?"
echo "Note: Waiting for the process to end and use of the -force option require that \$CATALINA_PID is defined"
exit 1
fi
I have 7 devices plugged into my development machine.
Normally I do adb install <path to apk> and can install to just a single device.
Now I would like to install my apk on all of my 7 connected devices. How can I do this in a single command? I'd like to run a script perhaps.
You can use adb devices to get a list of connected devices and then run adb -s DEVICE_SERIAL_NUM install... for every device listed.
Something like (bash):
adb devices | tail -n +3 | cut -sf 1 -d " " | xargs -iX adb -s X install ...
Comments suggest this might work better for newer versions:
adb devices | tail -n +2 | cut -sf 1 | xargs -iX adb -s X install ...
For Mac OSX(not tested on Linux):
adb devices | tail -n +2 | cut -sf 1 | xargs -I {} adb -s {} install ...
The other answers were very useful however didn't quite do what I needed. I thought I'd post my solution (a shell script) in case it provides more clarity for other readers. It installs multiple apks and any mp4s
echo "Installatron"
for SERIAL in $(adb devices | tail -n +2 | cut -sf 1);
do
for APKLIST in $(ls *.apk);
do
echo "Installatroning $APKLIST on $SERIAL"
adb -s $SERIAL install $APKLIST
done
for MP4LIST in $(ls *.mp4);
do
echo "Installatroning $MP4LIST to $SERIAL"
adb -s $SERIAL push $MP4LIST sdcard/
done
done
echo "Installatron has left the building"
Thank you for all the other answers that got me to this point.
Here's a functional one line command tailored from kichik's response (thanks!):
adb devices | tail -n +2 | cut -sf 1 | xargs -iX adb -s X install -r *.apk
But if you happen to be using Maven it's even simpler:
mvn android:deploy
Another short option... I stumbled on this page to learn that the -s $SERIAL has to come before the actual adb command! Thanks stackoverflow!
for SERIAL in $(adb devices | grep -v List | cut -f 1);
do `adb -s $SERIAL install -r /path/to/product.apk`;
done
Generalized solution from Dave Owens to run any command on all devices:
for SERIAL in $(adb devices | grep -v List | cut -f 1);
do echo adb -s $SERIAL $#;
done
Put it in some script like "adb_all" and use same way as adb for single device.
Another good thing i've found is to fork background processes for each command, and wait for their completion:
for SERIAL in $(adb devices | grep -v List | cut -f 1);
do adb -s $SERIAL $# &
done
for job in `jobs -p`
do wait $job
done
Then you can easily create a script to install app and start the activity
./adb_all_fork install myApp.apk
./adb_all_fork shell am start -a android.intent.action.MAIN -n my.package.app/.MainActivity
I liked workingMatt's script but thought it could be improved a bit, here's my modified version:
#!/bin/bash
install_to_device(){
local prettyName=$(adb -s $1 shell getprop ro.product.model)
echo "Starting Installatroning on $prettyName"
for APKLIST in $(find . -name "*.apk" -not -name "*unaligned*");
do
echo "Installatroning $APKLIST on $prettyName"
adb -s $1 install -r $APKLIST
adb -s $1 shell am start -n com.foo.barr/.FirstActivity;
adb -s $1 shell input keyevent KEYCODE_WAKEUP
done
echo "Finished Installatroning on $prettyName"
}
echo "Installatron"
gradlew assembleProdDebug
for SERIAL in $(adb devices | tail -n +2 | cut -sf 1);
do
install_to_device $SERIAL&
done
My version does the same thing except:
it finds the apks from the root of the project
it installs to every device simultaneously
it excludes the "unaligned" versions of the apks (these were just being installed over by the aligned versions anyway
it shows the readable names for the phones instead if their device ids
There's a few ways it could still be improved but I'm quite happy with it.
The following command should work:
$ adb devices | tail -n +2 | head -n -1 | cut -f 1 | xargs -I X adb -s X install -r path/to/your/package.apk
adb devices returns the list of devices. Use tail -n +2 to start from the 2nd line and head -n -1 to remove the last blank line at the end. Piping through cut with the default tab delimiter gets us the first column which are the serials.
xargs is used to run the adb command for each serial. Remove the -r option if you are not re-installing.
With this script you can just do:
adb+ install <path to apk>
Clean, simple.
If you don't want use the devices that have not enabled adb; use this
Mac/Linux
adb devices | grep device | grep -v devices | awk '{print$1}' | xargs -I {} adb -s {} install path/to/yourApp.apk
adb devices | grep device | grep -v devices | cut -sf 1 | xargs -I {} adb -s {} install path/to/yourApp.apk
Use this command-line utility: adb-foreach
PowerShell solution
function global:adba() {
$deviceIds = iex "adb devices" | select -skip 1 | %{$_.Split([char]0x9)[0].Trim() } | where {$_ -ne "" }
foreach ($deviceId in $deviceIds) {
Echo ("--Executing on device " + $deviceId + ":---")
iex ("adb -s $deviceId " + $args)
}
}
Put this in your profile file (notepad $PROFILE), restart your shell and you can invoke installations with :
adba install yourApp.apk
This command works perfect
adb devices | awk 'NR>1{print $1}' | xargs -n1 -I% adb -s % install foo.apk
well its simple you can create a installapk.bat file that can do the job for multiple apk to multiple connected devices open installapk.bat with notepad++ and copy paste this code
FOR /F "skip=1" %%x IN ('adb devices') DO start adb -s %%x install -r Facebook.apk
FOR /F "skip=1" %%x IN ('adb devices') DO start adb -s %%x install -r Instagram.apk
FOR /F "skip=1" %%x IN ('adb devices') DO start adb -s %%x install -r Messenger.apk
FOR /F "skip=1" %%x IN ('adb devices') DO start adb -s %%x install -r Outlook.apk
FOR /F "skip=1" %%x IN ('adb devices') DO start adb -s %%x install -r Viber.apk
FOR /F "skip=1" %%x IN ('adb devices') DO start adb -s %%x install -r WhatsApp.apk
Here is bash for install and run apk on all connected devices
Using
nick#nickolay:/home/workspace/MyProject$ > bash path/to/installAndRunApk.sh
installAndRunApk.sh
#!/usr/bin/env bash
#--------find apk---------
apkFile=$(find -name '*.apk' -print | grep -oP '(?<=.).*(.apk)')
#--------find apkFilePath---------
if test -z "apkFile"
then
echo "apkFile: is NULL"
exit 0;
fi
echo "apkFile: ${apkFile}"
apkFilePath=$(pwd)${apkFile}
echo "apk file path: ${apkFilePath}"
#--------install---------
if test -z "$apkFilePath"
then
echo "apkFilePath: is NULL"
exit 0;
fi
echo "adb install -t -r ${apkFilePath}"
for SERIAL in $(adb devices | grep -v List | cut -f 1);
do `adb -s ${SERIAL} install -t -r ${apkFilePath}`;
done
#--------get applicationId---------
echo "aapt dump badging ${apkFilePath} | grep -oP '(?<=package: name=).*(?=versionCode)'"
applicationId=$(aapt dump badging ${apkFilePath} | grep -oP '(?<=package: name=).*(?=versionCode)')
echo "applicationId: is ${applicationId}"
#--------launch---------
if test -z "$applicationId"
then
echo "applicationId: is NULL"
exit 0;
fi
echo "____________________START_APPLICATION_ID________________________"
echo "applicationId: ${applicationId}"
echo "____________________END_APPLICATION_ID__________________________"
echo "____________________START_LAUNCHER______________________________"
for SERIAL in $(adb devices | grep -v List | cut -f 1);
do `adb -s ${SERIAL} shell monkey -p ${applicationId} -c android.intent.category.LAUNCHER 1`;
done
echo "____________________END_LAUNCHER________________________________"
I added to the answer from #WorkingMatt
I updated his answer to additionally do the following things
Attempt to connect to all devices on the local network with open port 5555. Warning: this may be a security risk. Beware connecting to arbitrary ports unless you know that it is safe. I am not trained in cybersecurity, so take my advice here with a grain of salt.
Uninstall the previous version of the package if there is one installed (In my case I am uninstalling to remove previous app data)
#!/bin/bash
echo "Installatron2"
# Connect to all devices on the local network (in our case 192.168.0.0)
# This section requires nmap (You may need sudo apt install nmap)
echo "Scanning the network for connected debuggable devices"
ADDRESSES=$(nmap --open -p 5555 192.168.0/24 -oG - | grep "/open" | awk '{ print $2 }')
for ADDRESS in $ADDRESSES;
do
adb connect $ADDRESS
done
# Print devices connected to
echo "Connected to the following devices"
echo "$(adb devices)"
# Iterate through all apks in current directory
for SERIAL in $(adb devices | tail -n +2 | cut -sf 1);
do
for APKLIST in $(ls *.apk);
do
#Get the package name from the apk file (Needs sudo apt install aapt)
package=$(aapt dump badging "$APKLIST" | awk '/package/{gsub("name=|'"'"'",""); print $2}')
# Optionally uninstalls the pre-existing version of this package (In case you do not want to retain data)
echo "Uninstalling $package on $SERIAL"
adb uninstall $package
# Now install with replacement to the same device
echo "Installatroning $APKLIST on $SERIAL"
adb -s $SERIAL install -r $APKLIST
done
done
echo "Installatron2 has left the building"
With Android Debug Bridge version 1.0.29, try this bash script:
APK=$1
if [ ! -f `which adb` ]; then
echo 'You need to install the Android SDK before running this script.';
exit;
fi
if [ ! $APK ]; then
echo 'Please provide an .apk file to install.'
else
for d in `adb devices | ack -o '^\S+\t'`; do
adb -s $d install $APK;
done
fi
Not sure if it works with earlier versions.
The key is to launch adb in a separate process (&).
I came up with the following script to simultaneously fire-off installation on all of the connected devices of mine and finally launch installed application on each of them:
#!/bin/sh
function install_job {
adb -s ${x[0]} install -r PATH_TO_YOUR_APK
adb -s ${x[0]} shell am start -n "com.example.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
}
#iterate over devices IP-addresses or serial numbers and start a job
while read LINE
do
eval x=($LINE)
install_job ${x[0]} > /dev/null 2>&1 &
done <<< "`adb devices | cut -sf 1`"
echo "WATING FOR INSTALLATION PROCESSES TO COMPLETE"
wait
echo "DONE INSTALLING"
Note 1: the STDOUT and STDERR are suppressed. You won't see any "adb install" operation result. This may be improved, I guess, if you really have to
Note 2: you could also improve script by providing args instead of hardcoded path and activity names.
That way you:
Don't have to manually perform install on each device
Don't have to wait for one install to finish in order to execute another one (adb tasks are launched in parallel)
Originated from here: Make The Previous Post A Mass APK Installer That Does Not Uses ADB Install-Multi Syntax
#echo off
:loop
::-------------------------- has argument ?
if ["%~1"]==[""] (
echo done.
goto end
)
::-------------------------- argument exist ?
if not exist %~s1 (
echo error "%~1" does not exist in file-system.
) else (
echo "%~1" exist
if exist %~s1\NUL (
echo "%~1" is a directory
) else (
echo "%~1" is a file! - time to install:
call adb install %~s1
)
)
::--------------------------
shift
goto loop
:end
pause
::: ##########################################################################
::: ## ##
::: ## 0. run: adb devices - to start the deamon and list your device ##
::: ## ##
::: ## 1. drag&drop ANY amount of files (APK) over this batch files, ##
::: ## ##
::: ## - it will install them one by one. ##
::: ## - it just checks if file exists. ##
::: ## - it does not checks if it is a valid APK package ##
::: ## - it does not checks if package-already-installed ##
::: ## - if there is an error you can always press [CTRL]+[C] ##
::: ## to stop the script, and continue from the next one, ##
::: ## some other time. ##
::: ## - the file is copied as DOS's 8.3 naming to you ##
::: ## don't need to worry about wrapping file names or renaming ##
::: ## them, just drag&drop them over this batch. ##
::: ## ##
::: ## Elad Karako 1/1/2016 ##
::: ## http://icompile.eladkarako.com ##
::: ##########################################################################
Since I can't comment on the answer by #Tom, this worked for me on OSX 10.13
adb devices | tail -n +2 | cut -sf 1 | xargs -IX adb -s X install -r path/to/apk.apk
(Change the little i to a big I)
I was wanting to log what was happening whilst installing, also needed it to be slightly comprehendable. Ended up with:
echo "Installing app on all connected devices."
adb devices | tail -n +2 | cut -sf 1 | xargs -I % sh -c '{ \
echo "Installing on %"; \
adb -s % \
install myApp.apk; \
; }'
Tested on Linux & Mac
-Get all the apk stored in .apk folder
-Install and replace app on devices
getBuild() {
for entry in .apk/*
do
echo "$entry"
done
return "$entry"
}
newBuild="$(getBuild)"
adb devices | while read line
do
if [! "$line" = ""] && ['echo $line | awk "{print $2}"' = "device"]
then
device='echo $line | awk "{print $1}"'
echo "adb -s $device install -r $newbuild"
adb -s $device install -r $newbuild
fi
done