Buscar
Social
Ofertas laborales ES
« La ley de Yannis: la productividad de los programadores se duplica cada seis años | Main | Zeroturnaround anuncia JRebel 5.0 »
lunes
jun182012

JavaFX 2.2 traerá empaquetamiento nativo de aplicaciones

JavaFX 2.2 (en estos momentos ya está disponible para descargar JavaFX 2.2 build b13) va a atraer nuevas opciones para empaquetar las aplicaciones en ejecutables nativos para múltiples plataformas; se van a soportar los formatos de instalador exe, msi, dmg, rpm y archivos comprimidos zip para linux. Al usar esta opción para distribuir nuestra aplicación JavaFX el resultado será un instalador completamente autocontenido que incluye su propio JRE, para evitar posibles problemas de incompatibilidades entre la versión de Java requerida por la aplicación y la instalada en el equipo, o el escenario en el cual Java no está instalado en el equipo.

Entre las ventajas que tendrá esta solución está la posibilidad de distribuir nuestras aplicaciones Java FX en la Mac AppStore, donde no se permite aplicaciones que tengan dependencias externas. No obstante, las opciones de empaquetar la aplicación como un archivo jar, un Applet o una aplicación Java web start siguen disponibles.

Si queréis probar esta nueva funcionalidad podéis bajar una build del JDK 7u6, que ya incluye JavaFX 2.2 SDK así como las nuevas herramientas de empaquetamiento.

PrintView Printer Friendly Version

EmailEmail Article to Friend

Reader Comments (32)

Todo eso está muy bien, pero... No está ayudando en nada a lo que puede significar el éxito o el fracaso de JavaFX: la adopción por parte de los desarrolladores en Swing.

El problema de fondo, en la actualidad, consiste en que la integración de JavaFX en proyectos existentes en Swing es una calamidad, por decirlo con suavidad.
No hay una manera sencilla, ni cómoda, de integrar JavaFX en Swing, a causa de las dependencias externas de código nativo, que no se resuelven por la librería Java de JavaFX, en ejecución.
Es decir, si quiero incorporar componentes de JavaFX en una aplicación existente en Swing, tengo forzosamente que incluir en el proyecto todas las librerías nativas, de todos los sistemas operativos soportados por JavaFX, para que pueda ejecutarse.

A menos que esto se resuelva de una manera satisfactoria, JavaFX se va a quedar como otro intento fallido. Por más demos que se publiquen, su éxito solamente estará "asegurado" en el caso de que atraiga, sin dudas ni "invenciones raras", a los desarrolladores en Swing.
A menos que se crea que su futuro estará ligado inexorablemente al desarrollo para móviles, y webs. Personalmente estoy convencido de que no será así.

junio 18, 2012 | Registered Commenterchoces

Para aquellos que quieran explotar esta línea de despliegue de aplicaciones de "empaquetamiento nativo".

Les recomendaría utilizar "Excelsior JET". no solo encapsula una maquina virtual a medida de tu aplicación como parte del instalable (no se pre inicializan aquellos elementos de la JVM que no se van a utilizar), sino que además pre arma los JIT de manera optima y los almacena en disco, por lo que la diferencia de rendimiento con una JMV estándar es más que palpable, en especial en swing.

Y todo esto sin alterar los JAR y arrastrar dependencias extrañas, por lo que puedes tener un "ejecutable" para una plataforma N y arrancar de manera tradicional en el resto.

Un saludo,

junio 18, 2012 | Registered Commenterefrigerio

"No está ayudando en nada a lo que puede significar el éxito o el fracaso de JavaFX: la adopción por parte de los desarrolladores en Swing."

QUIEN DIJO QUE JAVAFX es para desarrolladores Swing?!?!?!?!

Nuevamente, gente salta a concluciones erróneas en base a supuestos erróneos...

FC

junio 18, 2012 | Unregistered CommenterFernando Cassia

yo por la parte que me toca sigo sin ver el futuro claro para JavaFX. Es qué tan siquiera entiendo el "porqué" desde el punto de vista de Oracle. No sé qué pretenden…

junio 19, 2012 | Registered CommenterAbraham

@Fernando

"QUIEN DIJO QUE JAVAFX es para desarrolladores Swing?!?!?!?!"

