Exporter un programme utilisant JOGL en Jar auto-éxécutable (ou sinon en JNLP).

Résolu
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012 - 14 juin 2011 à 12:17
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012 - 25 juil. 2011 à 00:47
Bonjour :)

J'ai développé un application JOGL, depuis Eclipse, en ayant crée ma User Library pour JOGL (avec les librairies natives pour WIndows, Mac et Linux i586).

Mon os de développement est Xubuntu 11.04, i586

Le problème que je rencontre, et je sais que beaucoup ont déjà essayé avant moi (certains ont déjà réussi je pense) mais je n'arrive pas à trouver une référence qui m'est utile sur le web, c'est pour exporter l'application en Jar auto-éxécutable qui puisse tourner sur les 3 OS les plus répandus.

1ere méthode essayée
Menu Export -> Runnable Jar File
[list]
[*] J'ai essayé les deux 1eres options : intégrer la librairie JOGL directement dans le Jar, et l'autre option compacter la librairie dans le Jar.
[*] J'ai même essayé en décompressant Jogl.jar et Gluegen-rt.jar avant de les recompresser en jar et les intégrer à nouveau dans le Jar de mon projet, afin de resigner le tout (par keytools) de manière cohérente => Rien n'y fait
/list

2e méthode essayée

Par JNLP

Je me suis inspiré du JNLP trouvé sur un autre site (progx.org) afin de rendre mon code auto-éxécutable par JavaWebStart, mais je rencontre des problèmes de sécurité.

A noter, je n'ai pas accès aux fichiers apaches de mon hébergeur (je suis hébergé gratuitement chez byethost22.com) afin d'ajouter le mime de jnlp : ceci explique peut-être cela.


Quelqu'un pourrait-il m'aider ?

Merci d'avance :)




Loloof64 : Programmer pour le plaisir et pour progresser :)

52 réponses

Utilisateur anonyme
19 juin 2011 à 23:59
N'as-tu rien trouvé dans mon code?


T.U.E.R yeah! vive java
0
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012
20 juin 2011 à 01:04
Il me semble, sans en être sûr, que tu appliques la formule dans la méthode rotateGlobal de la classe Camera (Source gimballock). Après cela m'arrangerait si je pouvais mieux comprendre l'algorithme sans forcément faire du copier-coller presque parfait. (J'ai entre autres remarqué que tu appliques plusieures fois la formule q*v*q^(-1) sur les quaternions qui permet d'appliquer une rotation sur un vecteur/point).

Demain je pense recommenser à analyser davantage le code, et revoir les formules que j'ai trouvées sur les quaternions. Quand on débute avec les "supers nombres complexes", c'est pas forcément de tout repos ^^ .

Programmons oui, mais le plus proprement possible.
0
Utilisateur anonyme
20 juin 2011 à 10:08
Bonjour

Je vais essayer de jeter un coup d'oeil dans mon vieux code pour voir où j'avais implémenté ça. Je te tiens au courant.











T.U.E.R yeah! vive java
0
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012
20 juin 2011 à 21:01
Salut,

je pense que ma classe quaternion est mal implémentée : j'ai réutilisé ton algorithme (sans les "if"), mais le résultat de la rotation combinée sur le cube est pire qu'avant. Il me faut donc encore travailler sur ma classe Quaternion.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012
21 juin 2011 à 18:56
Voici ma classe Quaternion : est-elle correcte ? Merci d'avance

/**
 * Represente un quaternion
 * @author laurent BERNABE
 *
 */
