Bloc-Note Java
Gestion vidéo bas-niveau
Activation du mode "Full-screen"
gd.setFullScreenWindow(window);
window.requestFocus();
Résumé des configurations écran disponibles
public void dumpConfiguration()
{
for (int i = 0; i < ge.getScreenDevices().length; i++)
{
logger.info("Screen " + i);
logger.info(" - id: " + gd.getIDstring());
logger.info(" - type: " + gd.getType());
logger.info(" - accelerated Memory: " + gd.getAvailableAcceleratedMemory());
logger.info(" - class: " + gd.getClass());
logger.info(" - isDisplayChangeSupported: " + gd.isDisplayChangeSupported());
logger.info(" - isFullScreenSupported: " + gd.isFullScreenSupported());
for (int j = 0; j < gd.getDisplayModes().length; j++)
{
DisplayMode displayMode = gd.getDisplayModes()[j];
logger.info(" - " + displayMode.getWidth() + "x" + displayMode.getHeight() + "x" + displayMode.getBitDepth() + " " + displayMode.getRefreshRate() + " Hz");
}
System.
out.
println(gd.
getIDstring());
for (int j = 0; j < gd.getConfigurations().length; j++)
{
}
}
}
Utilisation de java3D
public static class CustomCanvas3D extends Canvas3D
{
{
super(gcIn);
}
public void postRender()
{
J3DGraphics2D g = getGraphics2D();
}
public static void render(J3DGraphics2D g)
{
try
{
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(in);
in.close();
g.drawImage(photo, 0, 0, null);
}
{
// TODO: handle exception
}
g.flush(true);
}
}
public Test3D
() throws ImageFormatException,
IOException
{
SimpleUniverse.getPreferredConfiguration();
Canvas3D canvas = new CustomCanvas3D(config);
add("Center", canvas);
SimpleUniverse universe = new SimpleUniverse(canvas);
universe.getViewingPlatform().setNominalViewingTransform();
setUndecorated(true);
setResizable(false);
setAlwaysOnTop(true);
setVisible(true);
setSize(640,480);
setVisible(true);
CustomCanvas3D.render(universe.getCanvas().getGraphics2D());
}
{
new Test3D();
}
Un redimensionnement propre d'icônes
J'ai essayé des tonnes de méthode pour redimensionner une image type "png" d'un classique 128x128 à 16x16, et quelle que soit la méthode utilisé (draw direct, transformation, etc...), c'est l'enfer. J'ai toujours obtenu une sorte de "nearest" vilain.
La seule méthode que j'ai trouvé est la suivante :
Image scaledImage
= image.
getScaledInstance(width, height,
Image.
SCALE_SMOOTH);
Graphics2D graphics
= scaledBuffer.
createGraphics();
graphics.drawImage(scaledImage, 0, 0, width, height, null);
graphics.dispose();
return scaledBuffer;
}
Envoi d'un post http avec cookied
PostMethod post = null;
try
{
String nutName
= xmlInvokation.
getAttribut("nut");
String methodName
= xmlInvokation.
getAttribut("method");
String channel
= xmlInvokation.
getAttribut("channel",
"nuts");
String host
= xmlInvokation.
getAttribut("host",
"localhost");
int port = xmlInvokation.getAttributAsInteger("port", 8080);
String url
= "http://" + host
+ ":" + port
+ "/" + channel
;
NutContainer.logger.info("Running invokation : " + url + "/"+nutName + "." + methodName);
post = new PostMethod(url);
String toString
= xmlInvokation.
toString().
replace("&",
"&");
if (LoggerUtilities.isDebug(NutContainer.logger))
NutContainer.logger.debug(url + " : " + toString);
RequestEntity entity = new StringRequestEntity(toString, "text/xml", "UTF-8");
post.setRequestEntity(entity);
HttpClient httpclient = new HttpClient();
HttpState state = httpclient.getState();
state.clearCookies();
if (NutContainer.getInstance().getCookies() != null)
state.addCookies(NutContainer.getInstance().getCookies());
int result = httpclient.executeMethod(post);
state = httpclient.getState();
Cookie[] cookies = state.getCookies();
if (cookies != null)
NutContainer.getInstance().setCookies(cookies);
// Display status code
if (LoggerUtilities.isDebug(NutContainer.logger))
{
NutContainer.logger.debug("Response status code: " + result);
NutContainer.logger.debug("Response body: ");
NutContainer.logger.debug(post.getResponseBodyAsString());
}
}
{
LoggerUtilities.severe(NutContainer.logger, e);
}
finally
{
if (post != null)
post.releaseConnection();
}
Ping en java
try
{
startSensoring();
if (!address.isReachable((int) getTimeOut()))
setAlert(new SensorAlert("Host not reachable"));
}
{
setAlert(new SensorAlert("Unknown host " + getUrl()));
}
{
throw new SensorException(e);
}
Création d'un buffer d'image volatile
protected void createBuffer(int width, int height)
{
if (volatileImage)
{
buffer = gc.createCompatibleVolatileImage(2, height);
int valid = ((VolatileImage) buffer).validate(gc);
if (valid == VolatileImage.IMAGE_INCOMPATIBLE)
{
buffer = null;
LoggerUtilities.severe(logger, "Unable to create volatile image, switching to bufferedImage");
}
((VolatileImage) buffer).setAccelerationPriority(1);
}
if (buffer == null)
}
Activation du pipe OpenGL
System.
setProperty("sun.java2d.opengl", StringUtilities.
firstUp(String.
valueOf(configuration
().
isOpenGl())));
Spécification du dossier des JNI
-Djava.library.path=./native/
Vérifications d'usage : NPTL
NPTL est une fonction ajoutée au kernel récent pour optimiser la gestion des threads. Avant, un thread était un processus, comme une application lancée séparement ou plus exactement s'était un fork. l'arrivée de NPTL a permis de gérer les threads de manière plus efficace. Pour se donner une idée, l'ouverture de 100 000 threads prenait quelques 15 minutes sur un i86 contre, avec NPTL, 2 secondes sur la même machine. Dans la mesure où java utilise massivement les threads, l'arrivée de NPTL a booster les performances de près de 30% sous Linux. Il est donc important de vérifier s'ils sont activés sur la machine qui va héberger une application Java.
Avant de se casser la tête, vérifions que les NPTL sont présent tout court sur cette distribution :
getconf GNU_LIBPTHREAD_VERSION
# qui me répond :
# NPTL 2.4
Parfait. La gestion des threads est conférée à la librairie libc. Hors il y a 3 libc différentes sur une distribution moderne. Une dans /lib, une dans /lib/tls et une encore dans /lib/i686.. Pour connaître ce que supporte une de ses librairies, l'astuce consiste à les rendre exécutables et de les lancer.. En tant que root évidement :
chmod +x /lib/libc-2.3.5.so
/lib/libc-2.3.5.so
Ici, j'obtiens (entre autre) la ligne suivante :
linuxthreads-0.10 by Xavier Leroy
Pas de NPTL donc.. On continue sur les autres, même manipulation donc pour /lib/tls/libc-2.3.5.so j'obtiens :
Native POSIX Threads Library by Ulrich Drepper et al
Parfait, la librairie à utiliser est donc celle de /lib/tls. Maintenant pour savoir dans quel ordre sont lynkées ses librairies :
ldconfig -p | grep "libc"
# Ce qui me donne :
# libc.so.6 (libc6, hwcap: 0x8000000000000000, OS ABI: Linux 2.6.9) => /lib/tls/libc.so.6
# libc.so.6 (libc6, hwcap: 0x8000000000000, OS ABI: Linux 2.4.1) => /lib/i686/libc.so.6
# libc.so.6 (libc6, OS ABI: Linux 2.2.5) => /lib/libc.so.6
C'est positif, maintenant cherchons à savoir à quelle librairie fait appel java :
ldd /usr/java/jdk/jre/bin/java | grep libc
# cela donne :
# libc.so.6 => /lib/tls/libc.so.6 (0xb7de5000)
Parfait, java utilise bien la bonne librairie. On peut passer à la suite
Librairies utiles
Conversion de dates en multi-threads
L'objet SimpleDateFormat n'est pas threadsafe... Et le résulat est très étrange, cela peut donner une erreur du type java.lang.NumberFormatException: multiple points, et ce depuis le JDK1.4 jusqu'au 1.6. La solution, chynchroniser sur l'objet :
synchronized (dateFormat) {
return dateFormat.parse(value);
}
IllegalMonitorStateException
Un grand classique... Imaginons que nous voulions attendre dans notre thread qu'un événement se produise ailleurs. Cela donne quelque chose du genre :
class bidule {
this.valeur = valeur;
this.notify();
}
this.wait();
return valeur;
}
}
Dans un thread on va donc avoir un maValeur = bidule.lireValeur() qui va bloquer jusqu'à ce qu'un autre thread fasse un bidule.ecrireValeur(...). Et au lancement, padaboum, on se prend un bon vieux IllegalMonitorStateException sur le wait. La solution est aussi simple à mettre en oeuvre qu'à comprendre. En effet, que se passerait-il avec ce code si plusieurs threads appelaient la méthode lireValeur ? Benoîtement on se dit "il sont tous en attente". Manque de pot, Java ne sait pas faire cela car le "Wait" est lié à un et un seul thread. Donc si le but recherché est est d'avoir plusieurs thread appelant, il faut passer par une autre solution. Maintenant si lireValeur est appelé par un seul thread, il faut que cette méthode soit déclarée dans ce sens. Il suffit donc d'ajouter un synchronized dans la déclaration de la méthode pour régler notre problème. En rajouter un dans écrireValeur ne ferait pas de mal non plus ceci dit.
En somme, la régle, c'est que wait ne peut avoir lieu que dans un block synchronizé.
Crash entre Swing et Xinerama
Si au lancement de Swing vous obtenez une horreur du genre
Locking assertion failure. Backtrace:
#0 /usr/lib/libxcb-xlib.so.0 [0xb7cca767]
#1 /usr/lib/libxcb-xlib.so.0(xcb_xlib_unlock+0x31) [0xb7cca8b1]
#2 /usr/lib/libX11.so.6(_XReply+0xfd) [0xab708a8d]
#3 /opt/java/jre/lib/i386/xawt/libmawt.so [0xab81864e]
#4 /opt/java/jre/lib/i386/xawt/libmawt.so [0xab7f6f97]
#5 /opt/java/jre/lib/i386/xawt/libmawt.so [0xab7f7248]
#6 /opt/java/jre/lib/i386/xawt/libmawt.so(Java_sun_awt_X11GraphicsEnvironment_initDisplay+0x2f) [0xab7f754f]
#7 [0xb5c9366e]
#8 [0xb5c8bedd]
#9 [0xb5c8bedd]
#10 [0xb5c89243]
#11 /opt/java/jre/lib/i386/client/libjvm.so [0x620bc6d]
#12 /opt/java/jre/lib/i386/client/libjvm.so [0x630a828]
#13 /opt/java/jre/lib/i386/client/libjvm.so [0x620bb00]
#14 /opt/java/jre/lib/i386/client/libjvm.so(JVM_DoPrivileged+0x34b) [0x62619bb]
#15 /opt/java/jre/lib/i386/libjava.so(Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2+0x3d) [0xb7ca496d]
#16 [0xb5c9366e]
#17 [0xb5c8bd77]
#18 [0xb5c89243]
#19 /opt/java/jre/lib/i386/client/libjvm.so [0x620bc6d]
Locking assertion failure. Backtrace:
#0 /usr/lib/libxcb-xlib.so.0 [0xb7cca767]
#1 /usr/lib/libxcb-xlib.so.0(xcb_xlib_lock+0x2e) [0xb7cca81e]
#2 /usr/lib/libX11.so.6 [0xab707e08]
#3 /usr/lib/libX11.so.6(XGetVisualInfo+0x26) [0xab6feb76]
#4 /opt/java/jre/lib/i386/xawt/libmawt.so [0xab7f6249]
#5 /opt/java/jre/lib/i386/xawt/libmawt.so [0xab7f6495]
#6 /opt/java/jre/lib/i386/xawt/libmawt.so [0xab7f72f9]
#7 /opt/java/jre/lib/i386/xawt/libmawt.so(Java_sun_awt_X11GraphicsEnvironment_initDisplay+0x2f) [0xab7f754f]
#8 [0xb5c9366e]
#9 [0xb5c8bedd]
#10 [0xb5c8bedd]
#11 [0xb5c89243]
#12 /opt/java/jre/lib/i386/client/libjvm.so [0x620bc6d]
#13 /opt/java/jre/lib/i386/client/libjvm.so [0x630a828]
#14 /opt/java/jre/lib/i386/client/libjvm.so [0x620bb00]
#15 /opt/java/jre/lib/i386/client/libjvm.so(JVM_DoPrivileged+0x34b) [0x62619bb]
#16 /opt/java/jre/lib/i386/libjava.so(Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2+0x3d) [0xb7ca496d]
#17 [0xb5c9366e]
#18 [0xb5c8bd77]
#19 [0xb5c89243]
Cela viendrait du fait qu'AWT ait été compilé en statique avec X11. La solution est un patch sauvage de Java :
sed -i 's/XINERAMA/FAKEEXTN/g' /usr/local/java/jdk1.6.0_04/jre/lib/i386/xawt/libmawt.so
Look and feel Swing natif
try {
Traces.severe(logger, e);
}
Poster un nouveau commentaire