Lo dice Oracle, por ejemplo, como puede verse con claridad en el FAQ de JavaFX:

6. Is JavaFX replacing Swing as the new client UI library for Java SE?

Yes. However, Swing will remain part of the Java SE specification for the foreseeable future, and is included in the JRE. On one hand, Swing is widely used in existing Java desktop applications, but relies on an old architecture, which requires a certain level of expertise and specialization. On the other hand, JavaFX features a set of modern UI controls that can be skinned using standard CSS techniques. While we recommend developers to leverage JavaFX APIs as much as possible when building new applications, it is possible to use JavaFX within a Swing application, allowing developers to extend existing Swing applications.

http://www.oracle.com/technetwork/java/javafx/overview/faq-1446554.html

Aparte de esa evidencia, lo que yo he dicho es que JavaFX necesita para su éxito del apoyo de los desarrolladores en Swing. Y es una conclusión perfectamente lógica, dado que se pretende reemplazar Swing por JavaFX, como se dice con meridiana claridad en ese FAQ.

Sigo sin ver dónde hay conclusiones erróneas basadas en supuestos erróneos. A menos que te refieras a los supuestos y conclusiones de la propia Oracle.

junio 19, 2012 | Registered Commenterchoces

yo apoyo a javafx, nunca tuve la necesidad de hacer una aplicación standalone con javaSE hasta hace poco tuve esa necesidad y use de inmediato javaFX y realmente me pareció excelente en todos los sentidos, quizás el problema de los que mencionan a Swing es la transición de una herramienta a otra pero para los que empezamos de ceros me parece que deberíamos en definitiva usarlo. El único claro problema que le encuentro es la falta de herramienta pero eso es un problema que poco a poco se solventa con scene builder.

junio 19, 2012 | Registered Commentermontblack

@montblack

Puesto que usas JavaFX tal vez te interesaría echar un ojo aquí:

http://fxexperience.com/

junio 19, 2012 | Registered Commenterchoces

¿Alguien ha visto en JavaFX algo remotamente parecido al javax.swing.text.EditorKit ?

¡Y que nadie se atreva a decir que no es necesario porque menudo rollo le va a caer!.

junio 19, 2012 | Registered Commenterefrigerio

¿Es necesario? :O

En los packages .text y .web creo que hay algo parecido; pero como no sabía que era necesario, tampoco estoy muy seguro de que sean parecidos :O

junio 19, 2012 | Registered Commenterchoces

estoy empezando a usar javafx y realmente me gusta. no es dificil de aprender. ofrece muchooo mas que swing que honestamente ya me fastidia usarlo.

junio 19, 2012 | Unregistered Commentermiguel

"No es difícil de aprender"

Después de ver lo que sigue:

http://docs.oracle.com/javafx/2/ui_controls/table-view.htm#CJAGAAEE

me reservo mi opinión sobre lo "fácil" de aprender que pueda ser.
Si todavía queda alguien que crea que usar JavaFX en serio, y no para hacer "demos de blog", será "fácil"... mejor que vaya cambiando de idea.

junio 20, 2012 | Registered Commenterchoces

@choces
El EditorKit es la base sobre la que se construyen los browser y editores visuales de casi cualquier cosa que se altere dinámicamente, (SQL, HTML, XML, código java, y lo que se te ocurra).

Su potencia está en mantener coordinado el parser, con el árbol y la representación visual. Además de propagar los cambios entre estos y permitir inyectar comportamiento en diferentes capas.

Si alguien pretende hacer algo del nivel y la complejidad de comportamiento que puede tener un NetBeans, openoffice, dbvisualizer, y demas, lo coerente es que travaje a partir del EditorKit,

PD:
¿Cuáles son las clases de las que hablabas en los packages .text y web?.

junio 21, 2012 | Registered Commenterefrigerio

@efrigerio

Es evidente que no has pillado mi ironía sobre el Editor :D
De los javadocs de JavaFX: http://docs.oracle.com/javafx/2/api/index.html
No sé si tiene alguna relación directa con lo que quería saber.
De todos modos tengo la impresión (más subjetiva que objetiva en estos momentos) de que la "potencia" de JavaFX en relación con Swing es más una posibilidad, que una realidad, en lo que se refiere a su funcionalidad. El rendimiento gráfico no es comparable: JavaFX gana a Swing por goleada.
Todavía no creo que JavaFX esté en condiciones objetivas de reemplazar a Swing, por el momento. Sigue siendo "código beta", y le queda mucho camino que recorrer. En su favor, hay una gran actividad de desarrollo, con novedades constantes.