public class Quaternion {

/**
 * Construit un quaternion identite (pour multiplications)
 * => (w=1, x=0, y=0, z=0).
 */
private Quaternion(){
w = 1;
x y z = 0;
}

/**
 * Construit un quaternion a partir des 4 composantes
 * @param w - float - le composant scalaire
 * @param vector - float ... ou float[3] - la composante vecteur
 */
private Quaternion(float w, float ...vector){
this.w = w;
x = vector[0];
y = vector[1];
z = vector[2];
}

/**
 * Construit un quaternion identite (pour multiplications)
 * 
> (w1, x=0, y=0, z=0).
 * @return Quaternion - le quaternion
 */
public static Quaternion buildIdentityQuaternion(){
return new Quaternion();
}

/**
 * Construit un quaternion a partir des 4 composantes
 * @param w - float - le composant scalaire
 * @param vector - float ... ou float[3] - composante vecteur
 * @return Quaternion - le quaternion
 */
public static Quaternion buildFromFourComponents(float w, float ...vector){
return new Quaternion(w, vector[0], vector[1], vector[2]);
}

/**
 * Construit un quaternion a partir d'un vecteur
 * 
> w  0
 * 
> et x  vecX, y = vecY, z = vecZ
 * @param vector - float ... ou float[3] - vecteur
 * @return Quaternion - le quaternion
 */
public static Quaternion buildFromVector(float ...vector){
return new Quaternion(0, vector[0], vector[1], vector[2]);
}

/**
 * Construit un quaternion a partir d'angles d'Euler (en Degres)
 * @param angleX - float - angle autour de l'axe x
 * @param angleY - float - angle autour de l'axe y
 * @param angleZ - float - angle autour de l'axe z
 */
public static Quaternion buildFromEulerAngles(float angleX, float angleY, float angleZ){
float angleXRad = (float) Math.toRadians(angleX);
float angleYRad = (float) Math.toRadians(angleY);
float angleZRad = (float) Math.toRadians(angleZ);

Quaternion mqx = Quaternion.buildFromFourComponents(angleXRad, 1, 0, 0);

Quaternion qy = Quaternion.buildFromVector(0,1,0);
qy = mqx.mulInLeftOf(qy).mulInLeftOf(mqx.conjugate());
Quaternion mqy = Quaternion.buildFromFourComponents(angleYRad, qy.getX(), qy.getY(), qy.getZ());

Quaternion qz = Quaternion.buildFromVector(0,0,1);
Quaternion qtmp = mqy.mulInLeftOf(mqx);
qz = qtmp.mulInLeftOf(qz).mulInLeftOf(qtmp.conjugate());
Quaternion mqz = Quaternion.buildFromFourComponents(angleZRad, qz.getX(), qz.getY(), qz.getZ());

return mqz.mulInLeftOf(mqy).mulInLeftOf(mqx);
}

/**
 * Retourne un nouveau quaternion comme le produit de q1 * q2
 * Attention !!! Aucun quaternion ne sera modifie.
 * @param q1 - Quaternion - quaternion gauche
 * @param q2 - Quaternion - quaternion droite
 * @return Quaternion : le produit q1 * q2.
 */
public static Quaternion mul(Quaternion q1, Quaternion q2){
return q1.mulInLeftOf(q2);
}

/**
 * Calcule autre * this.
 * Aucun quaternion n'est changé.
 * @param autre - l'autre quaternion.
 * @return Quaternion - autre * this
 */
public Quaternion mulInLeftOf(Quaternion autre){
return new Quaternion(
this.w * autre.w - this.x * autre.x - this.y * autre.y - this.z * autre.z,
this.w * autre.x + this.x * autre.w + this.y * autre.z - this.z * autre.y,
this.w * autre.y - this.x * autre.z + this.y * autre.w + this.z * autre.x,
this.w * autre.z + this.x * autre.y - this.y * autre.x + this.z * autre.w
);
}

/**
 * Retourne le quaternion normalisé : de sorte a ce que sa
 * longueur vaille 1.

 * Attention : le quaternion this n'est pas change.
 * @return Quaternion - quaternion normalise
 */
public Quaternion normalize(){
float norm = (float) Math.sqrt(w*w + x*x + y*y + z*z);
if (norm <= 0.001)
// Identity quaternion for multiplication
return new Quaternion(1, 0,0,0);
return new Quaternion(w/norm, x/norm, y/norm, z/norm);
}

/**
 * Retourne l'equivalent dans le modele "axis angle"
 * 
 * <li>axisAngle[0] contiendra l'angle en degres
 * <li>axisAngle[1 to 2] contiendra le vecteur (x,y,z)
 * 
 * @return float [4] - l'"axis angle" equivalent
 */
public float [] toAxisAngle(){
float axisAngle [] = new float[16];
float scale = (float) Math.sqrt(x*x + y*y + z*z);
float thetaRadians = (float) Math.toDegrees(2*Math.acos(w));
if (scale <= 0.001){
// if scale is 0, axis direction is not important
axisAngle[0] = thetaRadians;
axisAngle[1] =  x;
axisAngle[2] =  y;
axisAngle[3] =  z;
}
else {
axisAngle[0] = thetaRadians;
axisAngle[1] = (x/scale);
axisAngle[2] = (y/scale);
axisAngle[3] = (z/scale);
}
return axisAngle;
}

/**
 * Convertit le quaternion en matrice
 * @return float[16] - la matrice equivalente.
 */
public float[] toMatrix(){
float matrix[] = new float[16];
Quaternion q = normalize();

matrix[0] = (float) (1.0 - 2.0 * (q.y*q.y + q.z*q.z));
matrix[1] = (float) (2.0 * (q.x*q.y + q.w*q.z));
matrix[2] = (float) (2.0 * (q.x*q.z - q.w*q.y));
matrix[3] = 0;

matrix[4] = (float) (2.0 * (q.x*q.y - q.w*q.z));
matrix[5] = (float) (1.0 - 2.0 * (q.x*q.x + q.z*q.z));
matrix[6] = (float) (2.0 * (q.y*q.z + q.w*q.x));
matrix[7] = 0;

matrix[8] = (float) (2.0 * (q.x*q.z + q.w*q.y));
matrix[9] = (float) (2.0 * (q.y*q.z - q.w*q.x));
matrix[10] = (float) (1.0 - 2.0 * (q.x*q.x + q.y*q.y));
matrix[11] = 0;

matrix[12] = matrix[13] = matrix[14] = 0;
matrix[15] = 1;

return matrix;
}

/**
 * Retourne le conjugue du quaternion
 * 
>x-x, y=-y, z=-z
 * 
Attention, le quaternion this reste inchange !!!
 * @return Quaternion - le conjugue
 */
public Quaternion conjugate(){
return new Quaternion(w, -x, -y, -z);
}

/**
 * Reinitialise this en quaternion identite (pour multiplications)
 * => w = 1
 * => x = y = z = 0
 */
public void setIdentity() {
w = 1;
x y z = 0;
}

/**
 * Fixe les valeurs a partir d'un "axis angle"
 * @param angleDegrees - float - angle en degres
 * @param vector - float... ou float[3] - vector (x,y,z)
 */
public void setFromAxisAngle(float angleDegrees, float ...vector){
float norm = (float) Math.sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
if (norm < 0.01){
setIdentity(); 
}
else {
vector[0] /= norm;
vector[1] /= norm;
vector[2] /= norm;
double cosHalfTheta = Math.cos(Math.toRadians(angleDegrees)/2);
double sinHalfTheta = Math.sin(Math.toRadians(angleDegrees)/2);
w = (float) cosHalfTheta;
x = (float) (vector[0] * sinHalfTheta);
y = (float) (vector[1] * sinHalfTheta);
z = (float) (vector[2] * sinHalfTheta);
}
}



public float getW() {
return w;
}

public float getX() {
return x;
}

public float getY() {
return y;
}

public float getZ() {
return z;
}



private float w, x, y ,z;



}



