2010-03-30 11 views
15

Google usa bsdiff y Courgette para parchar archivos binarios como la distribución de Chrome. ¿Existen herramientas similares para parchar archivos jar?¿Hay algo como bsdiff/Courgette para archivos jar?

Estoy actualizando archivos jar de forma remota a través de una conexión de ancho de banda limitado y me gustaría minimizar la cantidad de datos enviados. Tengo cierto control sobre la máquina del cliente hasta cierto punto (es decir, puedo ejecutar scripts localmente) y tengo la garantía de que la aplicación de destino no se ejecutará en ese momento.

Sé que puedo parchear aplicaciones Java al poner archivos de clase actualizados en el classpath, pero preferiría un método más limpio para hacer actualizaciones. Sería bueno si pudiera comenzar con el archivo jar de destino, aplicar un parche binario y luego terminar con un archivo jar actualizado que sea idéntico (bitwise) al nuevo jar (desde el cual se creó el parche).

+0

¿Qué ventaja está buscando más de simplemente tratar el frasco como un archivo binario y remendándolo? –

+2

Mayor compresión. Bsdiff y Courgette logran mayores índices de compresión porque los algoritmos que utilizan están diseñados específicamente para comprimir grandes ejecutables. No sé, pero me parece que se podría hacer lo mismo con los archivos jar. –

+1

Pregunta relacionada: http://stackoverflow.com/questions/3738523/patching-java-software –

Respuesta

2

Pruebe el proyecto javaxdelta en Sourceforge. Debe permitir crear parches y aplicarlos.

[EDITAR] Esta herramienta todavía no existe. Abra el archivo JAR con las herramientas habituales y luego use javaxdelta para crear un parche por entrada en el JAR. Cópialos y cópielos en el servidor.

Por otro lado, debe instalar un pequeño JAR ejecutable que toma el parche y el archivo JAR como argumentos y aplica el parche. Tendrás que escribir este también, pero eso no debería tomar mucho más que unas pocas horas.

+0

Hola Aaron: No estoy buscando un algoritmo de parche binario implementado en Java, estoy buscando una herramienta de parche que esté diseñada específicamente para trabajar con archivos JAR, en la línea de pack200. –

+0

Esta herramienta aún no existe. Abra el archivo JAR con las herramientas habituales y luego use javaxdelta para crear un parche por entrada en el JAR. Cópialos y cópielos en el servidor. Por otro lado, debe instalar un pequeño JAR ejecutable que tome el parche y el archivo JAR como argumentos y aplique el parche. Tendrás que escribir este también, pero eso no debería tomar mucho más que unas pocas horas. –

+0

@Ken - Lo que Aaron sugiere no es un algoritmo real, pero es lo que querrás hacer. Los archivos jar son archivos zip con archivos de clase en ellos. Es probable que una diferencia binaria de old/foo.class y new/foo.class revele algunas diferencias, mientras que una diferencia binaria de old/foo.jar y new/foo.jar es probable que parezcan mucho más diferentes. Simplemente puede comprimir (comprimir) la diferencia binaria de los archivos de clase y enviarla a sus puntos finales. Luego, en cada punto final, descomprimirán sus archivos jar que necesitan ser parcheados, aplicarán el parche y luego los volverán a hacer una copia de seguridad. – nategoose

1

. Los archivos .jar ya están comprimidos, entonces lo que realmente está pidiendo es una compresión que funcione bien en archivos zip;). Si lo haces al antes de lo guardas en el contenedor, tienes mejores probabilidades de aprovechar el conocimiento de que es "java", supongo. Sospecho que podría adaptar la factorización descrita en este paper como un método de compresión específico de Java.

+0

pack200 ya se ocupa del problema de compresión; lo que estoy buscando es algo que trate con parches. http: //java.sun.com/j2se/1.5.0/docs/guide/deployment/deployment-guide/pack200.html –

1

El problema es que los cambios muy pequeños en la fuente pueden tener cambios muy grandes en el archivo comprimido .JAR.

Esto es un artefacto de eliminar la redundancia. Así que no importa qué tan buena sea su herramienta de diferenciación, tiene una tarea casi imposible en sus manos.

Sin embargo, hay una solución, que es generar los diffs y aplicar los parches a sin comprimir datos. Por ejemplo:

Digamos que tiene

proyecto v1.jar

proyecto v2.jar

Generando el diff entre estos dos archivos es probable que sea enorme, aunque el cambio interno podría ser muy pequeño Así que decir que tenemos un programa de 'unjar' y 'rejar' - podemos generar

proyecto v1.jar -> v1.jar.unjar proyecto

proyecto v2.jar -> Proyecto-v2. jar.unjar

Luego, haciendo los diffs entre los archivos 'unjar' para generar un parche. Para aplicar el parche sería

project-v1.jar (unjar) -> project-v1.jar.unjar - (apply patch) -> project-v1.patched.unjar (rejar) -> project-v1. parcheadojar

Efectivamente, los programas 'unjar' (y 'rejar' es el inverso) deberían tomar un archivo ZIP fuente (o cualquier otro tipo de archivo) y descomprimir el contenido, incluidos los encabezados, atributos y cualquier otro detalle a una secuencia de salida (en lugar de crear archivos individuales).

Esto no debería ser un filtro muy complicado de escribir. La bonificación adicional consistiría en hacerlo consciente de la compresión y recursivo (para poder aplicarlo, por ejemplo, a un archivo WAR).

+0

El problema es que el código fuente (archivos .JAVA no abiertos) es más grande que el código compilado en el archivo .JAR. Entonces, la diferencia entre el archivo .JAVA puede tener un tamaño mayor que la diferencia entre 2 archivos .JAR o .DEX. –

+0

.unjar no implica código fuente, implica un (archivo descomprimido) de archivos .class - I.E: jar con la opción 0 (sin comprimir). ¡También comprimirías tu diff! – user340535

0

cheque delta-updater

el que está instalado para ver diferencias binario y directorios de parches, puede utilizar IOFilter para filtrar los archivos incluidos

Cuestiones relacionadas