junio 21, 2012 | Registered Commenterchoces

Hola choces, no trabajé nunca con swing, sólo lo conozco de lecturas y ejemplos hechos, por lo cual viendo el ejemplo del enlace tuyo no termino de ver porque no es fácil de utilizar.
Podrías explicarlo un poco mas en detalle?
Gracias

junio 21, 2012 | Unregistered Commenterdiego

Mi comentario quería salir al paso de quienes crean que codificar en JavaFX, comparado con Swing, es "mucho más fácil". Tal como decir que con JavaFX se pueden resolver los mismos problemas, "con cuatro golpes de ratón, y media docena de líneas de código".

Si lees con atención los comentarios en ese enlace, te darás cuenta de que hay muchos detalles que se dejan a un lado. Y que tratándose de una demo, quedan todavía más en el aire situaciones más realistas, como que los modelos para una Table se suelen construir a partir de accesos a bases de datos.

En realidad no veo una diferencia significativa, en cuanto a complejidad, respecto de Swing.

junio 21, 2012 | Registered Commenterchoces

@choces
http://docs.oracle.com/javafx/2/api/index.html

Mas ironía, supongo.
:o)

En cuanto a lo de "El rendimiento gráfico no es comparable: JavaFX gana a Swing por goleada." Para mí esto se explica por dos motivos,

1. Swing puede mejorarse (y mucho) sin necesidad de romper compatibilidad. El problema es que esto no se está haciendo.
2. Como has dicho la "potencia" de JavaFX en relación con Swing es más una posibilidad. O dicho de otra forma, el día que este en condiciones de dar soporte de manera estable a un rcp, a una suite ofimática. O cualquier otra cosa de semejante calaña, no creo que la diferencia termine siendo tan sustancial.

En todo caso me preocupa más lo que está pasando actualmente con los escritorios (Windows Metro, Ubuntu Unity, por ejemplo), Multi-touch, Geolocation, y no veo o escucho nada al respecto.

junio 21, 2012 | Registered Commenterefrigerio

@efrigerio

Como me preguntabas por esos packages... ¡Qué mejor que un enlace con sus Javadocs! :D

Siempre he sostenido que el problema de fondo de Swing es su dependencia de AWT, y de las limitaciones "nativas" tras AWT, en cuanto a su rendimiento gráfico.
Si se incluyese en el Hotspot un nuevo tipo de soporte gráfico, como se ha hecho con JavaFX, y AWT dejase de ser la pariente pobre de Java, es seguro que Swing daría un gran salto adelante, y no habría el más mínimo problema de compatibilidad.

Pero han decidido crear JavaFX, y proporcionarle todo lo que le falta a Swing, siempre en relación con su potencia gráfica.

Lo malo es que me temo que los criterios de diseño de JavaFX siguen, en los demás aspectos, la misma "idea" de fondo que Swing. A pesar de los años transcurridos, siguen sin considerar el problema de la comunicación entre componentes visuales, eliminando el acoplamiento excesivo. Me parece mentira que soluciones como EventBus o Google Guava EventBus, sigan estando fuera de JavaFX lo mismo que de Swing, y se siga insistiendo en los Observers. Hasta podrían "copiar" el Lookup API de NetBeans, que es de "la casa", y ni por esas.

Tal y como van las cosas, sospecho que JavaFX acabará siendo un Swing sin AWT, y como es más rápido (gracias a las librerías gráficas nativas), y más "atractivo" (gracias a CSS), se terminará "vendiendo" como el "gran avance en UI", mientras que los problemas cotidianos en desarrollos serios seguirán precisando de "añadidos externos", para que los RCP sean bastante más que demos bonitas para lucimiento de blogs de moda.

junio 21, 2012 | Registered Commenterchoces

Y aquí llegamos al punto muerto de siempre.

Para mí el problema no es AWT, si no lo que está por debajo. En ese sentido me gusta la aproximación de Opera, ellos crearon su propio motor de renderizado, yendo contra el mínimo común de las primitivas graficas (de todos los OS), renderizando el resto y empleando aceleramiento por hardware siempre que este se pueda. ¿Te suena conocido?

