As a heavy user of Debian based system like Ubuntu, if you’re developing Java Swing applications and want to distibute them to end users either for testing purposes or as a stable software, the first thing you think about is the Debian archive. Distributing Java software as JAR files may not be the best thing towards Debian OS and its derivatives users.
You still have many helper scripts like javahelper
( sudo apt-get install javahelper
) which is itself a bunch of scripts (jh_something
), each one having a specific purpose, to help you package your Java application as a Debian file. Besides, it gets irritating to use embedded package installers which do not respect to an extent the system packaging policies and which steals some of your freedom in that matter.
So, What about using only one script that semi-automates the debian packaging for us?
Well, in the recent post Bomico, we gave mention of a tiny Java application that had to be debianized in order to be natively installed in Ubuntu 12.04. To achieve this, we wrote a small script ( JDebianizer script ) that semi-automates debian packaging for us.
The follwoing is the so-called JDebianizer script as it was snapshot the first time. If you want to get the updated script please go to JDebianizer Github REPO:
#!/bin/bash # Title : JDebianizer # Description : Script tested only in Ubuntu. # This script is for Java developers who want to package a simple application for Ubuntu users as a Debian file. # Rules DO NOT execute this script with root power (sudo). # The script will try to install md5deep needed to generate md5 sums. # If no internet connection, md5sums will be used instead. # JDebianizer is onsole-only, so run it from Terminal or any other Shell. # Script is compliant only with BASH & KSH. Don't run it with SH, ZSH, DASH..). # Usage : In order to run the JDebianizer, switch to current directory that contains the script # and enter: # ./jdebianizer # or: # cd /path/to/containing/folder && bash jdebianizer # Dependencies : md5deep, whiptail, zenity # Author : Hanine HAMZIOUI <hanynowsky@gmail.com> حنين # Version : 1.0a # License : GNU GPL V3+ # Date created : Wed 14 Nov 2012 12:40:32 AM WET # ----------------- TODO ----------------------------- # TODO 1- add support for several icon sizes # TODO 2- add support for verbosity # TODO 3- add support for javadoc: jh_installjavadoc # TODO 4- add support for many config files # TODO 5- add support for other application folders (/etc /usr/share/menu) # -------------- Global variables ---------------------- JDVERSION="JDebianizer 1.0. \nCopyright (C) 2012 - 2013. Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. JDebianizer is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Written by Hanine HAMZIOUI." ROWS=$(echo "$LINES" | bc ) COLS=$(echo "$COLUMNS" | bc) LOGFILE=$HOME/tmp/jdebianizer.log CONFIGFILE=$HOME/.config/jdebianizer.conf TEMPFILE=$HOME/tmp/jdtemp.log ZWINICON=/usr/share/icons/hicolor/48x48/apps/distributor-logo.png # ----------------Re-execute the SCRIPT----- restartscript(){ echo "JDebianzier filename is: $0" filename=$(echo "$0" | sed -e 's/ /\\ /g' ) echo "Modified JDebianizer filename is: $filename" if [ -f "$filename" ]; then eval bash "$filename" else echo "Path to file is incorrect or contains trailing spaces. (e.g. ~/Ubuntu One/jdebianizer)"; exit 0 fi } # ----------------JAYATANA INSTALLER -------- DESKTOP=$(echo $XDG_CURRENT_DESKTOP) JDKPATH=$(echo $JAVA_HOME | grep .) USERHOME=$(echo $HOME) JAYATANADD="http://java-swing-ayatana.googlecode.com/svn/tags/1.2.4/jayatana" JAYABUILD="$USERHOME/jayatana/build.xml" JAYALOG="$USERHOME/Desktop/jayatana-stall.log" # INSTALL JAYAINSTALL(){ sudo apt-get -y install openjdk-7-jdk libunity-dev libxt-dev gcc make ant subversion sudo update-java-alternatives -s java-1.7.0-openjdk-amd64 svn checkout $JAYATANADD sudo ant install -buildfile $JAYABUILD -v sudo ant config -v sudo update-alternatives --config java sudo update-alternatives --config javac sudo ant install -Djava.home.7=/usr/lib/jvm/java-7-openjdk-amd64 -f $JAYABUILD -v -l $JAYALOG sudo ant config -Djava.home.7=$JDKPATH -buildfile $JAYABUILD -v -l $JAYALOG sudo chmod 777 $JAYALOG echo "Jayatana Installation finished. Run a Java Swing Application and check if it is integrated with global menu." whiptail --msgbox "Jayatana Installation finished. Run a Java Swing Application and check if it is integrated with global menu.\nA log file : $JAYALOG was created." "$LINES" "$COLUMNS" } INSTALLCOM () { if [ -d "$JAVA_HOME/jre/lib/endorsed" ] then CHECKJAYA=$(ls $JAVA_HOME/jre/lib/endorsed/* | grep "jayatana") if [ -n "$CHECKJAYA" ] then whiptail --yesno "Seems like Jayatana is already installed. Proceed anyway?" 20 80 --title "Jayatana" --backtitle "Jayatana Installation Check" if [ "$?" = 0 ] then echo "Trying to re-install Jayatana"; eval JAYAINSTALL else echo "Aborted by $USER"; eval restartscript fi else echo "Seems like Jayatana is not installed."; eval JAYAINSTALL fi else echo "Jayatana seems to be not installed yet for your default JRE."; eval JAYAINSTALL fi } # UNINSTALL UNINSTALLCOM (){ sudo ant deinstall -buildfile $JAYABUILD -v sudo ant deconfig -buildfile $JAYABUILD -v sudo ant deconfig -Djava.home.7=$JDKPATH -buildfile $JAYABUILD -v -logfile $JAYALOG echo "Jayatana uninstallation has finished." } # DELETE Jayatana Folder created by subversion checkout UNDIR() { whiptail --yesno "Delete Jayatana Folder too?" "$LINES" "$COLUMNS" --backtitle "Ubuntu Global Menu Support for Java Swing Applications" --title "JDebianizer" if [ "$?" = 0 ]; then mv $HOME/jayatana $HOME/.local/share/Trash/files/ elif [ "$?" = 1 ]; then echo "Jayatana Folder is kept by $USER , you can delete it later : ~/jayatana"; else echo "Jayatana Folder is kept by $USER , you can delete it later : ~/jayatana"; fi } # COMMON COMMON() { echo "$JDKPATH : is your default JDK." echo $(java -version) } # PROMPT INSTALL RUNINST() { eval COMMON; whiptail --yesno "Install/Uninstall Jayatana (ESCAPE or CTRL+C to cancel)" "$LINES" "$COLUMNS" --yes-button "Install" --no-button "Uninstall" --backtitle "Ubuntu Global Menu Support for Java Swing Applications" --title "JDebianizer" case "$?" in 0) eval INSTALLCOM; exit 0;; 1) eval UNINSTALLCOM;eval UNDIR;exit 0;; 255) echo "Aborted by $USER";exit 0;; # code returned by ESCAPE is 255 esac } # JAYATANA MAIN jayamain() { # "${DESKTOP,,}" if [ "${DESKTOP}" = "unity" ] || [ "${DESKTOP}" = "Unity" ]; then eval RUNINST else echo "Your Desktop environment is ${DESKTOP}. You cannot Install Jayatana. (Required: Unity Shell)" fi } # -------------------------- ARGS ----------- argfu(){ for arg in $@ do case "$arg" in --version|--v|--V) unset arg; echo -e "$JDVERSION"; exit 0;; --help|--h|--?|-?) echo -e "Run the script and follow instructions if any.\nUSAGE: \n./jdebianizer [OPTION...]\n\nOPTIONS: \n--v, --version Show the package version\n--c, --clean Remove files created by JDebianizer\n";exit 0;; --clean|--c) echo -e "Removing JDebianizer files"; if [ -f "$LOGFILE" ]; then rm -v $LOGFILE else echo "No Log File found." fi if [ -f "$CONFIGFILE" ]; then rm -v $CONFIGFILE else echo "No Config File Found." fi exit 0;; -v|--verbose) echo -e "Running in Verbose mode.";exit 0;; # TODO set the var to be used with whiptail "") break;; esac done } argfu "$@"; # START # Make sure the user has copied jar libraries if any and main executable package jar in a given folder start() { # clear the screen tput clear # Move cursor to screen location X,Y (top left is 0,0) tput cup 2 15 # Set a foreground colour using ANSI escape tput setaf 3 echo "JDebianizer. 1.0. (Debianize your Java Application)" tput cup 3 15 tput setaf 5 echo "https://github.com/hanynowsky/jdebianizer" tput sgr0 tput cup 5 17 # Set reverse video mode tput rev echo "I M P O R T A N T - N O T I C E" tput sgr0 tput cup 7 15 echo "A. Create a folder and put your executable Java program as well as its dependencies (jar file libraries) in it" tput cup 8 15 echo "B. The executable jar file should have the same lowercase name as the package. E.g: logism.jar" tput cup 9 15 echo "C. Prepare a 48x48 PNG image to be used as the icon of your Java application" tput cup 10 15 echo "D. You can eventually add documentation files you want to include in the debian package." # Set bold mode tput bold tput cup 13 15 echo "1. Start JDebianzer" tput cup 14 15 echo "2. Exit JDebianzer" tput cup 15 15 echo "3. Install Jayatana (Ubuntu Global Menu Support for Java Swing Applications)" tput cup 17 15 read -p "Enter your choice [ 1 / 2 / 3 ] " choice if [ "$choice" = "1" ] ; then echo "Starting JDebianizer..." elif [ "$choice" = "3" ] ; then tput sgr0; echo "Starting Jayatana installer..."; eval jayamain elif [ "$choice" = "2" ] ; then exit 0 else echo "exiting JDebianizer"; exit 0 fi tput clear tput sgr0 tput rc } eval start; whiptail --yesno "Welcome to JDebianizer. First of All, copy your package's main executable jar file (Must have the same name as the package name), as well as its dependency jar libraries, in the same folder (example: /home/yourusername/mypackagejars_folder), then select 'yes'. Clicking no means you still have not done so." "$LINES" "$COLUMNS" --clear if [ "$?" -eq 0 ]; then echo "Great! Let us continue then." else echo "Existing script. Retry when you're ready."; exit 0; fi exitoption(){ if [ $exitcode = 0 ]; then echo "$USER said okay: $exitcode" elif [ ${exitcode} = 1 ]; then echo "$USER said NO - Canceled: $exitcode"; exit 0 else echo "$? - Continue..."; fi } # ---------------CONFIG File ------------------ packpropform(){ zenity --forms --text="Package Properties" --add-entry="Package-Name" --add-entry="Version" --add-entry="Maintainer-Name" --add-entry="Maintainer-Surname" --add-entry="Email" --add-entry="Homepage" --window-icon $ZWINICON --title "JDebianizer" > $TEMPFILE exitcode=$? eval exitoption; echo "Grabbed Package Properties" } parseconfig(){ i=0 while read line; do if [[ "$line" =~ ^[^#]*= ]] then name[i]=$(echo $line | cut -d'=' -f 1) array[i]=$(echo $line | cut -d'=' -f 2) ((i++)) # echo "${array[i]}" fi done < $CONFIGFILE } lineasvar(){ cat $TEMPFILE | sed -e 's#|#\n#g' > $LOGFILE i=0 while read line; do array[i]=$(echo "${line}") if [ -z "${array[i]}" ] then echo "No field should be empty. Please Retry."; exit 0 else echo "${array[i]}" fi ((i++)) done < $LOGFILE echo "The entered item 1 is: ${array[0]}" | tr '[:upper:]' '[:lower:]' echo "The entered item 2 is: ${array[1]}" | tr '[:upper:]' '[:lower:]' echo "The entered item 3 is: ${array[2]}" echo "The entered item 4 is: ${array[3]}" echo "The entered item 5 is: ${array[4]}" echo "The entered item 6 is: ${array[5]}" rm $TEMPFILE } if [ -f "$CONFIGFILE" ] then whiptail --yesno "Config File Exists. Overwrite it?" 20 50 if [ "$?" -eq 0 ] then eval packpropform; eval lineasvar else eval parseconfig; echo "Found config file for package ${array[0]}" fi else echo "CONFIG FILE does not exist. Please enter package properties values."; eval packpropform; eval lineasvar fi PACKNAME=$(echo "${array[0]}" | tr '[:upper:]' '[:lower:]') # Package name : must be lowercase "${PACKNAME,,}" upperpackname=$(echo "${PACKNAME}" | sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g') PVERSION=$(echo "${array[1]}" | tr '[:upper:]' '[:lower:]') # Package Ubuntu version ROOTDIR=$(echo $HOME/Desktop/$PACKNAME"_"$PVERSION | grep .) # Root folder to debianize MAND="man" # Workaround for key word man mfname=$(echo "${array[2]}" | tr '[:lower:]' '[:upper:]') msname=$(echo "${array[3]}" | sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g') maintainer="$msname $mfname" memail=$(echo "<${array[4]}>" | tr '[:upper:]' '[:lower:]') homepage=$(echo "${array[5]}" | tr '[:upper:]' '[:lower:]') # --------------- Append Config File ------------------ echo "[PACKAGE]" > "$CONFIGFILE" # TODO before appending check for duplicates by PACKNAME echo "PACKNAME=${PACKNAME}" >> "$CONFIGFILE" echo "PVERSION=${PVERSION}" >> "$CONFIGFILE" echo "MFNAME=${mfname}" >> "$CONFIGFILE" echo "MSNAME=${msname}" >> "$CONFIGFILE" echo "MEMAIL=${memail}" >> "$CONFIGFILE" echo "HOMEPAGE=${homepage}" >> "$CONFIGFILE" # ------------- Desktop File variables ---------------- PICON="/usr/share/icons/hicolor/48x48/apps/$PACKNAME.png" # Desktop file Icon COMMENT=$(echo "${PACKNAME} $PVERSION - A Java based Application" sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g') # Desktop file comment GENAME=$(echo "${PACKNAME}"|sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g') # Desktop file generic name DNAME=$(echo "${PACKNAME}"| sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g') # Desktop file application name - First letter is # Uppercase "${DNAME^^[PATTERN]}" PTYPE="Application" # Desktop file type DVERSION="1.0" # Desktop file version # CREATE NECESSARY DIRECTORIES # We can create them using : mkdir $ROOTDIR/{DEBIAN,usr{share{man{man1},icons,doc{$PACKNAME},$PACKNAME{lib},applications},bin}} create_dirs(){ if [ ! -d "$ROOTDIR" ]; then mkdir -p $ROOTDIR; sudo chmod -R 777 $ROOTDIR # Unlock root folder else echo "Root folder exists. OK. Skipping."; sudo chmod -R 777 $ROOTDIR; sudo chown $USER:$USER -R $ROOTDIR fi BINDIR="${ROOTDIR}/usr/bin" if [ ! -d "${BINDIR}" ]; then mkdir -p ${BINDIR} else echo "bin folder exists. OK. Skipping." fi DEBDIR="${ROOTDIR}/DEBIAN" if [ ! -d "${DEBDIR}" ]; then mkdir -p ${DEBDIR} else echo "DEBIAN folder exists. OK. Skipping." fi DOCDIR="${ROOTDIR}/usr/share/doc/${PACKNAME}" if [ ! -d "$DOCDIR" ]; then mkdir -p $DOCDIR else echo "doc folder exists. OK. Skipping." fi SHAPPDIR="$ROOTDIR/usr/share/applications" if [ ! -d "$SHAPPDIR" ]; then mkdir -p $SHAPPDIR else echo "share applications folder exists. OK. Skipping." fi MANDIR="$ROOTDIR/usr/share/$MAND/man1" if [ ! -d "$MANDIR" ]; then mkdir -p $MANDIR else echo "man1 folder exists. OK. Skipping." fi PACKDIR="$ROOTDIR/usr/share/$PACKNAME" if [ ! -d "$PACKDIR" ]; then mkdir -p $PACKDIR else echo "Package folder exists.Ok. Skipping." fi LIBDIR="$ROOTDIR/usr/share/$PACKNAME/lib" if [ ! -d "$LIBDIR" ]; then mkdir -p $LIBDIR; echo "Created lib folder" else echo "lib folder exists.Ok. Skipping." fi DICONDIR="$ROOTDIR/usr/share/icons/hicolor/48x48/apps" if [ ! -d "$DICONDIR" ]; then mkdir -p $DICONDIR; echo "Created icon folder" else echo "icon folder exists.Ok. Skipping." fi } eval create_dirs; # ------------------Copy LIBRARIES & main binary EXECUTABLE----- sudo chmod 777 -R $ROOTDIR # Give full permission to allow writing libpath=$(zenity --file-selection --directory --title "Select the folder containing jars") exitcode=$? eval exitoption; echo "Jar Files Folder Confirmed." CHECKJARS=$(ls -1 $libpath/*.jar 2>/dev/null | wc -l) CHECKJAR=$(ls -1 $libpath/$PACKNAME.jar 2>/dev/null | wc -l) jarscount=$(echo "$CHECKJARS+0" | bc) if [ -d "$libpath" ] || [ $jarscount -gt 0 ]; then echo "Trying to copy: $libpath/*.jar" $LIBDIR"/" ; echo "${CHECKJARS} jar files found"; ls -l ${libpath} | grep "\.jar\$"; # grep "\.jar$" cp -v $libpath/*.jar $LIBDIR/ # $libpath"/." to cp all content; else echo "the folder you specified does not contain the necessary jar files." fi jarcount=$(echo "$CHECKJAR+0" | bc) if [ ! $jarcount -eq 0 ]; then mv $LIBDIR"/"$PACKNAME".jar" $PACKDIR"/"$PACKNAME".jar" else echo "Main jar not found" fi CHECKFILES=$(ls -1 $libpath 2>/dev/null | wc -l) a=$(echo $CHECKFILES+0 | bc) result=$(echo "$CHECKJARS" | bc) if [ $a -gt $result ]; then echo "folder has $CHECKFILES files, $CHECKJARS being jars" ;echo "WARNING: $libpath contains non-jar files."; echo "But we have not copied them. Copied only jar files." else echo "No files beside jar files on $libpath. Great! Let us continue." fi # -------------------------------------------------------------- echo "Working on: "$ROOTDIR " for debianizing package $PACKNAME" | grep . # --------------Create a DESKTOP FILE ---------------------- # We can use desktop-file-install to install the desktop file in a given folder DESKFILE="$ROOTDIR/usr/share/applications/$PACKNAME.desktop" # Desktop file path name writedeskfile(){ echo "Creating Desktop file"$DESKFILE echo "[Desktop Entry]" > $DESKFILE echo "Type=$PTYPE" >> $DESKFILE echo "Name=$DNAME" >> $DESKFILE if [ -z "$CATEGORIES" ] && [ -z $CATOTHER ]; then desktop-file-edit --add-category "Utility;Java;" $DESKFILE else echo $CATEGORIES fi echo "Other categories: " $CATOTHER echo "GenericName=$GENAME" >> $DESKFILE echo "Comment=$COMMENT" >> $DESKFILE echo "Exec=$PACKNAME" >> $DESKFILE echo "Terminal=false" >> $DESKFILE echo "Icon=$PICON" >> $DESKFILE echo "Version=$DVERSION" >> $DESKFILE MCATGET=$(whiptail --checklist "Choose Main Categories (Desktop File *.desktop). Use space to select and Tab to switch." 25 50 16 "AudioVideo" 0 "Audio" 0 "Video" 0 "Development" 0 "Game" 0 "Graphics" 0 "Office" 0 "Science" 0 "Settings" 0 "Utility" 1 "Network" 0 "Education" 0 "System" 0 --noitem 3>&1 1>&2 2>&3) exitcode=$? eval exitoption; echo "Main Desktop categories copied." ACATGET=$(whiptail --checklist "Choose Additional Categories (Desktop File *.desktop). Use space to select and Tab to switch." "$LINES" "$COLUMNS" 25 "Java" 1 "GTK;GNOME" 0 "Building" 0 "IDE" 0 "Profiling" 0 "Translation" 0 "Calendar" 0 "ContactManagement" 0 "Database" 0 "Dictionary" 0 "Chart" 0 "Email" 0 "Finance" 0 "FlowChart" 0 "PDA" 0 "ProjectManagement" 0 "Presentation" 0 "2DGraphics" 0 "VectorGraphics" 0 "RasterGraphics" 0 "3DGraphics" 0 "TextTools" 0 "InstantMessaging" 0 "Chat" 0 "WebDevelopment" 0 "Music" 0 "Biology" 0 "Chemistry" 0 "ComputerScience" 0 "Electricity" 0 "ImageProcessing" 0 "Physics" 0 "Engineering" 0 "ConsoleOnly" 0 --noitem 3>&1 1>&2 2>&3) exitcode=$? eval exitoption; echo "Additional Desktop categories confirmed." CATEGORIES=$(echo "$MCATGET"";""$ACATGET" | sed -e 's# #;#g' -e 's#"##g') # Desktop file Categories CATOTHER=$(whiptail --inputbox "Any other categories to add (Seperate by semi-comma). Leave blank if none." 10 30 3>&1 1>&2 2>&3 | sed -e 's# ##g' -e 's#[^a-zA-Z\;]##g') # Desktop Other categories desktop-file-edit --add-category $CATEGORIES $DESKFILE CATOTHERF=$("${CATOTHER}" | tr '[:upper:]' '[:lower:]') desktop-file-edit --add-category $(echo "${CATOTHERF}" | sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g') $DESKFILE echo "StartupNotify=true" >> $DESKFILE echo "X-Ubuntu-Gettext-Domain=$PACKNAME" >> $DESKFILE } pastedicon(){ LOCICON=$(zenity --file-selection --file-filter "*.png" --title "Select Your package Icon (PNG format and 48x48 resolution)") exitcode=$? eval exitoption; echo "Desktop Icon confirmed." if [ -r $LOCICON ]; then cp -v -u $LOCICON "${ROOTDIR}${PICON}" else echo "No PNG Icon found"; whiptail --msgbox "No PNG found. Exiting" $ROWS $COLS; exit 0 fi } if [ -f "$ROOTDIR/$PICON" ]; then echo "Desktop icon already exists." else eval pastedicon fi if [ -f "$DESKFILE" ]; then whiptail --yesno "Desktop file already exists. Overwrite it?" 20 80 if [ "$?" -eq 0 ]; then rm -v "$DESKFILE"; eval writedeskfile else echo "Existing Desktop file kept by $USER" fi else eval writedeskfile fi desktop-file-edit ${DESKFILE} # -----------------------Create CONTROL file---------------- CONTFILE=$ROOTDIR/DEBIAN/control priority=$(echo "optional" | tr '[:upper:]' '[:lower:]') # All properties are lowercase architecture=$(echo "all" | tr '[:upper:]' '[:lower:]') instsize=$(du -s $ROOTDIR | grep -o "^[0-9]*") # size should be appended at the very end sectionstring=(admin cli-mono comm database debug devel doc editors education electronics embedded fonts games gnome gnu-r gnustep graphics hamradio haskell httpd interpreters introspection java kde kernel libdevel libs lisp localization mail math metapackages misc net news ocaml oldlibs otherosfs perl php python ruby science shells sound tasks tex text utils vcs video web x11 xfce zope) sectionget(){ sectionvalue=$(whiptail --inputbox "Enter the appropriate Control Section amongst the following list (type java if you are not sure):\n\nadmin cli-mono comm database debug devel doc editors education electronics embedded fonts games gnome gnu-r gnustep graphics hamradio haskell httpd interpreters introspection java kde kernel libdevel libs lisp localization mail math metapackages misc net news ocaml oldlibs otherosfs perl php python ruby science shells sound tasks tex text utils vcs video web x11 xfce zope" 25 80 "java" 3>&1 1>&2 2>&3) for (( s=0; s < ${#sectionstring[*]}; s++ )); do lowersectv=$(echo "${sectionvalue}" | tr '[:upper:]' ':lower:') if [ "${lowersectv}" = "${sectionstring[s]}" ] then section="${lowersectv}"; echo "It is okay. We have found your control section listed." else section="java"; echo "Warriga, what you have typed does not figure in the Debian control section list...:(" 2>/dev/null fi done echo "Control file section property confirmed." } writecont(){ eval sectionget; exitcode=$? eval exitoption; depends=$(echo -e "libjava-gnome-java (>= 4.1.1), jarwrapper" | zenity --text-info --title "Control File dependencies. separate with comma and space." --editable --width=700 --height=300) exitcode=$? eval exitoption; echo "Control file dependencies confirmed." defscription="Body Mass Index Computer\n Check your body mass index with Bomico.\n Bomico is a small program written in Java and interfaced with Swing.\n See Documentation online at https://github.com/hanynowsky/bomico/wiki\r" description=$(echo -e $defscription | zenity --text-info --title "Control File description (First line must not exceed 80 Characters.)" --editable --width=600 --height=300) exitcode=$? eval exitoption; echo "Control file description confirmed." echo "Creating postinst file "$CONTFILE echo "Package: ${PACKNAME}" >> $CONTFILE echo "Version: $PVERSION" >> $CONTFILE echo "Section: ${section}" >> $CONTFILE echo "Priority: ${priority}" >> $CONTFILE echo "Architecture: ${architecture}" >> $CONTFILE echo "Depends: $depends" >> $CONTFILE echo "Maintainer: $maintainer $memail" >> $CONTFILE echo "Installed-Size: $instsize" >> $CONTFILE echo "Homepage: $homepage">> $CONTFILE echo -e "Description: $description\r" >> $CONTFILE } if [ -f "$CONTFILE" ]; then whiptail --yesno "control file exists. Overwrite it?" 20 80 if [ "$?" -eq 0 ]; then rm -v "$CONTFILE"; eval writecont else echo "Existing control file kept by $USER" fi else eval writecont fi # -----------------------Create PREINST file---------------- PREINSTFILE=$ROOTDIR/DEBIAN/preinst if [ -f "$PREINSTFILE" ]; then rm -v $PREINSTFILE else echo "postinst file not present. Going ahead..." fi echo "Creating preinst file "$PREINSTFILE echo "#!/bin/sh -e" > $PREINSTFILE echo "echo 'preinst is executing'" >> $PREINSTFILE echo "javahome=\$(echo \$JAVA_HOME)" >> $PREINSTFILE echo "javadef=\"/usr/lib/jvm/default-java/jre/bin/java\"" >> $PREINSTFILE echo "if [ -n \"\$javahome\" ] || [ -f \"\$javadef\" ]; then echo \"your JAVA_HOME is \$javahome\"" >> $PREINSTFILE echo "else whiptail --yesno 'ERROR: JAVA_HOME seems to be not set. Or no JRE is installed.\n Do you want to install OpenJDK JRE?' 25 50" >> $PREINSTFILE echo "if [ \"\$?\" -eq 0 ]; then sudo apt-get install -y openjdk-7-jre" >> $PREINSTFILE echo "else echo 'Please Install a Java JRE and re-install this package again.'; exit 0" >> $PREINSTFILE echo "fi" >> $PREINSTFILE echo "fi" >> $PREINSTFILE echo "exit 0;" >> $PREINSTFILE # -----------------------Create POSTINST file---------------- PINSTFILE=$ROOTDIR/DEBIAN/postinst if [ -f "$PINSTFILE" ]; then rm -v $PINSTFILE else echo "postinst file not present. Going ahead..." fi echo "Creating postinst file "$PINSTFILE echo "#!/bin/sh -e" >> $PINSTFILE echo "echo postinst is executing" >> $PINSTFILE echo "LOGUSER=\`who | sed -e 's#-##g' -e 's#tty##g' -e 's#pts##g' -e 's#[0-9()\:]##g' -e 's#^[ \t]*##' -e 's#[ \t]*\$##' | grep . -m 1\`" >> $PINSTFILE echo "BPATH=/usr/share/$PACKNAME/$PACKNAME.jar" >> $PINSTFILE echo "DPATH=/usr/share/applications/$PACKNAME.desktop" >> $PINSTFILE echo "LDPATH=\$HOME/.local/share/applications" >> $PINSTFILE echo "LDFPATH=\$HOME/.local/share/applications/$PACKNAME.desktop" >> $PINSTFILE echo "sudo chmod +x \$BPATH" >> $PINSTFILE echo "sudo chmod 644 \$DPATH" >> $PINSTFILE echo "cp \$DPATH \$LDPATH" >> $PINSTFILE echo "echo Logged user is \$LOGUSER" >> $PINSTFILE echo "sudo chown \$LOGUSER:\$LOGUSED \$LDFPATH" >> $PINSTFILE #echo "sudo chown \$LOGUSER:\$LOGUSER \$LDFPATH" >> $PINSTFILE echo "exit 0;" >> $PINSTFILE # -----------------------Create PRERM file---------------- PRERMFILE=$ROOTDIR/DEBIAN/prerm if [ -f "$PRERMFILE" ]; then rm -v $PRERMFILE else echo "prerm file not present. Going ahead..." fi echo "Creating prerm file "$PRERMFILE echo "#!/bin/sh -e" >> $PRERMFILE echo "echo prerm is being executed" >> $PRERMFILE echo "exit 0;" >> $PRERMFILE # -----------------------Create POSTRM file---------------- POSTRMFILE=$ROOTDIR/DEBIAN/postrm if [ -f "$POSTRMFILE" ]; then rm -v $POSTRMFILE else echo "postinst file not present." fi echo "Creating Postrm file "$POSTRMFILE echo "#!/bin/sh -e" >> $POSTRMFILE echo "echo postrm is executing" >> $POSTRMFILE echo "# Remember that if symlinks are used , an embedded IF dealing with symlink must be used -L" >> $POSTRMFILE echo "PHOME=\$HOME/$PACKNAME" >> $POSTRMFILE echo "LDFILE=\$HOME/.local/share/applications/$PACKNAME.desktop" >> $POSTRMFILE echo -e "if [ -d "\$PHOME" ]; then sudo chmod 777 -R \$PHOME; rm -r \$PHOME \n else echo '$PACKNAME home folder not found' \n fi \n if [ -f "\$LDFILE" ]; then rm \$LDFILE \n else echo '$PACKNAME.desktop in local folder not found' \n fi " >> $POSTRMFILE echo "exit 0;" >> $POSTRMFILE echo 'creator was executed'. # -----------------Create the FAKE BINARY------------------ FBINARY=$ROOTDIR/usr/bin/$PACKNAME if [ -f "$FBINARY" ]; then rm -v $FBINARY else echo "Fake binary $FBINARY file not present." fi echo "Creating fake binary file $FBINARY" echo "#!/bin/sh" >> $FBINARY echo "export EXECBIN=/usr/share/$PACKNAME" >> $FBINARY echo "argfu(){ for arg in \$@ do case \$arg in --version|--v|--V) unset arg; echo '${upperpackname} $PVERSION'; exit 0;; --help|--h|--?|-?) echo 'Run the script and follow instructions if any.\nCheck Manual (man $PACKNAME).'; exit 0;; '') break;; esac done } argfu \$@;" >> $FBINARY echo "java -jar \$EXECBIN/$PACKNAME.jar \$*" >> $FBINARY # ---------------- AUTHORS File --------------- writeauth(){ echo "$maintainer $memail" > $DOCDIR/AUTHORS echo "Surname FAMILYNAME <authoremailusername@domain.ext>" | zenity --text-info --title "Other Authors" --editable --height=200 --width=490 >> $DOCDIR/AUTHORS } if [ -f "$DOCDIR/AUTHORS" ]; then whiptail --yesno "AUTHORS file exists. Overwrite it?" "$LINES" "$COLUMNS" if [ "$?" -eq 0 ]; then eval writeauth else echo "The existing AUTHORS file is kept." fi else eval writeauth fi # ---------------- COPYRIGHT File ---------- writecopy(){ PSOURCE=$(whiptail --inputbox "Enter Package Source code repository here: " 25 50 "http://" 3>&1 1>&2 2>&3) PLICENSE=$(whiptail --radiolist "Choose Copyright License" 25 50 14 "BSD" 0 "GPL" 0 "GPL-1" 0 "GPL-2" 0 "GPL-3" 1 "LGPL" 0 "LGPL-2" 0 "LGPL-2.1" 0 "LGPL-3" 0 "GFDL-1.3" 0 "GFDL-1.2" 0 "GFDL" 0 "Artistic" 0 "Apache-2.0" 0 --noitem 3>&1 1>&2 2>&3) echo "Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=REVISION" > $DOCDIR/copyright echo "Upstream-Name: $PACKNAME" >> $DOCDIR/copyright echo "Upstream-contact: $maintainer $memail" >> $DOCDIR/copyright echo "Source: $PSOURCE" >> $DOCDIR/copyright echo -e "\n" >> $DOCDIR/copyright echo "Files: *" >> $DOCDIR/copyright cyear=$(date +%Y) echo "Copyright: Copyright $cyear $maintainer $memail" >> $DOCDIR/copyright echo "License: $PLICENSE" >> $DOCDIR/copyright echo " " >> $DOCDIR/copyright echo -e "\n" >> $DOCDIR/copyright echo "You should have received a copy of the GNU License along with $PACKNAME. If not, see <http://www.gnu.org/licenses/>. . On Debian systems, the complete text of the GNU General Public License version can be found in /usr/share/common-licenses/" >> $DOCDIR/copyright } if [ -f "$DOCDIR/copyright" ]; then whiptail --yesno "Copyright file exists. Overwrite it?" "$LINES" "$COLUMNS" if [ "$?" -eq 0 ]; then eval writecopy else echo "The existing Copyright file is kept." fi else eval writecopy fi # --------------------README File ------------ writereadme(){ READMETEXT=$(echo "" | zenity --text-info --title "Edit README file" --editable) echo -e "${upperpackname}. ${PVERSION}\n" > $DOCDIR/README echo "Description: $READMETEXT" >> $DOCDIR/README echo "Homepage: $homepage" >> $DOCDIR/README } GZFILEN="README" GZFILE="$DOCDIR/README" GZFUN="writereadme" gzaction(){ if [ -f "$GZFILE" ] && [ -f "$GZFILE.gz" ]; then whiptail --yesno "$GZFILEN & $GZFILEN.gz files exist. Overwrite GZIPED file?" "$LINES" "$COLUMNS" if [ "$?" -eq 1 ]; then rm -v "$GZFILE" else whiptail --yesno "Gzip existing $GZFILEN file (yes) & Create new $GZFILEN file (no)" "$LINES" "$COLUMNS" if [ "$?" -eq 0 ]; then gzip -v -f -9 $GZFILE else eval $GZFUN; gzip -v -f -9 $GZFILE fi fi elif [ ! -f "$GZFILE" ] && [ -f "$GZFILE.gz" ]; then whiptail --yesno "$GZFILEN.gz file exist. Overwrite it?" "$LINES" "$COLUMNS" if [ "$?" -eq 1 ]; then echo "Keeping exisiting $GZFILEN.gz" else eval $GZFUN; gzip -v -f -9 $GZFILE fi elif [ -f "$GZFILE" ] && [ ! -f "$GZFILE.gz" ]; then whiptail --yesno "$GZFILEN file exist. Overwrite it?" "$LINES" "$COLUMNS" if [ "$?" -eq 1 ]; then gzip -v -f -9 $GZFILE else eval $GZFUN; gzip -v -f -9 $GZFILE fi elif [ ! -f "$GZFILE" ] && [ ! -f "$GZFILE" ]; then $GZFUN; gzip -v -f -9 $GZFILE else echo "Nothing done for $GZFILEN file." fi } eval gzaction # ------------------- NEWS File -------------- TODAY=$(echo $(date +%a", "%d" "%b" "%Y" "%H:%M:%S" "%z)) writenews(){ echo -e "${upperpackname} $PVERSION: $TODAY Fixes and New Features: ----------------------- Initial support for Ubuntu Global Menu. Creation of .desktop installation file. 5 Formulas to calculate the BMI. Export BMI follow-up. Mediocre Audio support (Will be improved in future). Fixed Some layout issues." > $DOCDIR/NEWS readmev=$(cat $DOCDIR/NEWS | zenity --text-info --title "Edit NEWS File" --editable --width=500 --height=500) echo -e "$readmev" > $DOCDIR/NEWS } GZFILEN="NEWS" GZFILE="$DOCDIR/NEWS" GZFUN="writenews" eval gzaction # ------------------- CHANGELOG.DEBIAN File -------------- writeclog(){ echo "Writing changelog.Debian" echo -e "$PACKNAME ($PVERSION) stable; urgency=low * Updated Exit Action. Closes: #999999 * Added New Icons. -- $maintainer $memail $TODAY" > $DOCDIR/changelog.Debian readclog=$(cat $DOCDIR/changelog.Debian | zenity --text-info --title "Edit changelog.Debian File" --editable --width=500 --height=500) echo -e "$readclog" > $DOCDIR/changelog.Debian } GZFILEN="changelog.Debian" GZFILE="$DOCDIR/changelog.Debian" GZFUN="writeclog" eval gzaction # ------------------- TODO_File -------------- writetodo(){ TODOLIST=$(echo -e "1- Add feature X.\n" | zenity --text-info --title "TODO LIST EDITOR" --editable) echo "TODO LIST: " > $DOCDIR/TODO echo -e "\n" >> $DOCDIR/TODO echo "$TODOLIST" >> $DOCDIR/TODO } if [ -f "$DOCDIR/TODO" ]; then whiptail --yesno "TODO file exists. Overwrite it?" 20 80 if [ "$?" -eq 0 ]; then eval writetodo else echo "The existing TODO file is kept."; export readtodo=$(cat $DOCDIR/TODO | zenity --text-info --title "Edit TODO File" --editable --width=500 --height=500); echo -e "$readtodo" > $DOCDIR/TODO fi else eval writetodo fi # ------------------THANKS File ---------------- writethanks(){ THANKSTEXT=$(echo -e "1- Special thanks go to: \n" | zenity --text-info --title "THANKS File EDITOR" --editable) echo "$THANKSTEXT" >> $DOCDIR/THANKS } if [ -f "$DOCDIR/THANKS" ]; then whiptail --yesno "THANKS file exists. Overwrite it?" 20 80 if [ "$?" -eq 0 ]; then eval writethanks else echo "The existing THANKS file is kept."; export readthx=$(cat $DOCDIR/THANKS | zenity --text-info --title "Edit THANKS File" --editable --width=500 --height=500); echo -e "$readthx" > $DOCDIR/THANKS fi else eval writethanks fi # ----------------- MANUAL File--------------------- MANFILE=$MANDIR/$PACKNAME.1 writeman(){ MANDATE=$(date "+%Y-%m-%d") SHORTDESC=$(whiptail --inputbox "Manual file Short description: " "$LINES" "$COLUMNS" "Body Mass Index Computer") LONGDESC=$(whiptail --inputbox "Manual file Long description: " "$LINES" "$COLUMNS" "A tiny Java application that calculates your body mass index.") echo ".TH ${PACKNAME} 1 $MANDATE ${PACKNAME} ${PACKNAME}" > $MANFILE echo ".SH NAME" >> $MANFILE echo "${upperpackname} - ${SHORTDESC}" >> $MANFILE echo ".SH SYNOPSIS" >> $MANFILE echo ".B" >> $MANFILE echo ".I ${PACKNAME}" >> $MANFILE echo "[OPTIONS]" >> $MANFILE echo ".SH DESCRIPTION" >> $MANFILE echo ".I ${PACKNAME}" >> $MANFILE echo "${LONGDESC}" >> $MANFILE echo "\." >> $MANFILE echo ".SH OPTIONS" >> $MANFILE echo "Help options" >> $MANFILE echo ".TP" >> $MANFILE echo "\\\fB\-?\\\fR, \\\fB\-\-help\\\fR" >> $MANFILE echo "Show help options" >> $MANFILE echo ".PP" >> $MANFILE echo "Application options" >> $MANFILE echo ".TP" >> $MANFILE echo "\\\fB\--version\\\fR, \\\fB\-\-v\\\fR" >> $MANFILE echo "Show version info." >> $MANFILE echo ".SH AUTHORS" >> $MANFILE echo "- ${maintainer} (${memail:1:(( ${#memail} - 2 ))}) - ${homepage}" >> $MANFILE manv=$(cat $MANFILE | zenity --text-info --title "Edit Manual File" --editable --width=500 --height=500) echo -e "$manv" > $MANFILE } GZFILEN="${PACKNAME}.1" GZFILE=${MANDIR}/${PACKNAME}.1 GZFUN="writeman" eval gzaction # ----------------- Other DOCS --------------------------- otherdocs=$(zenity --file-selection --title "Select other files to include - Cancel if none" --multiple) transodocs=$(echo "$otherdocs" | sed 's#|# #g') if [ -z "$otherdocs" ]; then echo "No other doc files selected" else cp -u -v -t $DOCDIR/ $transodocs fi # -----------------------CORRECT PERMISSION--------------- sudo chmod 755 -R $ROOTDIR if [ -f $ROOTDIR/DEBIAN/md5sums ]; then sudo chmod 644 -c $ROOTDIR/DEBIAN/md5sums else echo "md5sums does not exist." fi sudo chmod 644 -v $ROOTDIR/DEBIAN/control sudo chmod 644 -v $ROOTDIR/usr/share/doc/$PACKNAME/* sudo chmod 644 -v $ROOTDIR/usr/share/applications/* sudo chmod 644 -v $ROOTDIR/usr/share/icons/hicolor/48x48/apps/* sudo chmod 644 -v $ROOTDIR/usr/share/$MAND/man1/* sudo chmod 644 -v $ROOTDIR/usr/share/$PACKNAME/lib/*; JARPATH="$ROOTDIR/usr/share/$PACKNAME/$PACKNAME.jar" if [ -f "$JARPATH" ]; then echo "$JARPATH jar is found"; sudo chmod ugo-x -c $ROOTDIR/usr/share/$PACKNAME/$PACKNAME".jar" # remove execution right from executables but add it with postinst else echo "$JARPATH not found or owner/perm problem" fi # ---------- MD5 SUMS FILE for all files in usr folder.---- hasdeep=$(dpkg -s md5deep 2>/dev/null | grep "md5deep" -m 1) # INSTALL md5deep UTILITY - To generate MD5 sums if [ -z "$hasdeep" ]; then sudo apt-get install -y md5deep else echo "md5deep is already installed" fi export MATCH=$ROOTDIR"/" if [ -f "$ROOTDIR/DEBIAN/md5sums" ]; then echo "md5sums exists. removing it"; sudo rm -v $ROOTDIR/DEBIAN/md5sums else echo "md5sums file does not exist" fi echo "Creating md5sums file." md5deeper(){ md5deep -r $ROOTDIR | sed -e '/DEBIAN/g' -e "s#$MATCH##g" | perl -ne 's/^$//g || print' | tee $ROOTDIR/DEBIAN/md5sums; } md5classic(){ LINES=$(ls -R $ROOTDIR | grep ^"$ROOTDIR/usr" | sed -e 's/^[.]//g' -e 's/[:]$//g') # HIDDEN DIRS NOT SUPPORTED by PATTERN i=0 for line in $LINES; do if [ -d "$line" ]; then md5sum $line/* | sed -e "s#$MATCH##g" >> $ROOTDIR/DEBIAN/md5sums else echo "Directory. Skip." fi done perl -ne 's/^$//g || print' -i $ROOTDIR/DEBIAN/md5sums # Should be replaced by sed or awk } if [ -f "/usr/bin/md5deep" ]; then eval md5deeper else eval md5classic fi chmod 644 $ROOTDIR/DEBIAN/md5sums echo "MD5 Sums written in: " " $ROOTDIR/DEBIAN/md5sums" # ------------- DEBIAN PACKAGER--------------- echo "Executing debian builder" fakeroot dpkg-deb -v --build $ROOTDIR # ------------- LINTIAN ---------------------- echo "Executing Lintian & Desktop file validator" datum=$(eval echo $(date +%Y/%m/%d/:%H:%M:%S)) echo $datum > $LOGFILE lintian -v -i $ROOTDIR.deb | tee -a $LOGFILE | zenity --progress --text "Validating $PACKNAME..." --percentage 10 --pulsate --auto-close --no-cancel desktop-file-validate $ROOTDIR/usr/share/applications/$PACKNAME.desktop >> $LOGFILE linte=$(cat $LOGFILE | grep "E:") lintw=$(cat $LOGFILE | grep "W:") if [ -n "$linte" ]; then lemsg="ERRORS"; export nsicon="error" elif [ -n "$lintw" ]; then lwmsg="WARNINGS"; export nsicon="error" else lmsg="no errors, nor warnings."; export nsicon="emblem-default" fi FINSTALTEXT="finished Debianization of $PACKNAME at $datum with $lmsg$lemsg / $lwmsg. Check $LOGFILE though for warnings (W:) or errors (E:) and correct them by running JDebianizer again. If not, proceed with the Debian file installation. " notify-send -u low -a JDebianizer -i $nsicon "JDebianizer" "Finished with $lmsg.\n$lemsg\n$lwmsg" -t 1000 whiptail --textbox $LOGFILE 20 80 whiptail --msgbox "$FINSTALTEXT" 20 80 whiptail --yesno "Install the_produced Debian file? $ROOTDIR.deb" 20 80 if [ "$?" -eq 0 ]; then echo "Trying to install the Debian file.";sudo dpkg -i $ROOTDIR.deb else whiptail --textbox "Script finished. You can install the produced Debian file manually." 20 80 fi # ---------RE-EXECUTE THE SCRIPT ------------------ eval restartscript exit 0;
If you feel like it’s a good idea, don’t hesitate to join the repository channel JDebianizer Github REPO and contribute to it. The script actually works fine for simple Java Swing applications, but needs many enhancements.
Specifications
For now the script supposes your Java application is already built (E.g: ANT) and that you have in hands a main JAR file (your app) and eventually some libraries it depends on and you want to debianize the whole as one package.
- Script must not be executed root power (sudo).
- The Option (Jayatana Install {Ubuntu Global Menu Integration for Java Swing Apps}) requires internet connection.
- JDebianizer is Console-only, so it must be run from Terminal or any other Shell.
- JDebianizer is not compliant with ZSH.