Programmons oui, mais le plus proprement possible.
0
Utilisateur anonyme
21 juin 2011 à 22:13
J'ai un doute sur toMatrix() mais ça doit être parce que j'utilise une implémentation optimisée à ma sauce.






T.U.E.R yeah! vive java
0
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012
21 juin 2011 à 22:45
Salut,

la formule que j'utilise pour toMatrix() est normalement correcte, cela est du au fait que j'ai normalisé le quaternion (l'article que j'ai lu se base sur le fait que x carré + y carré + z carré + w carré = 1). Enfin, je pense que je ne me suis pas trompé.

Par contre, pour la méthode buildFromEulerAngles(), ai-je bien respecté (hormis les structures conditionnelles, que je pense peut-être réimplémenter, pour limiter le garbage collector notamment) ton algorithme ?

Enfin, pour les autres méthodes ... je pense que l'erreur ne peut pas survenir de là non plus.


Programmons oui, mais le plus proprement possible.
0
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012
23 juin 2011 à 14:46
Salut,

en ce qui concerne le déploiement en Jar, j'ai réussi ^^.
Il existe une classe GPLv2 appelée JarClassLoader qui simplifie la tâche : JarClassLoader

[list]
[*] J'ai d'abord ajouté la classe à mon projet et crée un lanceur d'application comme indiqué
[*] J'ai crée un RunnableJar toujours depuis Eclipse, en choisissant mon nouveau Lanceur et en choisissant l'option ajouté les librairies dans le jar
[*] J'ai supprimé le loader généré par Eclipse
[*] J'ai ajouté les librairies natives (Mac, linux et Windows) à la racine du Jar
/list