Se podía hacer exactamente lo mismo en java, pero por debajo de JNI en C++ y listo todo en orden y sin tener que recompilar nada.

Por otra parte, en su momento (en la versión 1.5, si mal no recuerdo) se reemplazo Graphics por java2d (ahora Graphics2D), lo que se tradujo en una enorme mejora de performance, aun para aquellas cosas compiladas en 1.4. Por lo que no veo cual es el problema de hacer exactamente lo mismo con java3D (un Graphics3D) y colgar los efectos y animaciones de los componentes desde este.

¿Qué Swing es complejo para el programador medio?
Pues a construir algo por encima que lo simplifique, pero sin romper compatibilidad.

La verdad, es que JavaFX lleva ya demasiado tiempo sin "estar a la altura" y mientras tanto el escritorio está cambiando, las maquinas tienen nuevos rasgos y funciones (Geolocation no tiene nada que ver con Swing vs JavaFX), y nosotros seguimos atrapados entre una promesa incumplida y un toolkit sin mantenimiento.

Y quizás sea esto lo que más me molesta de JavaFX, no el que Oracle invierta tiempo y esfuerzo en su desarrollo (cada uno hace con sus recursos lo que le conviene o considere correcto) si no que muchos de los espejos de colores que se están vendiendo en nombre de JavaFX, son cosas que deberían estar en Swing desde hace varios años.

junio 21, 2012 | Registered Commenterefrigerio

Creo que ha sido un error no haber aprovechado la oportunidad para tener algún mecanismo para definir la interfaz en un documento xml u otro formato, de forma parecida a como se hace en android.

junio 22, 2012 | Unregistered Commentermario

Así comienza el bloque de código del constructor estático de Component de AWT:

static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
/* initialize JNI field and method ids */
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}

del que dependen todos los demás componentes visuales de AWT y de Swing.

Así se declara el método initIDs, hacia el final de la clase Component:

/**
* Initialize JNI field and method IDs
*/
private static native void initIDs();

Sobre loadLibraries... basta con leer el comentario inicial, para darse cuenta de "dónde estamos":

/**
* WARNING: This is a temporary workaround for a problem in the
* way the AWT loads native libraries.
A number of classes in the
* AWT package have a native method, initIDs(), which initializes
* the JNI field and method ids used in the native portion of
* their implementation.
*
* Since the use and storage of these ids is done by the
* implementation libraries, the implementation of these method is
* provided by the particular AWT implementations (for example,
* "Toolkit"s/Peer), such as Motif, Microsoft Windows, or Tiny. The
* problem is that this means that the native libraries must be
* loaded by the java.* classes, which do not necessarily know the
* names of the libraries to load. A better way of doing this
* would be to provide a separate library which defines java.awt.*
* initIDs, and exports the relevant symbols out to the
* implementation libraries.
*
* For now, we know it's done by the implementation, and we assume
* that the name of the library is "awt". -br.
*
* If you change loadLibraries(), please add the change to
* java.awt.image.ColorModel.loadLibraries(). Unfortunately,
* classes can be loaded in java.awt.image that depend on
* libawt and there is no way to call Toolkit.loadLibraries()
* directly. -hung
*/
private static boolean loaded = false;
static void loadLibraries() {
if (!loaded) {
java.security.AccessController.doPrivileged(
new sun.security.action.LoadLibraryAction("awt"));
loaded = true;
}
}

junio 22, 2012 | Registered Commenterchoces

@mario

Tengo curiosidad por saber cómo se hace en Android, porque sinceramente no comprendo lo que quieres decir con "definir una interfaz para documentos".

junio 22, 2012 | Registered Commenterchoces

@choces
"This is a temporary workaround for a problem in the way the AWT loads native libraries"
.

Que lo arreglen !!.

En todo caso si estuviesen actuando contra un solo toolkit en C++ (albo de la filosofía de QT) y que se arrastre como parte de la JVM, en lugar de tener que interactuar con uno distinto para cada plataforma. esto no sería un problema.

junio 22, 2012 | Registered Commenterefrigerio

