mardi 28 septembre 2010

java : eclipse choisir la JVM

Lorsque l'on a plusieurs projets java, il est fréquent que ces derniers n'utilisent pas tous la même version de java ... Mais on souhaite néanmoins disposer du dernier eclipse et outils ...

Pour cela, il est possible de préciser dans le eclipse.ini, des paramètres de démarrage:

Comme pour choisir une VM différente de celle spécifiée dans le JAVA_HOME -vm :
pour choisir un workspace -data
ou encore pour obliger eclipse a rafraichir sa configuration (après une install sale d'un plugin)-clean


-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256M
plugins\org.eclipse.osgi_3.4.3.R34x_v20081215-1030.jar
-framework
plugins\org.eclipse.osgi_3.4.3.R34x_v20081215-1030.jar
-vm
C:\Program Files\Java\jre6\bin\javaw.exe
-vmargs D:\ArchCvs\V9
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms512m
-Xmx1024m
-XX:PermSize=128m
-XX:MaxPermSize=256m
-XX:+CMSPermGenSweepingEnabled
-XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled
-XX:+PrintGCDetails
-Xloggc:D:/eclipse/gc


lundi 27 septembre 2010

maven : compiler un projet Flex

Voici, un exemple de pom permettant de compiler un projet flex (swf). De plus, ce dernier ne nécessite pas d'installation du flex SDK.



<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>${project.parent.groupId}</groupId>
<artifactId>mon-appli-flex</artifactId>
<packaging>swf</packaging>
<version>${project.parent.version}</version>
<name>Mon Appli Flex Module</name>

<parent>
<groupId>com.enwoo</groupId>
<artifactId>boc</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<dependencies>
<dependency>
<groupId>flexlib</groupId>
<artifactId>flexlib</artifactId>
<version>2.5</version>
<type>swc</type>
</dependency>
<dependency>
<groupId>com.maboite</groupId>
<artifactId>CGFlexFwk</artifactId>
<version>1.0.71</version>
<type>swc</type>
</dependency>
<dependency>
<groupId>flexlib</groupId>
<artifactId>flexlib</artifactId>
<version>2.5</version>
<type>swc</type>
</dependency>
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>flex-framework</artifactId>
<version>3.5.0.12683</version>
<type>pom</type>
</dependency>
</dependencies>

<build>
<sourceDirectory>src/main/flex</sourceDirectory>
<plugins>
<plugin>
<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<version>3.3.0</version>
<extensions>true</extensions>
<configuration>
<sourceFile>mon-appliFlex.mxml</sourceFile>
<output>${basedir}/../mon-appli/appli-web/src/main/webapp/mon-appliFlex.swf</output>
<services>${basedir}/../mon-appli/appli-web/src/main/webapp/WEB-INF/flex/services-config.xml</services>
<contextRoot>/mon-appli</contextRoot>
<compiledLocales>
<locale>fr_FR</locale>
<locale>en_US</locale>
</compiledLocales>
<debug>${flex.debug}</debug>
<warnings>
<noConstructor>false</noConstructor>
</warnings>
</configuration>
<dependencies>
<dependency>
<groupId>com.adobe.flex</groupId>
<artifactId>compiler</artifactId>
<version>3.5.0.12683</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.adobe.flex.compiler</groupId>
<artifactId>asdoc</artifactId>
<version>3.5.0.12683</version>
<type>zip</type>
<classifier>template</classifier>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>

mercredi 22 septembre 2010

oracle : identification externe par le user Unix

Voici, un moyen simple de lancer des scripts SQL via des ksh sans avoir les mots de passe Oracle.

En fait, lors de la création de l'utilisateur, il est possible que le SGBD, en l’occurrence Oracle, délègue l'authentification au système d'exploitation.

Pour cela, il suffit de créer un user avec "identified externally". L'exemple suivant montre la création de l'utilisateur ENWOO.

Ce dernier pourra se logger sur Unix/Linux, et n'aura qu'a taper sous sqlplus (en mode silencieux) la commande "connect /"

$sqlplus /NOLOG
SQL>connect /


Voici un petit exemple de script:


#!/bin/ksh
ORACLE_SID=maBddOracle
# connection a oracle en mode silencieux
sqlplus -s /nolog 1>/dev/null << FIN
WHENEVER SQLERROR EXIT FAILURE;
# connection en deleguant l'authentification a l'OS
connect /
FIN
if [ $? != 0 ]
then
echo "Connexion impossible (${ORACLE})"
exit 1
fi



-- Create the user
create user ENWOO
identified externally
default tablespace TBSBOUSER
temporary tablespace TEMP
profile DEFAULT;
-- Grant/Revoke role privileges
grant tablespacedev to ENWOO;
grant tablespacesysconnect to ENWOO;
-- Grant/Revoke system privileges
grant unlimited tablespace to ENWOO;

unix / linux : trouver les process et sockets ouverts

Voici, une commande permettant de trouver les sockets et fichiers ouverts

Attention il est nécessaire de préciser le protocole ... il y a une différence d'affichage entre lsof -i et lsof -i tcp:7666 ... Dans le cas lsof -i, je ne voyais pas mon processus qui utilisait le port 7666 en tcp !!!

lsof -i tcp:7666

Voici plusieurs exemples :


lsof -i (tous services internet TCP/UDP)
lsof -i tcp (tous services TCP)
lsof -i udp (tous services UDP)
lsof -i tcp:80 (services TCP sur port 80)
lsof -i @56.85.68.98 (liaison internet de mon poste avec 56.85.68.98)



Permet de trouver tous les fichiers ouverts par l'utilisateur "toto" ou "500" et par le process 1234 ou 12345:

lsof -p 1234,12345 -u 500,toto

Voici une très bonne page

java : JPA rappels

Parfois en JPA, il peut être difficile de gérer certains cas, comme on aurait pu le faire en SQL classique. Pour cela, il existe les "natives query", qui vous donnent accès à l'ensemble des fonctionnalités du SQL.

un très bon article d'Oracle ...

Supposez, vous souhaitez faire la somme des commandes de "Tortuga Trading":

A noter, un exemple de jointure JPQL :


...
String sup_name ="Tortuga Trading";
BigDecimal sum = (List)em.createNativeQuery("SELECT SUM(p.price*l.quantity)
FROM orders o JOIN orderlineitems l ON o.pono=l.pono
JOIN products p ON l.prod_id=p.prod_id
JOIN suppliers s ON p.sup_id=s.sup_id WHERE sup_name =?1")
.setParameter(1, sup_name)
.getSingleResult();
out.println("The total cost of the ordered products supplied by Tortuga Trading: " + sum +"
");
...


Un second exemple :

...
Double max = (Double) em.createQuery("SELECT MAX(p.price) FROM PurchaseOrder
o JOIN o.orderLineItems l JOIN l.product p JOIN p.supplier s WHERE s.sup_name = 'Tortuga Trading'")
.getSingleResult();
out.println("The highest price for an ordered product supplied by Tortuga Trading: "+ max + "
");
...


Obtenir tous les résultats ou un seul résultat :


...
@PersistenceUnit
private EntityManagerFactory emf;
public void doGet(
...
EntityManager em = emf.createEntityManager();
PrintWriter out = response.getWriter();
List arr_cust = (List)em.createQuery("SELECT c FROM Customer c")
.getResultList();
out.println("List of all customers: "+"
");
Iterator i = arr_cust.iterator();
Customer cust;
while (i.hasNext()) {
cust = (Customer) i.next();
out.println(cust.getCust_id()+"
");
out.println(cust.getCust_name()+"
");
out.println(cust.getEmail()+"
");
out.println(cust.getPhone()+"
");
out.println("----------------" + "
");
}
...


...
Integer cust_id =2;
Customer cust = (Customer)em.createQuery("SELECT c FROM Customer c WHERE c.cust_id=:cust_id")
.setParameter("cust_id", cust_id)
.getSingleResult();
out.println("Customer with id "+cust.getCust_id()+" is: "+ cust.getCust_name()+"
");
...

lundi 20 septembre 2010

glassfish : creer une ressource jdbc

avec asadmin tout est simple, voici comment faire pour une base derby:


#!/bin/bash
GLASSFISH_HOME=/home/enwoo/projets/outils/glassfishv3
$GLASSFISH_HOME/bin/asadmin create-jdbc-connection-pool --host localhost --port 4848 --datasourceclassname=org.apache.derby.jdbc.ClientDataSource --restype=javax.sql.XADataSource --property="portNumber=1527:password=APP:user=APP:serverName=localhost:databaseName=sun-appserv-samples:connectionAttributes=;create\=true" sample_derby_pool

Flex : tests automatiques avec QTP (compilation QTP)

Tout d'abord, il est nécessaire de récupèrer les librairies Flex et bundles adéquates pour le sdk Flex (ici adobe explique tout)

Une fois, le flex sdk et les librairies, bundles installés, il faut ajouter les locales :

Se placer dans le FLEX_HOME/bin; et lancer les commandes suivantes (en fonction des langues désirées).


./copylocale en_US fr_FR
./copylocale en_US de_DE
./copylocale en_US it_IT
./copylocale en_US ja_JP
./copylocale en_US nl_NL


Voici, la tâche ANT.

<!-- =================================
target: flex.qtp.compile
================================= -->
<target name="flex.qtp.compile" description="permet la compilation avec QTP FLEX">
<echo>"FLEX_HOME = [${FLEX_HOME}]"</echo>
<property name="srcdir" location="${basedir}/../../mon-appli-flex"/>
<property name="webSrcDir" location="${basedir}/../orchestre-web"/>
<echo>"srcdir = [${srcdir}/src/main/flex/MonMainFlex.mxml]"</echo>
<echo>"webSrcDir = [${webSrcDir}/MonMainFlex.swf]"</echo>
<echo>[${webSrcDir}/WEB-INF/flex/services-config.xml]</echo>
<echo>[${FLEX_HOME}/frameworks/flex-config.xml]</echo>
<echo>[${FLEX_HOME}/frameworks]</echo>
<echo>[${QTP_HOME}/]</echo>
<echo>[${srcdir}/src/main/locales/{locale}]</echo>

<!-- compile .mxml into .swf -->
<echo>[${basedir}/../orchestre-web/WEB-INF/flex/services-config.xml]</echo>
<mxmlc file="${srcdir}/src/main/flex/MonMainFlex.mxml"
output="${webSrcDir}/MonMainFlex.swf"
context-root="monAppliFlex"
allow-source-path-overlap="true"
actionscript-file-encoding="UTF-8"
headless-server="true"
locale="fr_FR"
debug="false"
keep-generated-actionscript="false"
incremental="false"
compiler.services="${webSrcDir}/WEB-INF/flex/services-config.xml">

<!-- Get default compiler options. -->
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml" />
<!-- List of path elements that form the roots of ActionScript class hierarchies. -->
<source-path path-element="${FLEX_HOME}/frameworks" />
<source-path path-element="${srcdir}/src/main/locales/{locale}" />
<source-path path-element="${FLEX_HOME}/frameworks/projects/automation/bundles/{locale}/src" />
<!-- List of SWC files or directories that contain SWC files. -->
<compiler.library-path dir="${srcdir}" append="true">
<include name="libs/CGFlexFwk-1.0.71.swc" />
<include name="libs/flexlib.swc" />
<include name="src/main/locales" />
</compiler.library-path>
<compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
<include name="libs" />
<include name="../bundles/{locale}" />
</compiler.library-path>
<compiler.include-libraries dir="${QTP_HOME}/qtp" append="true">
<include name="automation.swc" />
<include name="automation_agent.swc" />
<include name="qtp.swc" />
</compiler.include-libraries>

<!-- definition du basename du bundle -->
<include-resource-bundles bundle="MonMainFlex.properties" />
</mxmlc>
</target>

dimanche 19 septembre 2010

java : derby , rappel ...

Comment utiliser la BDD derby:

1) une fois l'application installé, il est nécessaire de setter le DERBY_HOME .... que l'on peut placer dans le ./bashrc ...

export DERBY_HOME=/home/monUser/../javadb

2) Démarrer via un terminal, le serveur via ./startNetworkServer (ce dernier démarre sur le port 1527 par défaut)

monUser$././startNetworkServer

3) l'utilitaire ij est un équivalent de SQLplus, et vous permet de vous connecter rapidement

Attention, la première fois, il est nécessaire de se connecter à la base et de la créer en même temps.

./ij
ij>connect 'jdbc:derby://localhost:1527/vNotes;create=true';

mardi 14 septembre 2010

oracle : trouver un lock

Voici une requête qui trouve qui locke un objet


SELECT o.owner,
o.object_name,
o.object_type,
o.last_ddl_time,
o.status,
l.session_id,
l.oracle_username,
l.locked_mode
FROM dba_objects o, gv$locked_object l
WHERE o.object_id = l.object_id;



Voici la requête permettant de trouver les sessions sur la BDD

select * from v$session where username is not null order by /*logon_time,*/ sid

java : traitement long

Voici la conclusion d'une discussion sur les traitements longs.

En conclusion , une application externe avec une communication via JMS, ou via la BDD avec un scheduler de tache du type Quartz ... et des ejbs qui traite la logique applicative.

Si le problème est du à une grosse requête (genre un extract, ou génération de fichiers plats) , il faut envisager un script Shell appelant du PL/SQL directement.

A partir de java 5 et de java EE 6, il est possible de faire requêtes asynchrones.

grace a des EJB asynchrones, ou des ejb timer ...


Reading between the lines of your collective responses (thanks to all you who answered!), it sounds like the general recommendation is to manage the batch-processing application in some external Java wrapper application that can interact via JMS. Then we keep our internal system logic in MDBs.


So the pattern is an external Java app which responds to JMS "start batch" messages from inside our EJB system, and which sends JMS "status update" messages back into the system. Then we have (inside our EJB container) stateless session beans which handle the job-starting requests, and MDBs which handle the status update messages and which update our internal job tracking database tables. So the external app never touches the job tracking database, and only interacts via JMS; and the EJB server never directly touches the external app.


I guess on some level this is the way it would have to be, as the batch processing can't really be made part of the J2EE clustering/failover/etc. system. Oh well. I'm sorry to have to consider deploying and managing another whole application (it's nice to have the whole system inside the EJB container), but looks like it's a bullet we'll have to bite. At least JMS will enable us to keep a uniform communication structure in the system.


We're very intrigued by IBM's "asynchronous beans" research in Websphere, but we'll wait to tackle that until it's a bit more widely deployed.... (Google for "IBM asynchronous beans" -- we can really use that kind of capability, as it sounds perfect for this problem!)

java : exemple configuration log4j

un petit rappel sur les appenders :

Le logger et l'arborescence de classes associées, et la référence à son appender :
BATCH_HISTO_RET. A noter, qu'il n'y a pas d'additivité des loggers parents.


ce qui donne:


#23 - Batch historisation des retraitements
log4j.logger.fr.sncf.fret.bocorchestre.batch.reprise.impl.historisation.boc.retraitement=DEBUG, BATCH_HISTO_RET
log4j.additivity.fr.sncf.fret.bocorchestre.batch.reprise.impl.historisation.retraitement=false


L'appender associé au logger (avec du layout):


#23 - Batch d'historisation des retraitements
log4j.appender.BATCH_HISTO_RET=biz.minaret.log4j.DatedFileAppender
log4j.appender.BATCH_HISTO_RET.layout=org.apache.log4j.PatternLayout
log4j.appender.BATCH_HISTO_RET.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} - %m%n
log4j.appender.BATCH_HISTO_RET.Prefix=batch_historisation_Retraitement_
log4j.appender.BATCH_HISTO_RET.Suffix=.log
log4j.appender.BATCH_HISTO_RET.Directory=/devel/logs_batch/historisationRetraitement/

oracle : exemple d'utilisation des HINT

Utilisation de HINT ... sous oracle. Ce n'est pas conseillé, mais parfois ça améliore considérablement les perfs ...


SELECT /*+ FIRST_ROWS */ *
FROM (SELECT *
FROM uneTableDeCommade tv
WHERE tv.no_cmd >= 1841541
AND tv.vers > 0
AND EXISTS (
SELECT 1
FROM uneTableActionCommande ta
WHERE tv.no_cmd = ta.no_cmd
AND tv.vers = ta.vers
AND ta.id_action > 0
AND ta.dh_deb >=TO_DATE ('01/03/2010 00:00:00','dd/mm/yyyy/ hh24:mi:ss'))
ORDER BY tv.no_cmd ASC)
WHERE ROWNUM <= 1000;

lundi 13 septembre 2010

oracle : savoir si une instance tourne ou non

il suffit de lister les process unix et de recherche le process smon

ex:

ps -ef | grep smon

ou on peut utiliser la commande tnsping qui s'appuie sur le tnsname.ora.

tnsping monSidDeBDD

Attention, cependant, plusieurs instance de BDD peuvent tourner sur les même port, et mon expérience m'a montré que si une base tourne alors le tnsping renvoie OK !!!

Donc, il vaut mieux utiliser la commande ps et connaitre le nom de BDD ou le nom du script de lancement ...

En fait, d'après oracle, la seule méthode permettant de savoir si une BDD tourne et de s'y connecter en "SQL*PLUS".

Si il est possible de s'y connecter alors cela signifie propablement que le listener n'est pas lancé ....

Pour le savoir lancer la commande suivante :

lsnrctl status

ou sur le shell des listeners :

lsnrctl
lsnrctl> status listener_name


ou une autre commande ps :

ps -ef | grep tnslsnr

ici, un cours complet

vendredi 3 septembre 2010

sites utiles

Un super site pour se rappeler l'ensemble des commandes shell :

Kit de survie Linux

Trouver a quel jar appartient une classe

Trouver des veilles versions d'applications (genre shockwave, adobe flex, etc ...)"

Cours de SQL standard

java : prettyPrint

voici, une petite fonction pour afficher de jolie tableau :

ce qui donne par exemple, pour ce petit main :


public static void main(String[] args) {
// TODO Auto-generated method stub
String [] unSeul = {"6"};
String [] deux = {"6","3"};
String [] quatre = {"6","3","4","6"};

System.out.println("1 = " + prettyPrint(unSeul));
System.out.println("2 = " + prettyPrint(deux));
System.out.println("3 = " + prettyPrint(quatre));
}



Le résultat est le suivant :


1 = {6}
2 = {6,3}
3 = {6,3,4,6}



public String prettyPrint(String [] tab)
{
StringBuffer buffer = new StringBuffer("{");
if(tab != null)
{
int length = tab.length;
for(int i = 0; i < length; i++)
{
if((length > 2 && i != length - 1) || (length == 2 && i == 0))
{
buffer.append(tab[i] + ",");
}
else
{
buffer.append(tab[i]);
}
}
}
buffer.append("}");
return buffer.toString();
}

jeudi 2 septembre 2010

BDD : ORACLE : sqlloader

Un petit exemple de script utilisant "sqlloader" pour charger un fichier excel de données (au format csv), et son fichier de controle "ctl" :

Tout d'abord, le fichier ctl :

1) La commande Load Data (charge les données)


--////////////////////////////////
-- Insertion des enregistrements
--////////////////////////////////
LOAD DATA
TRUNCATE
PRESERVE BLANKS
INTO TABLE MATABLE
FIELDS TERMINATED BY '\;'
TRAILING NULLCOLS
(
ID_CMD,
ID_VERS,
OPT_CORRECTION,
IND_SUCCES_TRAITEMENT
)



function my_log
{
echo `date '+%d/%m/%Y %H:%M '`" "$1 >> $path_log/$fic_log
}

##############################
# Initialisation des path
##############################

if [ $# -ne 2 ]
then
echo 'usage : '$0' [login] [password]'
exit 1
fi

ORACONN=$1
ORAPWD=$2
path_log=`pwd`
fic_ldr=`basename $0|cut -f1 -d"."`_`date '+%Y%m%d_%H%M%S'`.ldr
fic_log=`basename $0|cut -f1 -d"."`_`date '+%Y%m%d_%H%M%S'`.log
fic_dis=`basename $0|cut -f1 -d"."`_`date '+%Y%m%d_%H%M%S'`.dis
fic_bad=`basename $0|cut -f1 -d"."`_`date '+%Y%m%d_%H%M%S'`.bad
FIC=extract_MATABLE.csv
CTL=maj_MATABLE.ctl

##############################
# On teste la connexion a Oracle
##############################
sqlplus -s /nolog 1>/dev/null << FIN
WHENEVER SQLERROR EXIT FAILURE;
connect $ORACONN/$ORAPWD
FIN
if [ $? != 0 ]
then
echo "Connexion impossible (${ORACLE})"
exit 1
fi

ls $FIC 1>/dev/null 2>/dev/null
if [ $? = 0 ]
then
#################################
# sqlloader du fichier
#################################
dos2unix $FIC $FIC 2>/dev/null
sqlldr ${ORACONN}/${ORAPWD} control=$CTL data=$FIC log=$path_log/$fic_ldr bad=$path_log/$fic_bad discard=$path_log/$fic_dis silent='(header, feedback)' direct=false errors=100000 skip=1
if [ $? -ne 0 ]
then
my_log "Début de la mise à jour de la table MATABLE"
my_log "Erreur lors du chargement du fichier"
my_log "Detail des traitements dans le $path_log/$fic_ldr"
my_log "Detail des lignes en erreur dans le $path_log/$fic_bad"
my_log "Fin de la mise à jour de la table MATABLE"
echo 'Erreur lors du chargement du fichier '$FIC
echo '=> voir le fichier de log dans '$path_log/$fic_ldr
exit 1
fi
#################################
# Traitement du fichier
#################################
else
echo 'Fichier absent'
my_log "Début de la mise à jour de la table MATABLE"
my_log "Fichier absent"
my_log "Fin de la mise à jour de la table MATABLE"