diff --git a/org.sf.feeling.decompiler/src/org/sf/feeling/decompiler/util/JarClassExtractor.java b/org.sf.feeling.decompiler/src/org/sf/feeling/decompiler/util/JarClassExtractor.java
index 9407d65a..e1303471 100644
--- a/org.sf.feeling.decompiler/src/org/sf/feeling/decompiler/util/JarClassExtractor.java
+++ b/org.sf.feeling.decompiler/src/org/sf/feeling/decompiler/util/JarClassExtractor.java
@@ -9,6 +9,7 @@
package org.sf.feeling.decompiler.util;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -19,15 +20,76 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
+
public class JarClassExtractor
{
/**
- * extracts class files from jar/zip archive to specified path. See
- * IDecompiler
documentation for the format of pareameters.
+ * extracts class files from jar/zip archive or modules to specified path.
+ * See IDecompiler
documentation for the format of pareameters.
*/
public static void extract( String archivePath, String packege, String className, boolean inner, String to )
throws IOException
+ {
+ if ( isClassInJrt( archivePath ) )
+ {
+ extractClassFromJrt( archivePath, packege, className, to );
+ }
+ else
+ {
+ extractClassesFromJar( archivePath, packege, className, inner, to );
+ }
+ }
+
+ private static boolean isClassInJrt( String archivePath )
+ {
+ try
+ {
+ return archivePath.endsWith( JRTUtil.JRT_FS_JAR );
+ }
+ catch ( NoClassDefFoundError e )
+ {
+ // Compatible with pre-Oxygen Eclipse, where JRTUtil does not exist
+ return false;
+ }
+ }
+
+ private static void extractClassFromJrt( String archivePath, String packege, String className, String to )
+ throws IOException, FileNotFoundException
+ {
+ File outputFile = new File( to + File.separatorChar + className );
+ try (FileOutputStream outputStream = new FileOutputStream( outputFile ))
+ {
+ File jrtPath = new File( archivePath );
+ List modules = JRTUtil.getModulesDeclaringPackage( jrtPath, packege, null );
+ String moduleRelativePath = packege + "/" + className;
+ byte[] content = findModuleWithFile( jrtPath, modules, moduleRelativePath );
+ outputStream.write( content );
+ }
+ catch ( ClassFormatException e )
+ {
+ throw new RuntimeException( "Unable to read JRT file", e );
+ }
+ }
+
+ private static byte[] findModuleWithFile( File jrtPath, List modules, String moduleRelativeClassPath )
+ throws IOException, ClassFormatException
+ {
+ for ( String module : modules )
+ {
+ byte[] content = JRTUtil.getClassfileContent( jrtPath, moduleRelativeClassPath, module );
+ if ( content != null )
+ {
+ return content;
+ }
+ }
+ throw new RuntimeException( "No module in JRT contains class " + moduleRelativeClassPath );
+ }
+
+ private static void extractClassesFromJar( String archivePath, String packege, String className, boolean inner,
+ String to ) throws IOException, FileNotFoundException
{
ZipFile archive = new ZipFile( archivePath );
List entries = findRelevant( archive, packege, className, inner );
@@ -65,7 +127,6 @@ public static void extract( String archivePath, String packege, String className
out.close( );
}
}
-
}
private static List findRelevant( ZipFile archive, String packege, String className, boolean inner )
diff --git a/pom.xml b/pom.xml
index 175fd690..0075c988 100644
--- a/pom.xml
+++ b/pom.xml
@@ -103,9 +103,9 @@
- eclipse-juno
+ eclipse-oxygen
p2
- http://download.eclipse.org/releases/juno
+ http://download.eclipse.org/releases/oxygen