No sé en qué fecha fue escrito ese comentario, pero sospecho que lleva ahí tantos años como los que tiene el mismo AWT.
Lo que quería era resaltar la intrincada dependencia que tienen las clases fundamentales de AWT, respecto de un código nativo que estaba anticuado cuando se crearon.
No es de recibo que cuando se creó AWT solo pudiese utilizar el modo SVGA, por diseño, y haya seguido así todos estos años, sin que se les cayese la cara de vergüenza a sus responsables. James Gosling, can you here me? ;P

Dices "que lo arreglen" :D que es justo lo que están haciendo: JavaFX ;)

junio 22, 2012 | Registered Commenterchoces

¿Lo están haciendo?

Pregunto, porque lo que he visto de las tripas de JavaFX me da a entender que siguen utilizando un toolkit grafico distinto en cada plataforma.

Aun así seguimos en lo mismo
¿Cuál es el problema de reemplazar el Graphics2D por un Graphics3D al estilo de lo que se hiso en su momento?

Qué problema existe por el cual los Font no sean compatibles e intercambiables entre Swing y JavaFX.

¿Porque determinados objetos como MediaPlayer o el WebView (y que originalmente vieron la luz como componentes de Swing en las presentaciones de la JavaOne) no están disponibles en ambos toolkit de java?

¿Porque JavaFX tiene tan bajo nivel de acoplamiento con el resto de la JFC, en lugar de reutilizar cosas como el org.w3c.dom.Document o javax.script.* ?

Y en esa línea podría seguir un buen rato, pero, y de nuevo, lo que me molesta no es que Oracle invierta tiempo y esfuerzo en el desarrollo de JavaFX. Como tampoco me molestó que IBM hiciese lo propio con SWT.

Pero lo que si me molesta es esto de "forzar el cambio" pateando el tablero para las toneladas de código que ya existen. Y de la misma forma que (en su momento) a muchos conocidos le cabreó tanto cuando Microsoft hiso lo mismo con VB6 en favor de .NET que directamente lo mandaron al diablo y se subieron a Java.

junio 22, 2012 | Registered Commenterefrigerio

@choces

En swing normalmente creas los componentes de la interfaz gráfica por ejemplo:
JLabel prompt1 = prompt1 = new JLabel( "Texto:" );
En android también tenemos de definirlo en xml:

file: main.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Hello, Android"/>

Pudiendo utilizar esas variable con java importando el xml con
setContentView(R.layout.main) obtener instancias de los componentes definido con el metodo findViewById(R.id.componente), R.id.componente es el identificador del componente.

De esta forma no hace falta definir en java toda la interfaz. Si queremos modificar la lógica modificaremos la parte escrita en java. Si es la interfaz normalmente solo modificaremos la parte escrita en xml.

junio 22, 2012 | Unregistered Commentermario

choces,
¿Has escuchado alguna vez esto de...?
Doctor, coincido con su diagnostico, pero no creo que el cianuro le sirva de remedio al paciente.

Pues, cada vez que tu y yo hablamos de JavaFX, esa frase se queda dando vueltas en mi cabeza.

:o)

junio 22, 2012 | Registered Commenterefrigerio

No sabía que fueses un aficionado al cianuro :D
¿Lo tomas solo, o con Java? ;P

La verdad es que me gustaría poder responder a todas esas cuestiones que planteas, pero esperaré a ser un "experto" en JavaFX, un año de estos. Si es que me decido a dedicarle tiempo, porque por ahora sigo aferrado con los dientes a Swing, aunque muy atento a lo que pase "al otro lado del pasillo" ;)

Lo peor que puede suceder es que a JavaFX 2.x le acabe pasando lo mismo que a su predecesor 1.x, con lo que nos podemos quedar con un Swing bastante obsoleto, y varios años más perdidos. Me acuerdo ahora de una frase: "Ni comemos, ni se muere padre".

junio 22, 2012 | Registered Commenterchoces

Creo que la frase asía alusión a alguna practica medica del siglo XVIII
¿O era arsénico? da igual.

En todo caso, creo que coincidimos bastante, la diferencia está en esta frase tuya.
"Lo peor que puede suceder es que a JavaFX 2.x le acabe pasando lo mismo que a su predecesor 1.x, con lo que nos podemos quedar con un Swing bastante obsoleto, y varios años más perdidos"

