{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "---\n",
    "title: Mise en œuvre de Java\n",
    "description: Installation et utilisation des outils Java\n",
    "categories: \n",
    "  - Java\n",
    "  - I111\n",
    "  - PO43\n",
    "  - Lecture\n",
    "  - Exercices\n",
    "provide_notes: true\n",
    "provide_slides: false\n",
    "jupyter: java\n",
    "echo: true\n",
    "output: true\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "Ces instructions sont destinées aux systèmes Unix ou similaires (comme Linux et MacOS). Pour les utilisateurs de Windows, il est recommandé d'installer [WSL (Windows Subsystem for Linux)](https://learn.microsoft.com/fr-fr/windows/wsl/install).\n",
    "\n",
    "\n",
    "## Installer\n",
    "\n",
    "Pour installer et utiliser Java pour le développement d'applications, il suffit de télécharger un JDK. Il est recommandé d'utiliser celui du projet [Temurin](https://projects.eclipse.org/projects/adoptium.temurin) en raison de ses avantages en termes de licence. Une fois téléchargé, décompressez-le dans un répertoire de votre choix. Ensuite, définissez la variable d'environnement `JAVA_HOME` pour pointer vers ce répertoire et ajoutez `$JAVA_HOME/bin` à votre variable `PATH` pour pouvoir utiliser Java à partir de n'importe où dans votre système.\n",
    "\n",
    "\n",
    "```bash\n",
    "export JAVA_HOME=/usr/local/jdk....\n",
    "export PATH=\"$JAVA_HOME/bin:$PATH\"\n",
    "```\n",
    "\n",
    "Pensez à ajouter ces commandes au `.bashrc` (ou `.zshrc`).  \n",
    "\n",
    "Pour une installation rapide et simple de Java et de Maven, il est conseillé d'utiliser l'outil [SDKMan](http://sdkman.io/). SDKMan permet de gérer facilement différentes installations et versions de Java et d'autres outils, facilitant ainsi la transition d'une version à une autre.\n",
    "\n",
    "```bash\n",
    "curl -s \"https://get.sdkman.io\" | bash\n",
    "sdk install java             # Latest LTS (21)\n",
    "sdk install java 23-tem      # install a specific Java version\n",
    "sdk install maven            # Install latest Maven\n",
    "```\n",
    "\n",
    "on peut lister les JDK installés :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": "subslide"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               |     | 23           | graal   | installed  | 23-graal            \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " Java.net      |     | 24.ea.16     | open    | installed  | 24.ea.16-open       \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " Temurin       |     | 23           | tem     | installed  | 23-tem              \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               |     | 22.0.2       | tem     | installed  | 22.0.2-tem          \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               | >>> | 21.0.4       | tem     | installed  | 21.0.4-tem          \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               |     | 17.0.12      | tem     | installed  | 17.0.12-tem         \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               |     | 11.0.24      | tem     | installed  | 11.0.24-tem         \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               |     | 8.0.422      | tem     | installed  | 8.0.422-tem         \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               |     | 8.0.422.fx   | zulu    | installed  | 8.0.422.fx-zulu     \n"
     ]
    }
   ],
   "source": [
    "%%shell\n",
    "sdk list java|grep installed"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On peut vérifier que les chemins sont corrects :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": "subslide"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "JAVA_HOME = /home/jovyan/.sdkman/candidates/java/current\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PATH = /home/jovyan/.sdkman/candidates/java/21.0.4-tem/bin:/home/jovyan/bin:/usr/local/bin:/usr/local/sbin:/home/jovyan/.sdkman/candidates/maven/current/bin:/home/jovyan/.sdkman/candidates/java/current/bin:/opt/bin:/opt/conda/bin:/usr/sbin:/usr/bin:/sbin:/bin\n"
     ]
    }
   ],
   "source": [
    "%%shell\n",
    "echo \"JAVA_HOME = $JAVA_HOME\"\n",
    "echo \"PATH = $PATH\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Et que les versions de la machine virtuelle "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "openjdk 21.0.4 2024-07-16 LTS\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "OpenJDK Runtime Environment Temurin-21.0.4+7 (build 21.0.4+7-LTS)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "OpenJDK 64-Bit Server VM Temurin-21.0.4+7 (build 21.0.4+7-LTS, mixed mode, sharing)\n"
     ]
    }
   ],
   "source": [
    "%%shell\n",
    "java --version"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "et du compilateur sont correctes :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "javac 21.0.4\n"
     ]
    }
   ],
   "source": [
    "%%shell\n",
    "javac --version"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "::: {.callout-caution title=\"A Faire\"}\n",
    "Installer un JDK au minimum version 21.\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Compiler et exécuter\n",
    "\n",
    "Pour commencer, créez un répertoire qui contiendra tous vos projets, par exemple `/home/jovyan/work` (vous pouvez adapter ce chemin selon vos préférences). Ce répertoire sera appelé répertoire de travail ou workspace.\n",
    "\n",
    "À l’intérieur de ce répertoire de travail, ajoutez le répertoire du projet, par exemple `java/TP1/premierprogramme/`, que nous appellerons répertoire de projet.\n",
    "\n",
    "Ensuite, dans votre répertoire de projet, ajoutez les répertoires standards suivants : `src`, `bin`, `doc`, `dist` et `lib`.\n",
    "\n",
    "Dans le répertoire `src`, créez l’arborescence correspondant au paquetage : `fr.univtln.login.tp.tp1` (remplacez `login` par VOTRE login). À l’intérieur de ce paquetage, ajoutez la classe Java `HelloWorld.java` ci-dessous.\n",
    "\n",
    "```{.java filename=\"HelloWorld.java\"}\n",
    "package fr.univtln.jovyan.tp.tp1;\n",
    "\n",
    "/**\n",
    " * A very simple class to say Hello\n",
    " * @author Emmanuel Bruno\n",
    " * \n",
    " */\n",
    "public class HelloWorld {\n",
    "\n",
    "    /**\n",
    "     * A dummy constructor\n",
    "     */\n",
    "    public HelloWorld() { }\n",
    "    \n",
    "\t/**\n",
    "     * The entry point of the class\n",
    "\t * @param args The first parameter is a firstname\n",
    "\t */\n",
    "\tpublic static void main(String[] args) {\n",
    "\t\tif (args.length==1) \n",
    "            System.out.println(\"Bonjour \"+args[0]);\n",
    "\t\telse \n",
    "            System.out.println(\"Usage : PremierProgramme [prenom]\");\n",
    "\t}\n",
    "\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "//| output: true\n",
    "//| echo: false\n",
    "String script=\"\"\"\n",
    "rm -rf \"/home/jovyan/work/java/TP1/premierprogramme/\"\n",
    "    \"\"\";\n",
    "    \n",
    "IJava.getKernelInstance().getMagics().applyCellMagic(\"shell\",List.of(),script);  \n",
    "return null;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "créer les répertoires standards (adapter le chemin `/home/jovyan/work/`):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "%%shell \n",
    "mkdir -p /home/jovyan/work/java/TP1/premierprogramme/{src,bin,doc,dist,lib}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "créer l'arborescence des packages:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "%%shell\n",
    "cd /home/jovyan/work/java/TP1/premierprogramme/src/\n",
    "mkdir -p fr/univtln/jovyan/tp/tp1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Créer le fichier de la classe dans le répertoire de son package. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "//| output: true\n",
    "//| echo: false\n",
    "String script=\"\"\"\n",
    "\\\\cp -r resources/HelloWorld.java \\\n",
    "    /home/jovyan/work/java/TP1/premierprogramme/src/fr/univtln/jovyan/tp/tp1\n",
    "\"\"\";\n",
    "    \n",
    "IJava.getKernelInstance().getMagics().applyCellMagic(\"shell\",List.of(),script);  \n",
    "return null;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Le préfixe unique du package doit être adapté pour vous**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "//| output: true\n",
    "//| echo: false\n",
    "String script=\"\"\"\n",
    "sed -i 's/package fr.univtln.bruno.tp.tp1;/package fr.univtln.jovyan.tp.tp1;/g' \\\n",
    "    /home/jovyan/work/java/TP1/premierprogramme/src/fr/univtln/jovyan/tp/tp1/HelloWorld.java\n",
    "    \"\"\";\n",
    "    \n",
    "IJava.getKernelInstance().getMagics().applyCellMagic(\"shell\",List.of(),script);  \n",
    "return null;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "cela donne l'arborescence suivante :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/jovyan/work/java/TP1/premierprogramme/\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "├── bin\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "├── dist\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "├── doc\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "├── lib\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "└── src\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    └── fr\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "        └── univtln\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "            └── jovyan\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                └── tp\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    └── tp1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                        └── HelloWorld.java\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "11 directories, 1 file\n"
     ]
    }
   ],
   "source": [
    "%%shell\n",
    "tree \"/home/jovyan/work/java/TP1/premierprogramme/\" "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "A partir de votre répertoire de projet, compiler le programme avec la commande suivante qui indique la fichier à compiler, l'emplacement des sources au cas ou d'autres classes sont nécessaires et la destination du bytecode :"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "::: {.callout-caution title=\"A Faire\"}\n",
    "Mettre en place manuellement le projet et modifier ce programme pour que l’instruction package soit correcte en adaptant votre login.\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pour compiler, il faut utiliser commande `javac` en indiquant le répertoire des sources (si d'autres classes doivent être compilées), éventuellement le répertoire de destination et obligatoirement le fichier source."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/jovyan/work/java/TP1/premierprogramme/\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "├── bin\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "│   └── fr\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "│       └── univtln\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "│           └── jovyan\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "│               └── tp\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "│                   └── tp1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "│                       └── HelloWorld.class\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "├── dist\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "├── doc\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "├── lib\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "└── src\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    └── fr\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "        └── univtln\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "            └── jovyan\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                └── tp\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    └── tp1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                        └── HelloWorld.java\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "16 directories, 2 files\n"
     ]
    }
   ],
   "source": [
    "%%shell\n",
    "cd \"/home/jovyan/work/java/TP1/premierprogramme/\"\n",
    "javac -sourcepath src -d bin src/fr/univtln/jovyan/tp/tp1/HelloWorld.java\n",
    "    \n",
    "tree \"/home/jovyan/work/java/TP1/premierprogramme/\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pour exécuter le programme, depuis votre répertoire de projet utiliser la commande `java` et ajouter le répertoire `bin` au classpath : "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/jovyan/work/java/TP1/premierprogramme\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Bonjour Pierre\n"
     ]
    }
   ],
   "source": [
    "%%shell\n",
    "cd \"/home/jovyan/work/java/TP1/premierprogramme/\"\n",
    "# Displays current directory\n",
    "pwd\n",
    "# Load the Helloworld class and run the main method. \n",
    "java -classpath bin fr.univtln.jovyan.tp.tp1.HelloWorld Pierre"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "::: {.callout-caution title=\"A Faire\"}\n",
    "Compiler et exécuter la classe `HelloWorld`.\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Documenter\n",
    "\n",
    "La commande `javadoc` génère de la documentation à partir de commentaires spécifiques insérés dans le code source des classes (encadrés par `/** ... */`). Cette fonctionnalité permet de documenter des packages, des classes ou interfaces, des variables d'instance, des méthodes, et plus encore.\n",
    "\n",
    "Les commentaires peuvent contenir du texte simple ainsi que des balises HTML pour la mise en forme (`<I>` pour l'italique, `<B>` pour le gras, etc.). La balise `<code>` est utilisée pour inclure des extraits de code dans les commentaires. Des annotations spéciales, débutant par le caractère `@` (comme `@author`, `@version`, `@param`, etc.), permettent de définir des informations standard.\n",
    "\n",
    "Il est impératif que les commentaires soient placés juste avant l'élément qu'ils documentent. Pour plus de détails, consultez la [documentation officielle sur les commentaires Javadoc](https://docs.oracle.com/en/java/javase/17/docs/specs/javadoc/doc-comment-spec.html).\n",
    " \n",
    "A partir de maintenant, tous vos programmes seront commentés. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Loading source files for package fr.univtln.jovyan.tp.tp1...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Constructing Javadoc information...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Building index for all the packages and classes...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Standard Doclet version 21.0.4+7-LTS\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Building tree for all the packages and classes...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Generating doc/fr/univtln/jovyan/tp/tp1/HelloWorld.html...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Generating doc/fr/univtln/jovyan/tp/tp1/package-summary.html...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Generating doc/fr/univtln/jovyan/tp/tp1/package-tree.html...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Generating doc/overview-tree.html...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Building index for all classes...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Generating doc/allclasses-index.html...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Generating doc/allpackages-index.html...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Generating doc/index-all.html...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Generating doc/search.html...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Generating doc/index.html...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Generating doc/help-doc.html...\n"
     ]
    }
   ],
   "source": [
    "%%shell\n",
    "cd \"/home/jovyan/work/java/TP1/premierprogramme/\"\n",
    "\n",
    "javadoc -d doc -sourcepath src -subpackages fr.univtln.jovyan.tp.tp1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La documentation peut alors être consultée à partir du répertoire `doc` ici [/home/jovyan/work/java/TP1/premierprogramme/doc/index.html](/home/jovyan/work/java/TP1/premierprogramme/doc/index.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "un package Java est commenté en créant un fichier `package-info.java` dans le répertoire correspondant :\n",
    "\n",
    "```{.java filename=\"package-info.java\"}\n",
    "/**\n",
    " * This package is a first dummy exemple.\n",
    " * <p>\n",
    " * It presents a minimal Java Exemple. \n",
    " * </p>\n",
    " *\n",
    " * @since 1.0\n",
    " * @author Emmanuel BRUNO\n",
    " * @version 1.1\n",
    " */\n",
    "package fr.univtln.jovyan.tp.tp1;\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "::: {.callout-caution title=\"A Faire\"}\n",
    "Générer et consulter la documentation depuis votre répertoire de projet.\n",
    "Ajouter un commentaire pour le package `tp1`.\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Empaqueter\n",
    "\n",
    "Pour regrouper un ensemble de classes Java, on utilise la commande `jar`, qui permet de créer un fichier JAR (Java ARchive). Ce fichier contient les packages et les classes nécessaires à l'application."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "added manifest\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding: fr/(in = 0) (out= 0)(stored 0%)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding: fr/univtln/(in = 0) (out= 0)(stored 0%)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding: fr/univtln/jovyan/(in = 0) (out= 0)(stored 0%)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding: fr/univtln/jovyan/tp/(in = 0) (out= 0)(stored 0%)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding: fr/univtln/jovyan/tp/tp1/(in = 0) (out= 0)(stored 0%)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding: fr/univtln/jovyan/tp/tp1/HelloWorld.class(in = 984) (out= 567)(deflated 42%)\n"
     ]
    }
   ],
   "source": [
    "%%shell\n",
    "cd \"/home/jovyan/work/java/TP1/premierprogramme/\"\n",
    "cd bin\n",
    "jar cvf ../dist/TP01EX01.jar fr\n",
    "cd .."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Exécuter le programme en ajoutant le jar au classpath et en indiquant la classe exécutable avec la commande suivante : "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Bonjour Max\n"
     ]
    }
   ],
   "source": [
    "%%shell\n",
    "cd \"/home/jovyan/work/java/TP1/premierprogramme/\"\n",
    "java -cp dist/TP01EX01.jar fr.univtln.jovyan.tp.tp1.HelloWorld Max"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "::: {.callout-caution title=\"A Faire\"}\n",
    "Générer l’archive de votre projet et l'exécuter.\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Le fichier `.jar` contient des metadonnées dans le fichier `META-INF/MANIFEST.MF`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Manifest-Version: 1.0\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Created-By: 21.0.4 (Eclipse Adoptium)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "%%shell\n",
    "cd \"/home/jovyan/work/java/TP1/premierprogramme/\"\n",
    "unzip -q -c dist/TP01EX01.jar META-INF/MANIFEST.MF"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "Pour rendre un JAR exécutable en Java et spécifier la classe principale, vous pouvez suivre ces étapes :\n",
    "\n",
    "1. Créez un fichier `monManifest.txt` à la racine de votre projet.\n",
    "2. Ajoutez la ligne suivante dans ce fichier, en remplaçant `<nom de la classe point d'entrée>` par le nom complet de votre classe contenant le point d'entrée principal (c'est-à-dire la méthode `main` de votre application) :\n",
    "\n",
    "   ```\n",
    "   Main-Class: <nom de la classe point d'entrée>\n",
    "   ```\n",
    "\n",
    "   Par exemple, si votre classe principale s'appelle `MainApp`, le fichier `monManifest.txt` ressemblera à ceci :\n",
    "\n",
    "   ```\n",
    "   Main-Class: MainApp\n",
    "   ```\n",
    "3. Ensuite, pour créer votre JAR exécutable avec ce manifest personnalisé, utilisez la commande `jar` avec l'option `c` pour créer l'archive et l'option `m` pour spécifier le manifest :\n",
    "\n",
    "```bash\n",
    "jar cfm monApplication.jar monManifest.txt -C chemin/vers/les/classes .\n",
    "```\n",
    "\n",
    "- `monApplication.jar` est le nom que vous souhaitez donner à votre JAR exécutable.\n",
    "- `monManifest.txt` est le nom du fichier manifest que vous avez créé.\n",
    "- Assurez-vous de remplacer `chemin/vers/les/classes` par le chemin relatif ou absolu vers le répertoire contenant vos fichiers `.class`.\n",
    "\n",
    "Pour plus de détails et d'exemples sur la création et l'utilisation de fichiers manifest dans les JAR Java, vous pouvez consulter la [documentation Oracle sur les fichiers manifest](https://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "//| output: true\n",
    "//| echo: false\n",
    "String script=\"\"\"\n",
    "# Create a manual manifest\n",
    "cd \"/home/jovyan/work/java/TP1/premierprogramme/\"\n",
    "unzip -q -c dist/TP01EX01.jar META-INF/MANIFEST.MF|sed '/^[[:space:]]*$/d' > monManifest.txt\n",
    "echo \"Main-Class: fr.univtln.jovyan.tp.tp1.HelloWorld\" >> monManifest.txt\n",
    "\"\"\";\n",
    "    \n",
    "IJava.getKernelInstance().getMagics().applyCellMagic(\"shell\",List.of(),script);  \n",
    "return null;   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Le manifest a insérer :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Manifest-Version: 1.0\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Created-By: 21.0.4 (Eclipse Adoptium)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Main-Class: fr.univtln.jovyan.tp.tp1.HelloWorld\n"
     ]
    }
   ],
   "source": [
    "%%shell \n",
    "cd \"/home/jovyan/work/java/TP1/premierprogramme/\"\n",
    "cat monManifest.txt\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Créer le jar:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "added manifest\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding: fr/(in = 0) (out= 0)(stored 0%)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding: fr/univtln/(in = 0) (out= 0)(stored 0%)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding: fr/univtln/jovyan/(in = 0) (out= 0)(stored 0%)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding: fr/univtln/jovyan/tp/(in = 0) (out= 0)(stored 0%)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding: fr/univtln/jovyan/tp/tp1/(in = 0) (out= 0)(stored 0%)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding: fr/univtln/jovyan/tp/tp1/HelloWorld.class(in = 984) (out= 567)(deflated 42%)\n"
     ]
    }
   ],
   "source": [
    "%%shell \n",
    "cd \"/home/jovyan/work/java/TP1/premierprogramme/\"\n",
    "cd bin\n",
    "jar cvfm ../dist/TP01EX01.jar ../monManifest.txt fr\n",
    "cd .."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Puis exécuter directement l’archive : "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Bonjour Pierre\n"
     ]
    }
   ],
   "source": [
    "%%shell\n",
    "cd \"/home/jovyan/work/java/TP1/premierprogramme/\"\n",
    "java -jar dist/TP01EX01.jar Pierre"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "::: {.callout-caution title=\"A Faire\"}\n",
    "Rendre l’archive de votre projet \"exécutable\" et l'exécuter.\n",
    ":::"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "java",
   "language": "java",
   "name": "java",
   "path": "/opt/conda/share/jupyter/kernels/java"
  },
  "language_info": {
   "codemirror_mode": "java",
   "file_extension": ".jshell",
   "mimetype": "text/x-java-source",
   "name": "java",
   "pygments_lexer": "java",
   "version": "21.0.4+7-LTS"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
