Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Prof. Dr. Th. Letschert CS5233 Components – Models and Engineering - Komponententechnologien Master of Science (Informatik) Working with Jars (and other files using NIO) Seite 1 © Th Letschert Jars http://download.oracle.com/javase/tutorial/deployment/jar/index.html Jar Files Jar files : most important de-facto components in the Java biotope Jar file : archive file in zip format Zip file : format for (compressed) archive file with (compressed) content files Jar Tool command line tool <jdk>/bin/jar create / manipulate / extract from jar files Seite 2 Th Letschert Jars / Jar Tool Jar Tool / common operations Create jar c[v0M]f jarfile inputfiles jar c[v0]mf manifest jarfile inputfiles Update jar u[v0M]f jarfile inputfiles jar u[v0]mf manifest jarfile inputfiles Extract files jar x[v]f jarfile [ inputfiles ] Options: c create v verbose output 0 no compression M no manifest file f specify name of jar file m specify name of manifest file u update x extract t display table of contents List contents jar t[v]f jarfile [ inputfiles ] Seite 3 Th Letschert Jars / Meta Information Meta-Information a jar file may contain a directory META-INF containing “meta information” META-INF the directory for meta information contains information relevant for configuration purposes files / directories that are recognized by standard Java tools: – – – – – META-INF/MANIFEST.MF META-INF/INDEX.LIST META-INF/x.SF META-INF/x.DSA META-INF/services/ Seite 4 Th Letschert Jars / Meta Information Manifest-Version : 1.0 Created-By: 1.7.0-ea (Oracle Corporation) Manifest file MANIFEST.MF Example: Default manifest created by <jdk-7>/bin/jar Text file (UTF-8) structured into name – value pairs. Has to start with the main attribute – Manifest-Version version number of the manifest specification Additional main-attributes may follow – – – – – – Created-By Signature-Version Class-Path Main-Class Extension-Name … etc. …. vendor of the java implementation the signature version space separated list of relative urls that extend the class path main class in case the jar file defines a standalone application the name of the extension (the jar file contains an extension) Per entry attributes may follow after an empty line These are attributes that refer to a single entry of the jar file Example: Content-type of a file Seite 5 Th Letschert Jars / Working with Jars Package java.util.jar Provides classes for reading and writing jar files. Class java.util.jar.JarFile read the contents of a jar file Class java.util.jar.JarInputStream read the contents of a jar file from an input stream Class java.util.jar.JarOutputStream write the contents of a jar file to an output stream Package java.net Class java.net.JarURLConnection subclass of URLConnection read data identified by a jar-url Seite 6 Th Letschert Jars / Working with Jars JarFile Example: read and display content of a jar file import import import import java.io.IOException; java.util.Enumeration; java.util.Scanner; java.util.jar.*; public class ReadJar { public static void main(String[] args) throws IOException { Scanner scan = new Scanner(System.in); // get jar file's name String jarName = scan.next(); // display content JarFile jarFile = new JarFile(jarName); Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry jarEntry = entries.nextElement(); System.out.println(jarEntry.getName()); } // display manifest Manifest manifest = jarFile.getManifest(); for (Object mainAttr: manifest.getMainAttributes().keySet()) { System.out.println( mainAttr + " -> " + manifest.getMainAttributes().getValue((Attributes.Name) mainAttr)); } } } Seite 7 Th Letschert Jars / Working with Jars JarFile Example: read and display content of a jar Manifest (1) import import import import import import import import import java.io.IOException; java.io.InputStream; java.nio.file.FileSystems; java.nio.file.Files; java.nio.file.Path; java.util.Map; java.util.jar.Attributes; java.util.jar.JarInputStream; java.util.jar.Manifest; file handling relies on nio-2 features of Java 7 public class Test { public static void main(String[] args) throws IOException { Path path = FileSystems.getDefault().getPath("/tmp/ajar.jar"); InputStream fis = Files.newInputStream(path); JarInputStream jis = new JarInputStream(fis); Manifest manifest = jis.getManifest(); ... next Slide ... } } Seite 8 Th Letschert Jars / Working with Jars JarFile Example: read and display content of a jar Manifest (2) System.out.println("Main Entries:"); for (Object mainAttr: manifest.getMainAttributes().keySet()) { System.out.println( mainAttr + " -> " + manifest.getMainAttributes().getValue((Attributes.Name) mainAttr)); } System.out.println(); System.out.println("Entries:"); Map<String,Attributes> manifestEntries = manifest.getEntries(); for(String key : manifestEntries.keySet() ) { System.out.println("entry key: " + key); System.out.println("entry values: "); Attributes attrs = manifestEntries.get(key); for (Object o : attrs.keySet()) { System.out.println(" " + o + " => " + attrs.getValue((Attributes.Name)o)); } } Main Entries: Manifest-Version -> 1.0 schlabber -> Schlapp Blubber-bla -> wusch Manifest-Version: 1.0 Blubber-bla: wusch schlabber: Schlapp Entries: entry key: /p_269/CoreBuilder.class entry values: Sealed => false Bu-Bu => true Name: /p_269/CoreBuilder.class Bu-Bu: true Sealed: false Manifest file Seite 9 Output Th Letschert Jars / Working with Jars JarFile Example: unzip jar file (1) import import import import import import import import import import import import import java.io.File; java.io.IOException; java.nio.file.DirectoryStream; java.nio.file.FileSystems; java.nio.file.Files; java.nio.file.Path; java.nio.file.PathMatcher; java.nio.file.attribute.PosixFilePermission; java.nio.file.attribute.PosixFilePermissions; java.util.Enumeration; java.util.Set; java.util.jar.JarEntry; java.util.jar.JarFile; public class ExtractJar { public static void main(String[] args) throws IOException { Path jarPath = FileSystems.getDefault().getPath("/tmp/Scratch/ajar.jar"); // check jar if (! Files.exists(jarPath) || ! Files.isReadable(jarPath) || Files.isDirectory(jarPath) ) { throw new IOException("not a readable file"); } PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + "*.jar"); Path filePath = jarPath.getFileName(); if (filePath == null || ! matcher.matches(filePath)) { throw new IOException(" file does not exist or is not a jar file"); } if ( ! Files.probeContentType(jarPath).equals("application/x-java-archive") ) { throw new IOException("no jar content " + Files.probeContentType(jarPath)); } } ... next Slide ... } Seite 10 Th Letschert Jars / Working with Jars JarFile Example: unzip jar file (2) // determine directory to inflate into Path dirPath = jarPath.getParent(); String fileNameWithoutExt = ((filePath.toString()).split("\\."))[0]; Path inflatePath = dirPath.resolve(fileNameWithoutExt); System.out.println("inflate in directory " + inflatePath); // create inflate dir, previously delete it recursively if it already exists deleteRecursive(inflatePath); Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---"); Files.createDirectory(inflatePath, PosixFilePermissions.asFileAttribute(perms)); //inflate jar content to dir JarFile jarFile = new JarFile(new File(jarPath.toString())); Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry jarEntry = entries.nextElement(); Path destPath = inflatePath.resolve( FileSystems.getDefault().getPath(jarEntry.getName())); if (jarEntry.getName().endsWith("/")) { // directory Files.createDirectories(destPath); continue; } Files.createDirectories(destPath.getParent()); Files.copy(jarFile.getInputStream(jarEntry), destPath); } Seite 11 Th Letschert Jars / Working with Jars JarFile Example: unzip jar file (3) /** * Delete a file or recursively a directory * @param path the file or directory * @throws IOException if something went wrong */ private static void deleteRecursive(Path path) throws IOException { if (Files.isDirectory(path)) { DirectoryStream<Path> stream = Files.newDirectoryStream(path); for (Path entry: stream) { deleteRecursive(entry); } Files.deleteIfExists(path); } } helper function for deletion Seite 12 Th Letschert Jars / Jar URL Jar URL identifies resources within a jar file defined by Java API specification Syntax : jar:<url>!/[<entry>] where <url> is a non-jar url (e.g. a file url: file://[host]/path a http url, or ftp url) Examples (from Java API doc.): A Jar entry jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class A Jar file jar:http://www.foo.com/bar/baz.jar!/ A Jar directory jar:http://www.foo.com/bar/baz.jar!/COM/foo/ Seite 13 Th Letschert Jars / Working with Jars Example: load and execute runnable jar file (1) import import import import import import import import import java.io.IOException; java.lang.reflect.InvocationTargetException; java.lang.reflect.Method; java.lang.reflect.Modifier; java.net.JarURLConnection; java.net.URL; java.net.URLClassLoader; java.util.Scanner; java.util.jar.Attributes; public class JarExecuter { public static void main(String[] args) throws IOException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { Scanner scan = new Scanner(System.in); // get jar file's name // something like // /some/directory/HelloWorld.jar String jarName = scan.next(); ... next slide ... } } Seite 14 Th Letschert Jars / Working with Jars Example: load and execute runnable jar file (2) //The syntax of a JAR URL is:jar:<url>!/{entry} // The terminating !/ separator indicates that the URL refers to an entire JAR file URL url = new URL("jar:file:" + jarName + "!/"); URLClassLoader urlLoader = new URLClassLoader(new URL[] { url }); JarURLConnection uc = (JarURLConnection)url.openConnection(); Attributes attr = uc.getMainAttributes(); if (attr != null) { String mainClassName = attr.getValue(Attributes.Name.MAIN_CLASS); if (mainClassName != null) { Class<?> c = urlLoader.loadClass(mainClassName); Method m = c.getMethod("main", new Class[] { args.getClass() }); m.setAccessible(true); int mods = m.getModifiers(); if (m.getReturnType() != void.class || !Modifier.isStatic(mods) || !Modifier.isPublic(mods)) { throw new NoSuchMethodException("main"); } try { m.invoke(null, new Object[] { args }); } catch (IllegalAccessException e) { // never reached } } } Seite 15 Th Letschert