Para mí (y mientras JavaFX no de la talla) no es aceptable el que Swing se siga deteriorando.
Y no, antes que lo digas, no pierdo ni gano nada por hacer de Quijote.

En todo caso, te has sacado el gusto y hemos tenido el debate sobre JavaFX.

:o)

Aunque es una lástima que la gente de Oracle lea estas cosas y no reaccione.

PD:
¿espalda o lomo?, ¿pulpa o hueso?

:D

Un saludo.

junio 22, 2012 | Registered Commenterefrigerio

Recordarás la famosa frase, adjudicada a SUN: "Not invented here!, con la que se daba a entender la resistencia activa a admitir soluciones gestadas "fuera de la casa".

Como anécdota relativamente reciente, hace un par de años, cuando se presentó el bug de SwingWorker con su Executor interno, que lo convertía en monotarea, propuse abiertamente en los comentarios al bug 6880336 que se eliminase el final en la declaración del método execute(), de tal manera que se pudiese usar un Executor externo, si fuese el caso.

Ya imaginarás cómo terminó el asunto:
- Se limitaron a rectificar el asombroso bug interno, sin más.
- Terminé desarrollando mi propia versión de SwingWorker, fusionando las fuentes originales (antes de ser incluidas en el JDK), junto con las extensiones creadas para Swing Application Framework, y añadiendo o quitando lo que me pareció oportuno.

Con esto quiero decir que desde siempre ha habido una resistencia enorme a, no ya aceptar, sino siquiera a considerar cualquier cosa de "origen externo". Incluso eliminar un final de un método público les parece " arriesgado". Y de un método que se limita a iniciar un Executor, que por cierto también debería ser público, y no una clase privada.

Situaciones como ésta han sido la tónica habitual, y lo siguen siendo en gran medida. Comprenderás mi escepticismo ante la posibilidad de que, al margen del éxito o fracaso de JavaFX, mis expectativas respecto a mejoras significativas de Swing estén bajo mínimos.

junio 23, 2012 | Registered Commenterchoces

Habemos unos cuantos con historias similares.
En mi caso va de un error estúpido en los métodos getView y getViewCount de la clase javax.swing.text.BoxView, reportado varias veces a lo largo del tiempo y serrado siempre con el mismo comentario idiota “esto solo pasa cuando hay comentarios en el HTML”

Con esto en claro. ¿Qué garantía tienes de que no pasará exactamente lo mismo con JavaFX?


Un saludo,

junio 25, 2012 | Registered Commenterefrigerio

Yo empec'e a usar java hace poco por su eslogan escribelo un vez y ejecutalo donde quiera. Pero al parecer esto no es tan cierto. Si hago una aplicación de escritorio, no la puedo usar como applet y tampoco copiarla directamente a un movil y que funcione.
Mi idea es unificar esfuerzos. La máquina virtual de un móvil debería ignorar lo que no funcione en el móvil pero sin usar una api dedicada, sería bueno hacer un jar que al darle doble click en la pc se ejecutara, luego copiarla a un móvil y se ejecutara, luego esa misma aplicación iportarla en una página con la etiquieta applet y que funcionara. Pero al parecer seguimos en lo mismo, en la confusión. Seguirán reinventándose cosas hasta saturar la mente humana y estancar el desarrollo, se trancaría la tecnología por estas idioteces. ya basta, creemos una sola vm tanto para móviles como para pc y en vez de crear entornos separados del mismo lenguaje, añadamolos a la nueva versión como librería. Pero que al instalar el se tambien venga esta funcionalidad. Si no es así no me molestaría seguir con C/C++ si al final recompilo y ya en cualquier lado consiguiendo las librerías, no es esto lo que seguimos haciendo con java?.

noviembre 6, 2014 | Unregistered CommenterHaylem Candelario Bauzá

Buenas, estoy intentando empaquetar una aplicación realizada con Eclipse , usando JavaFx(media player ) y scene builder, es una reproductor multimedia de videos interactivos, al empaquetarlo cuando ejecuto el .jar las funcionalidades que me realiza cuando lo ejecuto desde eclipse como una java Aplication , no me las realiza , por lo tengo me lo empaqueta mal , ¿alguien sabe como solucionarlo?, muchas gracias

noviembre 24, 2020 | Unregistered CommenterNerea

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>