下面列出了java.util.jar.JarOutputStream#write ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private File makeClassLoaderTestJar(String... clsNames) throws IOException {
File jarFile = new File(TEST_ROOT_DIR, TEST_JAR_2_NAME);
JarOutputStream jstream =
new JarOutputStream(new FileOutputStream(jarFile));
for (String clsName: clsNames) {
String name = clsName.replace('.', '/') + ".class";
InputStream entryInputStream = this.getClass().getResourceAsStream(
"/" + name);
ZipEntry entry = new ZipEntry(name);
jstream.putNextEntry(entry);
BufferedInputStream bufInputStream = new BufferedInputStream(
entryInputStream, 2048);
int count;
byte[] data = new byte[2048];
while ((count = bufInputStream.read(data, 0, 2048)) != -1) {
jstream.write(data, 0, count);
}
jstream.closeEntry();
}
jstream.close();
return jarFile;
}
static void copyJarFile(JarInputStream in, JarOutputStream out) throws IOException {
if (in.getManifest() != null) {
ZipEntry me = new ZipEntry(JarFile.MANIFEST_NAME);
out.putNextEntry(me);
in.getManifest().write(out);
out.closeEntry();
}
byte[] buffer = new byte[1 << 14];
for (JarEntry je; (je = in.getNextJarEntry()) != null; ) {
out.putNextEntry(je);
for (int nr; 0 < (nr = in.read(buffer)); ) {
out.write(buffer, 0, nr);
}
}
in.close();
markJarFile(out); // add PACK200 comment
}
private static void createTempJarInner(JarOutputStream out, File f,
String base) throws IOException {
if (f.isDirectory()) {
File[] fl = f.listFiles();
if (base.length() > 0) {
base = base + "/";
}
for (int i = 0; i < fl.length; i++) {
createTempJarInner(out, fl[i], base + fl[i].getName());
}
} else {
out.putNextEntry(new JarEntry(base));
FileInputStream in = new FileInputStream(f);
byte[] buffer = new byte[1024];
int n = in.read(buffer);
while (n != -1) {
out.write(buffer, 0, n);
n = in.read(buffer);
}
in.close();
}
}
/**
* Saves a jar without the manifest
*
* @param nodeList The loaded ClassNodes
* @param path the exact jar output path
*/
public static void saveAsJarClassesOnly(ArrayList<ClassNode> nodeList, String path) {
try {
JarOutputStream out = new JarOutputStream(new FileOutputStream(path));
ArrayList<String> noDupe = new ArrayList<String>();
for (ClassNode cn : nodeList) {
ClassWriter cw = new ClassWriter(0);
cn.accept(cw);
String name = cn.name + ".class";
if (!noDupe.contains(name)) {
noDupe.add(name);
out.putNextEntry(new ZipEntry(name));
out.write(cw.toByteArray());
out.closeEntry();
}
}
noDupe.clear();
out.close();
} catch (IOException e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
private static void writeJarEntry(JarOutputStream jos, String path, File f) throws IOException, FileNotFoundException {
JarEntry je = new JarEntry(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = new FileInputStream(f);
try {
copyStreams(is, baos);
} finally {
is.close();
}
byte[] data = baos.toByteArray();
je.setSize(data.length);
CRC32 crc = new CRC32();
crc.update(data);
je.setCrc(crc.getValue());
jos.putNextEntry(je);
jos.write(data);
}
static void copyJarFile(JarInputStream in, JarOutputStream out) throws IOException {
if (in.getManifest() != null) {
ZipEntry me = new ZipEntry(JarFile.MANIFEST_NAME);
out.putNextEntry(me);
in.getManifest().write(out);
out.closeEntry();
}
byte[] buffer = new byte[1 << 14];
for (JarEntry je; (je = in.getNextJarEntry()) != null; ) {
out.putNextEntry(je);
for (int nr; 0 < (nr = in.read(buffer)); ) {
out.write(buffer, 0, nr);
}
}
in.close();
markJarFile(out); // add PACK200 comment
}
/**
* Writes an entry with specific contents to the jar. Directory entries must include the trailing
* '/'.
*/
protected void writeEntry(JarOutputStream out, String name, byte[] content) throws IOException {
if (names.add(name)) {
// Create a new entry
JarEntry entry = new JarEntry(name);
entry.setTime(newEntryTimeMillis(name));
int size = content.length;
entry.setSize(size);
if (size == 0) {
entry.setMethod(JarEntry.STORED);
entry.setCrc(0);
out.putNextEntry(entry);
} else {
entry.setMethod(storageMethod);
if (storageMethod == JarEntry.STORED) {
CRC32 crc = new CRC32();
crc.update(content);
entry.setCrc(crc.getValue());
}
out.putNextEntry(entry);
out.write(content);
}
out.closeEntry();
}
}
/**
* creates a JarInputStream containing the passed text files. Each Pair<String
*/
public static InputStream jarInputStream(TextFile... files) {
try {
ByteArrayOutputStream out2 = new ByteArrayOutputStream();
JarOutputStream jo = new JarOutputStream(new BufferedOutputStream(out2));
for (TextFile textFile : files) {
JarEntry je = new JarEntry(textFile.path);
jo.putNextEntry(je);
byte[] bytes = textFile.content.getBytes();
jo.write(bytes, 0, bytes.length);
}
jo.close();
return new ByteArrayInputStream(out2.toByteArray());
} catch (IOException e) {
throw new WrappedException(e);
}
}
@Test
@JavaVersionRule.Enforce(7) // Avoid leak since class loader cannot be closed
public void testSuccessfulLocation() throws Exception {
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(file));
try {
JarEntry jarEntry = new JarEntry(FOO + "/" + BAR + ".class");
jarOutputStream.putNextEntry(jarEntry);
jarOutputStream.write(VALUE);
jarOutputStream.write(VALUE * 2);
jarOutputStream.closeEntry();
} finally {
jarOutputStream.close();
}
URL url = file.toURI().toURL();
ClassFileLocator classFileLocator = new ClassFileLocator.ForUrl(Collections.singleton(url));
try {
ClassFileLocator.Resolution resolution = classFileLocator.locate(FOO + "." + BAR);
assertThat(resolution.isResolved(), is(true));
assertThat(resolution.resolve(), is(new byte[]{VALUE, VALUE * 2}));
} finally {
classFileLocator.close();
}
}
private static void putJarEntry(final JarOutputStream jar, final File f, final String path) throws IOException {
jar.putNextEntry(new ZipEntry(path));
final InputStream in = new BufferedInputStream(new FileInputStream(f));
try {
final byte[] b = new byte[4096];
int len;
while ((len = in.read(b)) > 0)
jar.write(b, 0, len);
} finally {
in.close();
}
jar.closeEntry();
}
public void doExportDevice(String device) throws Exception {
File ftd = new File(OS.getFolderMyDevices()+File.separator+device+".ftd");
byte buffer[] = new byte[10240];
FileOutputStream stream = new FileOutputStream(ftd);
JarOutputStream out = new JarOutputStream(stream);
out.setLevel(Deflater.BEST_SPEED);
File root = new File(OS.getFolderDevices()+File.separator+device);
int rootindex = root.getAbsolutePath().length();
Collection<File> c = OS.listFileTree(root);
Iterator<File> i = c.iterator();
while (i.hasNext()) {
File entry = i.next();
String name = entry.getAbsolutePath().substring(rootindex-device.length());
if (entry.isDirectory()) name = name+"/";
JarEntry jarAdd = new JarEntry(name);
out.putNextEntry(jarAdd);
if (!entry.isDirectory()) {
InputStream in = new FileInputStream(entry);
while (true) {
int nRead = in.read(buffer, 0, buffer.length);
if (nRead <= 0)
break;
out.write(buffer, 0, nRead);
}
in.close();
}
}
out.close();
stream.close();
}
/**
* Creates simple JAR file to test archetype loader.
*
* @throws IOException If an IO error occurs.
*/
@BeforeAll
public static void createSimpleJar() throws IOException {
Manifest manifest = new Manifest();
File file = targetDir().toPath().resolve("test.jar").toFile();
JarOutputStream os = new JarOutputStream(new FileOutputStream(file), manifest);
JarEntry entry = new JarEntry("META-INF/helidon-archetype.xml");
os.putNextEntry(entry);
os.write("<archetype-descriptor></archetype-descriptor>".getBytes(StandardCharsets.US_ASCII));
os.close();
}
private static void writeJarredFile(JarOutputStream jos, String file, String suffix, byte[] bytes) {
String fileName = file.replace(".", "/") + "." + suffix;
JarEntry ze = new JarEntry(fileName);
try {
ze.setSize(bytes.length);
jos.putNextEntry(ze);
jos.write(bytes);
jos.closeEntry();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
static void copyJarFile(JarFile in, JarOutputStream out) throws IOException {
byte[] buffer = new byte[1 << 14];
for (JarEntry je : Collections.list(in.entries())) {
out.putNextEntry(je);
InputStream ein = in.getInputStream(je);
for (int nr; 0 < (nr = ein.read(buffer)); ) {
out.write(buffer, 0, nr);
}
}
in.close();
markJarFile(out); // add PACK200 comment
}
/**
* Create a JAR using the given file contents and with the given file name.
*
* @param fileName
* Name of the file to create
* @param content
* Content of the created file
* @return The JAR file content
* @throws IOException
* If there is a problem creating the output stream for the JAR file.
*/
public byte[] createJarFromFileContent(final String fileName, final String content) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
JarOutputStream jarOutputStream = new JarOutputStream(byteArrayOutputStream);
JarEntry entry = new JarEntry(fileName);
entry.setTime(System.currentTimeMillis());
jarOutputStream.putNextEntry(entry);
jarOutputStream.write(content.getBytes());
jarOutputStream.closeEntry();
jarOutputStream.close();
return byteArrayOutputStream.toByteArray();
}
/**
* Convert a ScriptModule to its compiled equivalent ScriptArchive.
* <p>
* A jar script archive is created containing compiled bytecode
* from a script module, as well as resources and other metadata from
* the source script archive.
* <p>
* This involves serializing the class bytes of all the loaded classes in
* the script module, as well as copying over all entries in the original
* script archive, minus any that have excluded extensions. The module spec
* of the source script archive is transferred as is to the target bytecode
* archive.
*
* @param module the input script module containing loaded classes
* @param jarPath the path to a destination JarScriptArchive.
* @param excludeExtensions a set of extensions with which
* source script archive entries can be excluded.
*
* @throws Exception
*/
public static void toCompiledScriptArchive(ScriptModule module, Path jarPath,
Set<String> excludeExtensions) throws Exception {
ScriptArchive sourceArchive = module.getSourceArchive();
JarOutputStream jarStream = new JarOutputStream(new FileOutputStream(jarPath.toFile()));
try {
// First copy all resources (excluding those with excluded extensions)
// from the source script archive, into the target script archive
for (String archiveEntry : sourceArchive.getArchiveEntryNames()) {
URL entryUrl = sourceArchive.getEntry(archiveEntry);
boolean skip = false;
for (String extension: excludeExtensions) {
if (entryUrl.toString().endsWith(extension)) {
skip = true;
break;
}
}
if (skip)
continue;
InputStream entryStream = entryUrl.openStream();
byte[] entryBytes = IOUtils.toByteArray(entryStream);
entryStream.close();
jarStream.putNextEntry(new ZipEntry(archiveEntry));
jarStream.write(entryBytes);
jarStream.closeEntry();
}
// Now copy all compiled / loaded classes from the script module.
Set<Class<?>> loadedClasses = module.getModuleClassLoader().getLoadedClasses();
Iterator<Class<?>> iterator = loadedClasses.iterator();
while (iterator.hasNext()) {
Class<?> clazz = iterator.next();
String classPath = clazz.getName().replace(".", "/") + ".class";
URL resourceURL = module.getModuleClassLoader().getResource(classPath);
if (resourceURL == null) {
throw new Exception("Unable to find class resource for: " + clazz.getName());
}
InputStream resourceStream = resourceURL.openStream();
jarStream.putNextEntry(new ZipEntry(classPath));
byte[] classBytes = IOUtils.toByteArray(resourceStream);
resourceStream.close();
jarStream.write(classBytes);
jarStream.closeEntry();
}
// Copy the source moduleSpec, but tweak it to specify the bytecode compiler in the
// compiler plugin IDs list.
ScriptModuleSpec moduleSpec = sourceArchive.getModuleSpec();
ScriptModuleSpec.Builder newModuleSpecBuilder = new ScriptModuleSpec.Builder(moduleSpec.getModuleId());
newModuleSpecBuilder.addCompilerPluginIds(moduleSpec.getCompilerPluginIds());
newModuleSpecBuilder.addCompilerPluginId(BytecodeLoadingPlugin.PLUGIN_ID);
newModuleSpecBuilder.addMetadata(moduleSpec.getMetadata());
newModuleSpecBuilder.addModuleDependencies(moduleSpec.getModuleDependencies());
// Serialize the modulespec with GSON and its default spec file name
ScriptModuleSpecSerializer specSerializer = new GsonScriptModuleSpecSerializer();
String json = specSerializer.serialize(newModuleSpecBuilder.build());
jarStream.putNextEntry(new ZipEntry(specSerializer.getModuleSpecFileName()));
jarStream.write(json.getBytes(Charsets.UTF_8));
jarStream.closeEntry();
} finally {
if (jarStream != null) {
jarStream.close();
}
}
}
private void writeEntry(JarOutputStream j, String name,
long mtime, long lsize, boolean deflateHint,
ByteBuffer data0, ByteBuffer data1) throws IOException {
int size = (int)lsize;
if (size != lsize)
throw new IOException("file too large: "+lsize);
CRC32 crc32 = _crc32;
if (_verbose > 1)
Utils.log.fine("Writing entry: "+name+" size="+size
+(deflateHint?" deflated":""));
if (_buf.length < size) {
int newSize = size;
while (newSize < _buf.length) {
newSize <<= 1;
if (newSize <= 0) {
newSize = size;
break;
}
}
_buf = new byte[newSize];
}
assert(_buf.length >= size);
int fillp = 0;
if (data0 != null) {
int size0 = data0.capacity();
data0.get(_buf, fillp, size0);
fillp += size0;
}
if (data1 != null) {
int size1 = data1.capacity();
data1.get(_buf, fillp, size1);
fillp += size1;
}
while (fillp < size) {
// Fill in rest of data from the stream itself.
int nr = in.read(_buf, fillp, size - fillp);
if (nr <= 0) throw new IOException("EOF at end of archive");
fillp += nr;
}
ZipEntry z = new ZipEntry(name);
z.setTime(mtime * 1000);
if (size == 0) {
z.setMethod(ZipOutputStream.STORED);
z.setSize(0);
z.setCrc(0);
z.setCompressedSize(0);
} else if (!deflateHint) {
z.setMethod(ZipOutputStream.STORED);
z.setSize(size);
z.setCompressedSize(size);
crc32.reset();
crc32.update(_buf, 0, size);
z.setCrc(crc32.getValue());
} else {
z.setMethod(Deflater.DEFLATED);
z.setSize(size);
}
j.putNextEntry(z);
if (size > 0)
j.write(_buf, 0, size);
j.closeEntry();
if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z));
}
public static void main(String[] args) throws Exception {
String srcDir = System.getProperty("test.src", ".");
String keystore = srcDir + "/JarSigning.keystore";
String jarName = "largeJarEntry.jar";
// Set java.io.tmpdir to the current working dir (see 6474350)
System.setProperty("java.io.tmpdir", System.getProperty("user.dir"));
// first, create jar file with 8M uncompressed entry
// note, we set the max heap size to 8M in @run tag above
byte[] bytes = new byte[1000000];
CRC32 crc = new CRC32();
for (int i=0; i<8; i++) {
crc.update(bytes);
}
JarEntry je = new JarEntry("large");
je.setSize(8000000l);
je.setMethod(JarEntry.STORED);
je.setCrc(crc.getValue());
File file = new File(jarName);
FileOutputStream os = new FileOutputStream(file);
JarOutputStream jos = new JarOutputStream(os);
jos.setMethod(JarEntry.STORED);
jos.putNextEntry(je);
for (int i=0; i<8; i++) {
jos.write(bytes, 0, bytes.length);
}
jos.close();
String[] jsArgs = { "-keystore", keystore, "-storepass", "bbbbbb",
jarName, "b" };
// now, try to sign it
try {
sun.security.tools.jarsigner.Main.main(jsArgs);
} catch (OutOfMemoryError err) {
throw new Exception("Test failed with OutOfMemoryError", err);
} finally {
// remove jar file
file.delete();
}
}
public static void main(String[] args) throws Exception {
String srcDir = System.getProperty("test.src", ".");
String keystore = srcDir + "/JarSigning.keystore";
String jarName = "largeJarEntry.jar";
// Set java.io.tmpdir to the current working dir (see 6474350)
System.setProperty("java.io.tmpdir", System.getProperty("user.dir"));
// first, create jar file with 8M uncompressed entry
// note, we set the max heap size to 8M in @run tag above
byte[] bytes = new byte[1000000];
CRC32 crc = new CRC32();
for (int i=0; i<8; i++) {
crc.update(bytes);
}
JarEntry je = new JarEntry("large");
je.setSize(8000000l);
je.setMethod(JarEntry.STORED);
je.setCrc(crc.getValue());
File file = new File(jarName);
FileOutputStream os = new FileOutputStream(file);
JarOutputStream jos = new JarOutputStream(os);
jos.setMethod(JarEntry.STORED);
jos.putNextEntry(je);
for (int i=0; i<8; i++) {
jos.write(bytes, 0, bytes.length);
}
jos.close();
String[] jsArgs = { "-keystore", keystore, "-storepass", "bbbbbb",
jarName, "b" };
// now, try to sign it
try {
sun.security.tools.jarsigner.Main.main(jsArgs);
} catch (OutOfMemoryError err) {
throw new Exception("Test failed with OutOfMemoryError", err);
} finally {
// remove jar file
file.delete();
}
}
private void writeEntry(JarOutputStream j, String name,
long mtime, long lsize, boolean deflateHint,
ByteBuffer data0, ByteBuffer data1) throws IOException {
int size = (int)lsize;
if (size != lsize)
throw new IOException("file too large: "+lsize);
CRC32 crc32 = _crc32;
if (_verbose > 1)
Utils.log.fine("Writing entry: "+name+" size="+size
+(deflateHint?" deflated":""));
if (_buf.length < size) {
int newSize = size;
while (newSize < _buf.length) {
newSize <<= 1;
if (newSize <= 0) {
newSize = size;
break;
}
}
_buf = new byte[newSize];
}
assert(_buf.length >= size);
int fillp = 0;
if (data0 != null) {
int size0 = data0.capacity();
data0.get(_buf, fillp, size0);
fillp += size0;
}
if (data1 != null) {
int size1 = data1.capacity();
data1.get(_buf, fillp, size1);
fillp += size1;
}
while (fillp < size) {
// Fill in rest of data from the stream itself.
int nr = in.read(_buf, fillp, size - fillp);
if (nr <= 0) throw new IOException("EOF at end of archive");
fillp += nr;
}
ZipEntry z = new ZipEntry(name);
z.setTime(mtime * 1000);
if (size == 0) {
z.setMethod(ZipOutputStream.STORED);
z.setSize(0);
z.setCrc(0);
z.setCompressedSize(0);
} else if (!deflateHint) {
z.setMethod(ZipOutputStream.STORED);
z.setSize(size);
z.setCompressedSize(size);
crc32.reset();
crc32.update(_buf, 0, size);
z.setCrc(crc32.getValue());
} else {
z.setMethod(Deflater.DEFLATED);
z.setSize(size);
}
j.putNextEntry(z);
if (size > 0)
j.write(_buf, 0, size);
j.closeEntry();
if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z));
}