Et cela fonctionne sur le jar fonctionne bien à la fois sur Windows et Linux

Voilà peut-être une rubrique à ajouter dans mon futur tutoriel (je pense finalement le passer dans la section sources en tant que pdf).

Programmons oui, mais le plus proprement possible.
0
Utilisateur anonyme
23 juin 2011 à 21:12
Utiliser Java Web Start est quand même plus commode que de faire un gros JAR qui contient tout.












T.U.E.R yeah! vive java
0
Utilisateur anonyme
23 juin 2011 à 21:13
De plus, sous Windows, beaucoup de gens ont WinRar qui ouvrent par défaut les JARs donc utiliser un JAR auto-exécutable est une mauvaise idée. Un fichier JNLP ne pose pas ce problème.




T.U.E.R yeah! vive java
0
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012
24 juin 2011 à 08:28
Salut,

le problème que tu as évoqué pour les Jars n'en est pas un :
[list]
[*] Il suffit de demander d'ouvrir avec Java Runtime, par le menu contextuel
[*] Et en plus, il est possible de le configurer comme programme par défaut
/list

De plus, je ne sais pas si c'est vraiment un plus, l'utilisateur n'est plus effrayé par l'avertissement au lancement d'une application Java Web Start.


Sinon, je suis en train de me mettre à QTJambi 4.7.0, pour l'utiliser avec JOGL, mais je n'ai pas encore réussi à initialiser correctement mon contexte GL ... je dois encore travailler cela.

Programmons oui, mais le plus proprement possible.
0
Utilisateur anonyme
24 juin 2011 à 10:57
Bonjour

Le problème que j'évoque est suffisamment important pour que les développeurs de jeux vidéo en Java privilégient les applets, Java Web Start et divers installeurs mais surtout pas un simple JAR ou un ZIP. Quand Java est bien installé, avec un lien JNLP, ça lance Java Web Start sans possibilité de confusion, aucun programme ne prendra ton fichier JNLP pour un ZIP puisque ça n'en est pas un. Avec Java Web Start, l'utilisateur lambda qui n'y connait rien n'a pas à faire clic droit -> Ouvrir avec Sun Java. Il faut aller au plus simple sinon l'utilisateur laisse vite tomber.

Si ton JAR s'ouvre comme un ZIP lors d'un double clic, l'utilisateur lâche l'affaire. Pour l'avertissement au lancement de Java Web Start, tu peux régler ça en ayant un certificat payant, ça met un truc bleu plus rassurant, c'est ce que je conseille de faire quand l'application est vraiment finalisée, ça vaut le coup.

En gros, ton idée d'utiliser un JAR auto-exécutable pour tout lancer d'un double clic ne marchera bien que sur Mac et sur les rares postes Windows où ni WinZip ni WinRAR ni aucun décompresseur de ZIP ne va chercher à ouvrir ton JAR à la place de Java. Sur Linux, par défaut, souvent ça ouvre le JAR comme un ZIP ou bien ça te demande avec quoi l'ouvrir.

Si tu penses que je dis n'importe quoi, demande aux programmeurs sur javagaming.org.

Pour QtJambi, tu pourras demander de l'aide sur javagaming.org ou sur jogamp.org, quelques rares utilisateurs se servent de JOGL avec Qt en Java. Bon courage.





T.U.E.R yeah! vive java
0
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012
24 juin 2011 à 14:06
Je te fais confiance, mais je ne compte pas pour l'instant déployer en JavaWS, vu que j'y éprouve beaucoup plus de difficultés qu'en déployant en Jar. Donc pour l'instant : Jar, Bricolages et Système-D.

Finallement pour QTJambi, je vais abandonner : la version Windows est fournie sous forme d'exe, ce qui ne me permet pas d'en extraire les librairies natives ... et il n'y a même pas de version Mac => Je me tournerais vers SWT (j'ai déjà développer un plugin perso de code de couleurs HTML : rustique, mais suffisant pour s'y mettre). De plus, il me semble que le site offciel de JOGL explique déjà comment intégrer JOGL à SWT :)

