En informática , marshalling o marshaling ( ortografía estadounidense ) es el proceso de transformar la representación de memoria de un objeto en un formato de datos adecuado para el almacenamiento o la transmisión , especialmente entre diferentes tiempos de ejecución . [ cita requerida ] Se utiliza normalmente cuando los datos deben trasladarse entre diferentes partes de un programa informático o de un programa a otro.
El marshalling simplifica las comunicaciones complejas, porque permite utilizar objetos compuestos en lugar de restringirse a objetos primitivos .
El marshalling es similar o sinónimo de serialización , aunque técnicamente la serialización es un paso en el proceso de marshalling de un objeto.
Por lo tanto, el marshalling y la serialización se pueden realizar de manera diferente, aunque normalmente se utiliza alguna forma de serialización para realizar el marshalling. [1]
El término deserialización es algo similar a desmarshalar un objeto seco "en el lado del servidor", es decir, desmarshalar (o desmarshalar) para recuperar un objeto vivo: el objeto serializado se transforma en una estructura de datos interna, es decir, un objeto vivo dentro del entorno de ejecución de destino. Por lo general, corresponde al proceso inverso exacto del marshalling, aunque a veces ambos extremos del proceso activan una lógica empresarial específica.
La definición precisa de serialización difiere entre lenguajes de programación como Python , Java y .NET y, en algunos contextos, se utiliza indistintamente con serialización.
" Serializar " un objeto significa convertir su estado en un flujo de bytes de tal manera que el flujo de bytes pueda convertirse nuevamente en una copia del objeto, lo que en esencia es desagrupar. Los distintos lenguajes de programación hacen o no la distinción entre los dos conceptos. Algunos ejemplos:
En Python , el término "marshal" se utiliza para un tipo específico de "serialización" en la biblioteca estándar de Python [2] : almacenar objetos internos de Python:
El módulo marshal existe principalmente para soportar la lectura y escritura de código “pseudocompilado” para módulos Python de archivos .pyc.
…
Si está serializando y deserializando objetos Python, utilice el módulo pickle en su lugar
— La biblioteca estándar de Python [3]
En el RFC 2713 relacionado con Java , se utiliza el marshalling al serializar objetos para invocación remota . Un objeto que se serializa registra el estado del objeto original y contiene la base de código ( la base de código aquí se refiere a una lista de URL desde donde se puede cargar el código del objeto, y no al código fuente). Por lo tanto, para convertir el estado del objeto y la base de código, se debe realizar un desmarshalling. La interfaz de unmarshaller convierte automáticamente los datos serializados que contienen la base de código en un objeto Java ejecutable en JAXB. Cualquier objeto que se pueda deserializar se puede desmarshalling. Sin embargo, no es necesario que lo inverso sea cierto.
"Marshal" (registrar) un objeto significa registrar su estado y código base de tal manera que cuando el objeto serializado se "desmarque", se obtenga una copia del objeto original, posiblemente cargando automáticamente las definiciones de clase del objeto. Puede serializar cualquier objeto que sea serializable o remoto (es decir, que implemente la interfaz java.rmi.Remote). El marshaling es como la serialización, excepto que el marshaling también registra códigos base. El marshaling se diferencia de la serialización en que el marshaling trata los objetos remotos de manera especial.
…
Cualquier objeto cuyos métodos se puedan invocar [en un objeto de otra máquina virtual Java] debe implementar la interfaz java.rmi.Remote. Cuando se invoca un objeto de este tipo, sus argumentos se ordenan y se envían desde la máquina virtual local a la remota, donde se desordenan y se utilizan.
— Esquema para representar objetos Java(tm) en un directorio LDAP (RFC 2713) [4]
En .NET , el marshalling también se utiliza para referirse a la serialización cuando se utilizan llamadas remotas :
Cuando se serializa un objeto por valor, se crea una copia del objeto y se serializa en el servidor. Todas las llamadas a métodos que se realizan en ese objeto se realizan en el servidor.
— Cómo enviar un objeto a un servidor remoto por valor mediante Visual Basic .NET (Q301116) [5]
El marshalling se utiliza dentro de implementaciones de diferentes mecanismos de llamada a procedimiento remoto (RPC), donde es necesario transportar datos entre procesos y/o entre subprocesos .
En el Modelo de objetos componentes (COM) de Microsoft , los punteros de interfaz deben serializarse al cruzar los límites del departamento COM. [6] [7] En .NET Framework , la conversión entre un tipo no administrado y un tipo CLR , como en el proceso P/Invoke , también es un ejemplo de una acción que requiere que se realice la serialización. [8]
Además, el marshalling se utiliza ampliamente en scripts y aplicaciones que utilizan las tecnologías XPCOM proporcionadas dentro del marco de aplicaciones de Mozilla . El navegador Mozilla Firefox es una aplicación popular creada con este marco, que además permite que los lenguajes de script utilicen XPCOM a través de XPConnect (Cross-Platform Connect).
En la familia de sistemas operativos Microsoft Windows , todo el conjunto de controladores de dispositivos para Direct3D son controladores en modo kernel. La parte de la API en modo usuario la gestiona el entorno de ejecución DirectX proporcionado por Microsoft.
Esto es un problema porque llamar a operaciones en modo kernel desde el modo usuario requiere realizar una llamada al sistema , y esto inevitablemente obliga a la CPU a cambiar al "modo kernel". Esta es una operación lenta, que tarda en completarse en el orden de microsegundos . [9] Durante este tiempo, la CPU no puede realizar ninguna operación. Por lo tanto, minimizar la cantidad de veces que se debe realizar esta operación de cambio optimizaría el rendimiento en un grado sustancial.
Los controladores OpenGL de Linux se dividen en dos: un controlador de kernel y un controlador de espacio de usuario. El controlador de espacio de usuario realiza toda la traducción de los comandos OpenGL a código de máquina para enviarlos a la GPU . Para reducir la cantidad de llamadas al sistema, el controlador de espacio de usuario implementa el marshalling. Si el búfer de comandos de la GPU está lleno de datos de renderizado, la API podría simplemente almacenar la llamada de renderizado solicitada en un búfer temporal y, cuando el búfer de comandos esté cerca de vaciarse, puede realizar un cambio al modo kernel y agregar una cantidad de comandos almacenados a la vez.
La serialización de datos requiere algún tipo de transferencia de datos, que aprovecha un formato de datos específico que se elegirá como objetivo de serialización.
XML es uno de esos formatos y un medio de transferencia de datos entre sistemas. Microsoft, por ejemplo, lo utiliza como base de los formatos de archivo de los distintos componentes (Word, Excel, Access, PowerPoint, etc.) del paquete Microsoft Office (véase Office Open XML ).
Aunque esto suele dar como resultado un formato de cable muy detallado, la sintaxis de XML, con etiquetas de inicio y de fin entre corchetes, permite ofrecer diagnósticos más precisos y una recuperación más sencilla de errores de transmisión o de disco. Además, como las etiquetas aparecen repetidamente, se pueden utilizar métodos de compresión estándar para reducir el contenido (todos los formatos de archivo de Office se crean comprimiendo el XML sin procesar). [10] Los formatos alternativos, como JSON (JavaScript Object Notation), son más concisos, pero correspondientemente menos robustos para la recuperación de errores.
Una vez que los datos se transfieren a un programa o una aplicación, es necesario convertirlos nuevamente en un objeto para su uso. Por lo tanto, la desagrupación se utiliza generalmente en el extremo receptor de las implementaciones de los mecanismos de invocación de método remoto (RMI) y llamada a procedimiento remoto (RPC) para desagrupar los objetos transmitidos en un formato ejecutable.
JAXB o Arquitectura Java para Enlace XML es el marco más común utilizado por los desarrolladores para ordenar y desordenar objetos Java. JAXB permite la interconversión entre los tipos de datos fundamentales admitidos por Java y los tipos de datos de esquema XML estándar . [11]
XmlSerializer es el marco de trabajo que utilizan los desarrolladores de C# para ordenar y desordenar objetos de C#. Una de las ventajas de C# sobre Java es que C# admite de forma nativa la ordenación gracias a la inclusión de la clase XmlSerializer. Java, por otro lado, requiere un código de unión no nativo en forma de JAXB para admitir la ordenación. [12]
Un ejemplo de desagrupación es la conversión de una representación XML de un objeto a la representación predeterminada del objeto en cualquier lenguaje de programación. Considere la siguiente clase:
clase pública Estudiante { char privado nombre [ 150 ] ; int privado ID ; String público obtenerNombre ( ) { devuelve este.nombre ; } int público obtenerID ( ) { devuelve este.ID ; } void setName ( String nombre ) { este.nombre = nombre ; } void setID ( int ID ) { este.ID = ID ; } }
<!-- Fragmento de código 1 --><?xml version="1.0" encoding="UTF-8"?> <student id= "11235813" > <nombre> Jayaraman </nombre> </student> <student id= "21345589" > <nombre> Shyam </nombre> </student>
// Fragmento de código 2Estudiante s1 = nuevo Estudiante (); s1.setID ( 11235813 ) ; s1.setName ( " Jayaraman" ) ; Estudiante s2 = nuevo Estudiante ( ) ; s2.setID ( 21345589 ) ; s2.setName ( " Shyam " ) ;
La desagrupación es el proceso de convertir la representación XML del fragmento de código 1 a la representación ejecutable Java predeterminada del fragmento de código 2 y ejecutar ese mismo código para obtener un objeto coherente y activo. Si se hubiera elegido un formato diferente, el proceso de desagrupación habría sido diferente, pero el resultado final en el entorno de ejecución de destino sería el mismo.
El proceso de desagrupar datos XML en un objeto Java ejecutable está a cargo de la clase Unmarshaller incorporada. Los métodos de desagrupación definidos en la clase Unmarshaller están sobrecargados para aceptar XML de diferentes tipos de entrada, como un archivo, un flujo de entrada de archivo o una URL. [13] Por ejemplo:
JAXBContext jcon = JAXBContext . newInstance ( "com.acme.foo" ); Desmarshaller umar = jcon . createUnmarshaller (); Objeto obj = umar . unmarshal ( nuevo Archivo ( "input.xml" ));
Los métodos de deserialización pueden deserializar un documento XML completo o una pequeña parte de él. Cuando el elemento raíz XML se declara globalmente, estos métodos utilizan la asignación de JAXBContext de elementos raíz XML a clases asignadas a JAXB para iniciar la deserialización. Si las asignaciones no son suficientes y los elementos raíz se declaran localmente, los métodos de deserialización utilizan métodos de tipo declarado para el proceso de deserialización. Estos dos enfoques se pueden entender a continuación. [13]
El método unmarshal utiliza JAXBContext para desagrupar los datos XML cuando el elemento raíz se declara globalmente. El objeto JAXBContext siempre mantiene una asignación del elemento XML declarado globalmente y su nombre a una clase asignada a JAXB. Si el nombre del elemento XML o su @xsi:type
atributo coincide con la clase asignada a JAXB, el método unmarshal transforma los datos XML utilizando la clase asignada a JAXB adecuada. Sin embargo, si el nombre del elemento XML no coincide, el proceso de desagrupación se interrumpirá y generará una UnmarshalException . Esto se puede evitar utilizando los métodos unmarshal by declaredType . [14]
Cuando el elemento raíz no se declara globalmente, la aplicación ayuda al desagrupador mediante la asignación proporcionada por la aplicación utilizando parámetros de tipo declarado. Por orden de precedencia, incluso si el nombre raíz tiene una asignación a una clase JAXB apropiada, el tipo declarado anula la asignación. Sin embargo, si el @xsi:type
atributo de los datos XML tiene una asignación a una clase JAXB apropiada, entonces esto tiene prioridad sobre el parámetro de tipo declarado. Los métodos de desagrupación por parámetros de tipo declarado siempre devuelven una JAXBElement<declaredType>
instancia. Las propiedades de esta instancia de JAXBElement se establecen de la siguiente manera: [15]