¿Cuáles son las razones para sellar un .jar y cómo lo verificaría?

9

He creado un frasco sellado, pero no veo diferencia en comparación con el uso de uno no sellado.

  • ¿Qué pruebas puedo realizar para verificar que el frasco esté sellado?
  • ¿Qué razón podríamos tener para preferir usar un sellado en lugar de uno?
  • ¿Un sellado creará algún problema para los usuarios de mis proyectos?
Poder de acuario
fuente
3
He reformulado el título y la pregunta principal en la publicación (en su mayoría ajustes menores de redacción en este punto). Debería estar un poco mejor ahora.
1
¿Leyó paquetes de sellado dentro de un archivo JAR ? Esto se aplica tanto a paquetes individuales como a frascos enteros.

Respuestas:

10

Puede probar que un jar está sellado definiendo una clase para que exista en un paquete utilizado en el archivo jar. Si el frasco está sellado, todos los paquetes están normalmente sellados, de lo contrario, puede sellarlos por paquete. La clase que cree debería intentar acceder a los miembros protegidos o predeterminados de una clase en ese paquete.

Por ejemplo, si el jar tiene una clase com.example.Widgetdonde el paquete com.exampleestá sellado y Widgettiene miembros protegidos / predeterminados, cree una clase com.example.Testque intente acceder a esos miembros. Esto debería fallar.

El motivo del sellado se deriva de una descripción de cómo probarlo: desea que su código sea autónomo y los usuarios del jar solo deben usar miembros públicos. No se requiere que los paquetes sean únicos en los archivos jar (y las carpetas bin en su IDE) utilizados por un programa. Puede definir una clase en el mismo paquete que en un jar y acceder a miembros protegidos / predeterminados que pueden causar problemas. A menudo, la visibilidad predeterminada se usa como un análogo a la friendpalabra clave de C ++ al permitir que otras clases en el mismo paquete puedan realizar acciones que solo son seguras porque los mismos programadores trabajan en ambas clases y entienden sus componentes internos. Tal vez un método de visibilidad predeterminado evita algunos límites al verificar el nombre del rendimiento, con el entendimiento de que el código del cliente nunca accederá a él. Por ejemplo, elStringLa clase en Java tiene algunos de estos tipos de métodos ya que el manejo de cadenas debe ser extremadamente rápido porque una gran cantidad de código depende de él. BigDecimalestá construido sobre BigIntegery utiliza el acceso predeterminado para optimizar algunas operaciones que otros usuarios de la clase no deberían usar.

TL; DR : Las clases en el mismo paquete pueden tener acceso a miembros no públicos entre sí por rendimiento o simplicidad. Es posible que este acceso no verifique invariantes y condiciones previas. Uno puede poner clases en el mismo paquete en múltiples ubicaciones en el classpath. Sellar un paquete o jar restringe el acceso del código del cliente a estos métodos, ya que de lo contrario podría romper cosas.

Esto no causará ningún problema a los usuarios del jar. El mecanismo de carga de clases que accede a los recursos (por ejemplo, archivos de clase) en jarras es totalmente compatible con jarras y paquetes sellados.

Lectura relacionada: Sellar paquetes dentro de un archivo JAR


fuente
así que si quiero que Widget sea completamente extensible, ¿no debo sellar el frasco ya que los miembros protegidos serán inaccesibles? o se puede crear otro frasco que no esté sellado para ello ¿verdad? en otras palabras, como el 3D JMonkeyEngine, creo que no sellarán sus frascos (y debo cuidarme de no sellarlos también al distribuirlos, pero veré que mi propio proyecto no funciona si está sellado, supongo, porque extiendo y acceso a miembros protegidos).
Acuario Power
Además, quería evitar el acceso de miembros protegidos de las clases en el mismo proyecto; en este caso, creo que necesitaría crear otro proyecto pequeño y usar su frasco sellado en el proyecto principal, ¿verdad? o podría haber otra manera?
Acuario Power
También leí sobre SecurityException en caso de que intentemos "anular una clase" de un paquete sellado.
Acuario Power
1
Del artículo vinculado: "Los paquetes dentro de los archivos JAR se pueden sellar opcionalmente, lo que significa que todas las clases definidas en ese paquete deben archivarse en el mismo archivo JAR". Esto se trata simplemente de restringir la especificación del paquete de una clase, lo que tiene un impacto en los miembros predeterminados / protegidos a los que otras clases pueden acceder en el mismo paquete que describo en mi respuesta. Esto es ortogonal a la herencia, lo que significa que puede extender las clases en frascos sellados y puede acceder a los miembros protegidos de esa manera.
Si desea que una clase en un paquete sellado no se extienda, hágalo final. Si desea que se extienda dentro del jar pero no afuera ... debe comenzar a buscar clases de visibilidad predeterminadas, interfaces, métodos de fábrica, etc., que están fuera del alcance de esta pregunta.
2

Para responder a su segunda pregunta, sellamos nuestros frascos como medida de seguridad, ya que esto evita una forma de inyección de código donde se agregan clases adicionales a nuestra base de código en tiempo de ejecución.

Tenemos una cierta cantidad de reflexión en nuestro código donde los objetos se crean en función de la entrada del usuario. El código que crea estos objetos solo permitirá instanciar clases de nombres de paquetes fijos.

Al sellar los frascos que contienen las clases que queremos que los usuarios puedan crear, no hay forma de que el usuario pueda crear nuevas clases potencialmente peligrosas y hacer que nuestro software las instancia en tiempo de ejecución. A menos que la clase esté en el paquete correcto, nuestro código no lo cargará, y sellar los frascos significa que solo las clases a las que deseamos que los usuarios tengan acceso son accesibles.

Si nuestros Jars no estuvieran sellados, el usuario podría agregar nuevas clases que podrían ser instanciadas. Esto sería un riesgo de seguridad.

TL; DR: al sellar sus jarras, puede evitar un tipo de inyección de código malicioso.

Mark Douglas
fuente
entonces, ¿básicamente necesitaríamos codificar (cadena constante) el acceso a las clases recién instanciadas para garantizar que estén en el paquete correcto? También me pregunto si eso podría interferir con el perfil de jrat.
Acuario Power