Pour le quaternion, à défaut de réussir avec la méthode de ton professeur d'université, je vais au moins pour l'instant m'en tenir à la version classique ... car sinon je n'avancerais pas le projet, restant bloqué sur l'implémentation de cette version plus robuste de l'anti-gimbal-lock.

Enfin pour le tuto, je ne vais pas le publier maintenant : vu que je sais maintenant que j'ai au moins un possibilité d'exporter le projet pour tous les os (en attendant de m'en sortir avec la méthode plus sûre JAVAWS, qui ne me réussit toujours pas ...)

Voilà, je vous tiens au courant pour ces différents points.

Programmons oui, mais le plus proprement possible.
0
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012
24 juin 2011 à 14:09
Sinon, pour éviter de faire systématiquement du système-D : je me suis mis à ANT sous Eclipse pour essayer de construire le jar de manière propre, sans dépendre du Wizard d'Eclipse qui ne peut pas tout faire pour moi.

Avis à ceux qui s'y connaissent ... je suis en recherche d'aides :) (Les liens de Google sont toujours très techniques pour un débutant en ANT comme moi).

Programmons oui, mais le plus proprement possible.
0
Utilisateur anonyme
24 juin 2011 à 14:30
J'utilise déjà Ant sous Eclipse, l'exemple que je t'ai donné au tout début fait ce que tu cherches à faire, il est conçu pour marcher sur plusieurs IDE et en ligne de commande, j'ai mis à part la seule cible qui dépend d'Eclipse. Ce n'est pas du système D et tu sembles avoir compris que ça te donne plus de flexibilité.

Justement, Ant permet de signer facilement les JARs ce qui t'aidera à utiliser Java Web Start. Vas-y par étape et ça te semblera relativement simple.




T.U.E.R yeah! vive java
0
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012
24 juin 2011 à 16:38
Ok merci

(Pour l'instant j'arrive à définir une cible initialiser, et une cible compiler - y compris avec les paquetages -. C'est juste la cible executer qui ne fonctionne pas si je met mes sources dans un paquetage : problème de classpath je pense. Bref, je semble bien démarrer)

Programmons oui, mais le plus proprement possible.
0
Utilisateur anonyme
24 juin 2011 à 17:19
Prends exemple sur la cible "run-tuer" de mon fichier build.xml. Pense à passer les bonnes options à la machine virtuelle pour qu'elle trouve les JARs et les modules natifs. Tu dois donc paramétrer le class path ainsi que le java library path.

Utilise la balise <classpath> pour le class path et <jvmarg value="-Djava.library.path=${TON_CHEMIN}"/> pour les modules natifs.

<manifest> te permet de paramétrer le manifeste du JAR.
<genkey> permet de générer la clé.
<signjar> permet de signer le JAR.



T.U.E.R yeah! vive java
0
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012
24 juin 2011 à 18:05
Ok j'ai téléchargé le build.xml : je vais donc pouvoir tenir compte de tes conseils :)
0
cs_loloof64 Messages postés 342 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 6 novembre 2012
25 juin 2011 à 11:57
Juste pour savoir : est-on dans l'illégalité si l'on construit ses propres jars en intégrant des api tierces, et en les diffusant ensuite ? Parce que je pense procéder ainsi dans un premier temps.

J'ai bien avancé pour Ant : compilation + execution (que ce soit en mode jar ou simplement avec des *.class).

J'ai essayé de poster mon tuto sur le site : aucune méthode n'a fonctionné. Il faudra donc attendre davantage (pour ce qu'il vaut en plus ...)

Programmons oui, mais le plus proprement possible.
0
Utilisateur anonyme
25 juin 2011 à 13:59
Bonjour

Pour JOGL, tu n'auras pas besoin de faire ça. Tu as le droit de procéder ainsi en fonction de la licence utilisée. C'est interdit pour JMC par exemple, ça peut être interdit pour des bibliothèques soumises à des royalties comme OpenInventor, JCarnac/Pro, bref des trucs propriétaires pas très intéressants.

Ton tutoriel est sûrement trop gros. Parle de ton souci à Twinuts, il te donnera un coup de main. Cordialement.













T.U.E.R yeah! vive java
0
Rejoignez-nous