giovedì 30 luglio 2009

Configurazione di Apache Tomcat 6.x

* Incollare i sorgenti dell'applicazione Web in una cartella, ad esempio applicazione, e spostarla nella cartella webapps di Tomcat

* (facoltativo) Aggiungere le seguenti righe a tomcat-users.xml (in conf)





in modo da poter accedere al tomcat manager con l'utenza admin

* Nel file servers.xml (in conf) aggiungiamo la nostra applicazione:
unpackWARs="false"
xmlValidation="false"
xmlNamespaceAware="false"
autoDeploy="false"
deployOnStartup="false"
liveDeploy="false">





* Ora modifichiamo il DNS per inserire la nostra Webapp: modifichiamo il file c:\windows\system32\drivers\etc\hosts inserendo la riga

127.0.0.1 applicazione.app.it

* Avviamo tomcat da riga di comando: spostiamoci nella cartella bin e digitiamo startup.bat (se siamo in ambiente Windows)

* Richiamiamo la nostra applicazione nel browser digitando http://applicazione.app.it:8080

martedì 5 maggio 2009

Gestione di un acquisto PayPal

Creare innanzitutto da Sandbox (http://developer.paypal.com) un account Business ed uno Personal (personalmente ho preferito creare manualmente due utenti italiani, visto che nei preimpostati al momento non è possibile farlo), attivare email ed associare una carta di credito fittizia oppure un conto. Nell'utente Business, andare su profile->website payment preferences, attivare Auto-Return, inserire l'indirizzo di ritorno PDT (es.: http://pdt.php) e attivare Payment Data Transfer e segnarsi l'id.
Poi su profile -> Instant Payment Notification abilitare l'opzione ed inserire l'url che gestirà l'IPN (es: http://...../ipn.php).
Poi andare su merchant services e creare un bottone di acquisto e copiarne ed incollarne il codice in una pagina Web (es: payWithPayPal.php), aggiungendo se necessario un campo hidden chiamato "custom" e valorizzato con un valore di cui si vuole tenere traccia (max 255 caratteri). Questo è necessario se voglio per esempio salvare su database l'andamento della transazione se andata a buon fine ed associarla all'utente salvato in sessione: essendo fatte su ipn.php solo chiamate asincrone, l'istruzione $_SESSION non funziona come ci si aspetterebbe. Passandogli invece la variabile custom, posso riceverla comunque in ipn.php e farci tutte le operazioni che desidero.
Ecco i codici di esempio delle due pagine:

payWithPayPal.php











ipn.php


// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}


// post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

$sandbox = isset($_POST['test_ipn']) ? true : false;

if ($sandbox) {
$fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30);
} else {
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
}

// assign posted variables to local variables
$custom = $_POST['custom'];

if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {


if(isset($_POST['payment_status'])){
if ($_POST['payment_status']=="Completed"){
//mettere qui la logica di inserimento di dati nel db
}
}

}
}
fclose($fp);
}

?>




infine, ecco il codice della pagina se si vuole utilizzare pdt.php:


$tx = $_GET['tx'];

/*
Probabilmente è sufficiente usare PDT: qui la pagina capisce che proviene da paypal e quindi posso salvare
nel DB l'abbonamento che ha scelto l'utente
*/
/*
$refe=$_SERVER['HTTP_REFERER'];//Estraggo la pagina di provenienza del navigatore
$ip=$_SERVER['REMOTE_ADDR'];//Estraggo l'IP del navigatore
*/
?>
grazie per aver effettuato il pagamento. La transazione è stata completata e una ricevuta dell'acquisto è stata inviata al tuo indirizzo email. Per visualizzare i dettagli sulla transazione effettua l'accesso al tuo conto dall'indirizzo www.sandbox.paypal.com/it.



cmd:


ID transazione: ">


Token identità (quella che imposto attivando PDT sul sito del venditore):



venerdì 10 aprile 2009

Autenticazione su LDAP tramite Active Directory con richiesta parametri

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
public class LDAPTest
{
static class LDAP
{
static String ATTRIBUTE_FOR_USER = "sAMAccountName";
@SuppressWarnings("unchecked")
public Attributes authenticateUser(String username, String password, String _domain, String host, String dn)
{
String returnedAtts[] ={ "sn", "givenName", "mail" , "company" , "department" };
String searchFilter = "(&(objectClass=user)(" + ATTRIBUTE_FOR_USER + "=" + username + "))";
//Create the search controls
SearchControls searchCtls = new SearchControls();
searchCtls.setReturningAttributes(returnedAtts);
//Specify the search scope
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String searchBase = dn;
Hashtable environment = new Hashtable();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
//Using starndard Port, check your instalation
environment.put(Context.PROVIDER_URL, "ldap://" + host + ":389");
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.SECURITY_PRINCIPAL, username + "@" + _domain);
environment.put(Context.SECURITY_CREDENTIALS, password);
LdapContext ctxGC = null;
try
{
ctxGC = new InitialLdapContext(environment, null);
// Search for objects in the GC using the filter
NamingEnumeration answer = ctxGC.search(searchBase, searchFilter, searchCtls);
while (answer.hasMoreElements())
{
SearchResult sr = (SearchResult)answer.next();
Attributes attrs = sr.getAttributes();
if (attrs != null)
{
return attrs;
}
}
}
catch (NamingException e)
{
System.out.println("Just reporting error");
e.printStackTrace();
}
return null;
}
}
public static void main(String[] args) throws Exception
{

LDAP ldap = new LDAP();

String username = "user";
String password = "pwd";


Attributes att = ldap.authenticateUser(username, password, "dominio.estensione", "ip_addr", "DC=dominio,DC=estensione");
if (att == null)
{
System.out.println("Sorry your use is invalid or password incorrect");
}
else
{
String s = att.get("department").toString();
System.out.println("DEPARTMENT=" + s);

NamingEnumeration all = att.getAll();
int i = 1;
while(all.hasMore()){
System.out.println("ATTR "+i+" "+all.next().toString());
i++;
}

}
}
}

Autenticazione su LDAP tramite Active Directory

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

Hashtable env= new Hashtable(11);
env.put(Context.SECURITY_PRINCIPAL,"CN=kiran,OU=LinkedgeOU,DC=LINKEDGEDOMAIN"); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://:389");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
//username

env.put(Context.SECURITY_PRINCIPAL, );
//password
env.put(Context.SECURITY_CREDENTIALS, password);

try {
DirContext ctx = new InitialDirContext(env);
String[] sAttrIDs = new String[2];
Attributes attr = ctx.getAttributes("");
NamingEnumeration ids = attr.getIDs();
}
catch(NamingException e){
System.err.println("Problem getting attribute: " + e);
}

Configurazione log4j per tomcat

Scaricare il jar di log4j dal sito di Apache e includerlo nella webapp.

Scrivere il file di configurazione log4.properties, del tipo:

#LOGGER
log4j.rootCategory=DEBUG, APPENDER_CONSOLE, APPENDER_FILE

#APPENDER_OUT
log4j.appender.APPENDER_CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.APPENDER_CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.APPENDER_CONSOLE.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

#APPENDER_FILE
log4j.appender.APPENDER_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.APPENDER_FILE.File=c:/mioLog.log
log4j.appender.APPENDER_FILE.MaxFileSize=500KB
log4j.appender.APPENDER_FILE.MaxBackupIndex=10
log4j.appender.APPENDER_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.APPENDER_FILE.layout.ConversionPattern=%p %t %c - %m%n


in cui imposto i console e file appender per il livello di debug.

In http://logging.apache.org/log4j/1.2/manual.html è descritta la seguente configurazione
Imposto la servlet di inizializzazione di log4j:

package it.flavio.ldap;

import org.apache.log4j.PropertyConfigurator;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Log4jInit extends HttpServlet {

public
void init() {
String prefix = getServletContext().getRealPath("/");
String file = getInitParameter("log4j-init-file");
// if the log4j-init-file is not set, then no point in trying
if(file != null) {
//PropertyConfigurator.configure(prefix+file);
PropertyConfigurator.configure("c:\\log4j.properties");
}
}

public
void doGet(HttpServletRequest req, HttpServletResponse res) {
}
}



e quindi aggiungo a web.xml il seguente mapping per fare eseguire questa servlet all'inizio dell'applicazione:


<>
<> log4j-init< / servlet-name >
<>it.flavio.ldap< /servlet-class >

<>
<>log4j-init-file< /param-name >
<>WEB-INF/classes/log4j.lcf< /param-value >
< /init-param >

<>1< /load-on-startup >
< /servlet >



  
Ora le impostazioni per il logging sono configurate, per generare i file di log è sufficiente aggiungere la riga:

Logger log = Logger.getLogger(Log4jInit.class);

nelle classi in cui vogliamo fare logging coi metodi log.debug, log.error ecc..


giovedì 9 aprile 2009

JDBC SQL Server 2000

Per gestire JDBC con le librerie della Microsoft

Aggiungere al progetto i jar reperibili sul sito di microsoft:
msbase.jar
mssqlserver.jar
msutil.jar

try{
// caricamento della classe del driver
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
} catch(Exception E){
System.out.println(E.toString());
}
try{
Connection MyConn = DriverManager.getConnection("jdbc:microsoft:sqlserver://db_address:1433;databaseName=db_name;User=username;Password=password");
} catch(Exception E){
System.out.println(E.toString());
}




Per gestire invece con JTDS
Driver: net.sourceforge.jtds.jdbc.Driver
URL: jdbc:jtds:://[:][/][;=[;...]]

I jar necessari si trovano su sourceforge (http://jtds.sourceforge.net/ -> download)
Scompattare l'archivio, il jar si trova nella root e si chiama jtds.jar
Ho dovuto inoltre copiare il file \x86\SSO\ntlmauth.dll in [...]\jdk\jre\bin


venerdì 3 aprile 2009

Relazione many-to-many con attributi con Hibernate

Mappare una molti-a-molti semplice con Hibernate usando le annotations è un'operazione piuttosto immediata, le cose si complicano quando si vanno ad aggiungere proprietà aggiuntive a questa relazione. Seguendo il manuale "Java Persistence With Hibernate", ecco l'esempio della mappatura di una relazione molti-a-molti con attributi, realizzata esplicitando la join table messa in relazione uno-a-molti con entrambe le tabelle interessate. Le tabelle in questione sono "Utente" e "Movie", in relazione molti-a-molti e mappate dalla join table utente_movie.

Ecco il codice delle classi con cui è stata realizzata la mappatura:


UTENTE

package it.flavio.moltiamolti.model;

import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.springmodules.validation.bean.conf.loader.annotation.handler.Length;


/**
* Object mapping for hibernate-handled table: movie.
* @author autogenerated
*/

@Entity
@Table(name = "utente", catalog = "moltiamolti")
public class Utente implements Cloneable, Serializable {

/** Serial Version UID. */
private static final long serialVersionUID = -559009206L;

/** Use a WeakHashMap so entries will be garbage collected once all entities
referring to a saved hash are garbage collected themselves. */
private static final Map SAVED_HASHES =
Collections.synchronizedMap(new WeakHashMap());

/** hashCode temporary storage. */
private volatile Integer hashCode;
private Set utenteToMovies;

/** Field mapping. */
private String name;
/** Field mapping. */
private Long id = 0L; // init for hibernate bug workaround

/**
* Default constructor, mainly for hibernate use.
*/
public Utente() {
// Default constructor
}

/** Constructor taking a given ID.
* @param id to set
*/
public Utente(Long id) {
this.id = id;
}


/** Return the type of this class. Useful for when dealing with proxies.
* @return Defining class.
*/
@Transient
public Class getClassType() {
return Utente.class;
}


/**
* Return the value associated with the column: duration.
* @return A String object (this.duration)
*/
@Length(max=45)
@Column( length = 45 )
public String getName() {
return this.name;

}


/**
* Set the value related to the column: duration.
* @param duration the duration value you wish to set
*/
public void setName(final String name) {
this.name = name;
}

/**
* Return the value associated with the column: id.
* @return A Integer object (this.id)
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column( name = "utente" )
public Long getId() {
return this.id;

}



/**
* Set the value related to the column: id.
* @param id the id value you wish to set
*/
public void setId(final Long id) {
// If we've just been persisted and hashCode has been
// returned then make sure other entities with this
// ID return the already returned hash code
if ( (this.id == null || this.id == 0) &&
(id != null) &&
(this.hashCode != null) ) {
SAVED_HASHES.put( id, this.hashCode );
}
this.id = id;
}


@Column( nullable = false )
@OneToMany( mappedBy = "utente" )
public Set getUtenteToMovies() {
return utenteToMovies;
}

public void setUtenteToMovies(Set utenteToMovies) {
this.utenteToMovies = utenteToMovies;
}



/**
* Deep copy.
* @return cloned object
* @throws CloneNotSupportedException on error
*/
@Override
public Utente clone() throws CloneNotSupportedException {
super.clone(); // keep hierarchy
final Utente copy = new Utente();


copy.setName(this.getName());
copy.setId(this.getId());

return copy;
}


/** Provides toString implementation.
* @see java.lang.Object#toString()
* @return String representation of this class.
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer();

sb.append("duration: " + this.getName() + ", ");
sb.append("id: " + this.getId() + ", ");

return sb.toString();
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;


result = prime * result
+ ((name == null) ? 0 : name.hashCode());

result = prime * result
+ ((hashCode == null) ? 0 : hashCode.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());

return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Utente other = (Utente) obj;

if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;


if (hashCode == null) {
if (other.hashCode != null)
return false;
} else if (!hashCode.equals(other.hashCode))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;

return true;
}

}





MOVIE

package it.flavio.moltiamolti.model;

import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.springmodules.validation.bean.conf.loader.annotation.handler.Length;


/**
* Object mapping for hibernate-handled table: movie.
* @author autogenerated
*/

@Entity
@Table(name = "movie", catalog = "moltiamolti")
public class Movie implements Cloneable, Serializable {

/** Serial Version UID. */
private static final long serialVersionUID = -559009206L;

/** Use a WeakHashMap so entries will be garbage collected once all entities
referring to a saved hash are garbage collected themselves. */
private static final Map SAVED_HASHES =
Collections.synchronizedMap(new WeakHashMap());

/** hashCode temporary storage. */
private volatile Integer hashCode;
private Set utenteToMovies;



/** Field mapping. */
private String duration;
/** Field mapping. */
private Long id = 0L; // init for hibernate bug workaround

/**
* Default constructor, mainly for hibernate use.
*/
public Movie() {
// Default constructor
}

/** Constructor taking a given ID.
* @param id to set
*/
public Movie(Long id) {
this.id = id;
}


/** Return the type of this class. Useful for when dealing with proxies.
* @return Defining class.
*/
@Transient
public Class getClassType() {
return Movie.class;
}







/**
* Return the value associated with the column: duration.
* @return A String object (this.duration)
*/
@Length(max=45)
@Column( length = 45 )
public String getDuration() {
return this.duration;

}



/**
* Set the value related to the column: duration.
* @param duration the duration value you wish to set
*/
public void setDuration(final String duration) {
this.duration = duration;
}

/**
* Return the value associated with the column: id.
* @return A Integer object (this.id)
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column( name = "movie" )
public Long getId() {
return this.id;

}



/**
* Set the value related to the column: id.
* @param id the id value you wish to set
*/
public void setId(final Long id) {
// If we've just been persisted and hashCode has been
// returned then make sure other entities with this
// ID return the already returned hash code
if ( (this.id == null || this.id == 0) &&
(id != null) &&
(this.hashCode != null) ) {
SAVED_HASHES.put( id, this.hashCode );
}
this.id = id;
}



/**
* Return the value associated with the column: itemOrder.
* @return A Set<ItemOrder> object (this.itemOrder)
*/
@Column( nullable = false )
@OneToMany( mappedBy = "movie" )
public Set getUtenteToMovies() {
return utenteToMovies;
}

public void setUtenteToMovies(Set utenteToMovies) {
this.utenteToMovies = utenteToMovies;
}







/**
* Deep copy.
* @return cloned object
* @throws CloneNotSupportedException on error
*/
@Override
public Movie clone() throws CloneNotSupportedException {
super.clone(); // keep hierarchy
final Movie copy = new Movie();


copy.setDuration(this.getDuration());
copy.setId(this.getId());

return copy;
}


/** Provides toString implementation.
* @see java.lang.Object#toString()
* @return String representation of this class.
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer();

sb.append("duration: " + this.getDuration() + ", ");
sb.append("id: " + this.getId() + ", ");

return sb.toString();
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;


result = prime * result
+ ((duration == null) ? 0 : duration.hashCode());

result = prime * result
+ ((hashCode == null) ? 0 : hashCode.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());

return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Movie other = (Movie) obj;

if (duration == null) {
if (other.duration != null)
return false;
} else if (!duration.equals(other.duration))
return false;


if (hashCode == null) {
if (other.hashCode != null)
return false;
} else if (!hashCode.equals(other.hashCode))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;

return true;
}


}




UTENTETOMOVIE


package it.flavio.moltiamolti.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;


/**
* Object mapping for hibernate-handled table: movie.
* @author autogenerated
*/

@Entity
@Table(name = "utente_movie", catalog = "moltiamolti")
public class UtenteToMovie implements Cloneable, Serializable {

@Embeddable
public static class Id implements Serializable {
@Column(name = "movie_id")
private Long movieId;

@Column(name = "utente_id")
private Long utenteId;

public Id() {}
public Id(Long movieId, Long utenteId) {
this.movieId = movieId;
this.utenteId = utenteId;
}
public boolean equals(Object o) {
if (o != null && o instanceof Id) {
Id that = (Id)o;
return this.movieId.equals(that.movieId) &&
this.utenteId.equals(that.utenteId);
} else {
return false;
}
}
public int hashCode() {
return movieId.hashCode() + utenteId.hashCode();
}
}


@EmbeddedId
private Id id = new Id();

@ManyToOne
@JoinColumn(name="utente_id",
insertable = false,
updatable = false)
private Utente utente;

@ManyToOne
@JoinColumn(name="movie_id",
insertable = false,
updatable = false)
private Movie movie;



private String quantity;
@Column(name = "quantity" , length = 50)
public String getQuantiy(){
return this.quantity;
}

public void setQuantity(String quantity){
this.quantity = quantity;
}



public UtenteToMovie() {}
public UtenteToMovie( Movie movie,
Utente utente) {
// Set fields
//this.username = username;
this.movie = movie;
this.utente = utente;
// Set identifier values
this.id.movieId = movie.getId();
this.id.utenteId = utente.getId();
// Guarantee referential integrity
movie.getUtenteToMovies().add(this);
utente.getUtenteToMovies().add(this);
}




public Id getId() {
return id;
}
public void setId(Id id) {
this.id = id;
}
public Utente getUtente() {
return utente;
}
public void setUtente(Utente utente) {
this.utente = utente;
}
public Movie getMovie() {
return movie;
}
public void setMovie(Movie movie) {
this.movie = movie;
}


}

lunedì 17 novembre 2008

Problema scheda video SIS M760GX di Acer Aspire 5000 su Ubuntu Intrepid Ibex

Ho avuto un grande problema con i driver della scheda video indicata appena ho installato Ubuntu 8.10: i colori erano completamente sfasati e molti pixel "pulsavano". Senza modificare Xorg.conf, ho risolto aggiungendo la riga:

sisfb

al file /etc/modules

Dopo aver riavviato ed impostato la memoria video condivisa a 64Mb il problema pare risolto.

martedì 12 giugno 2007

Operazioni pianificate Ubuntu

Per eseguire operazioni pianificate in Ubuntu, procedere col seguente modo.
Se non esiste ancora alcuna operazione pianificata, con un editor di testo creare il file crontab nella cartella /var/spool/cron/crontabs/
La riga di comando per pianificare un'operazione ha la seguente struttura:

min h giornoMese mese giornoSettimana comando parametri

min: minuto in cui eseguire l'operazione (0-59)
h: ora (0-23)
giornoMese: giorno del mese (1-31)
mese: mese (1-12)
giornoSettimana: giorno della settimana (0-6, con domenica = 0)
comando: il comando da eseguire
paramteri: eventuali parametri. Questo campo è facoltativo.

Se per esempio si vuole pianificare l'esecuzione del file jmail.sh alle 15.58 di ogni giorno, si dovrà inserire nella riga:

58 15 * * * ./home/tostao/workspace/javaMail1/jmail.sh

(jmail.sh deve essere reso eseguibile tramite il comando chmod. Vedi post "Creazione di uno shell script per eseguire un JAR", tag JAR, Ubuntu).
Importante: l'ultima riga del file crontab DEVE esistere ed essere vuota!
Per concludere, ora bisogna associare il file crontab creato all'utente di Ubuntu.
Per fare ciò, andare nel terminale e digitare:

sudo crontab -u utente /var/spool/cron/crontabs/crontab

Per verificare che l'operazione è andata a buon fine, digitare crontab -l per vedere le righe contenute nel nostro file crontab.
Per editare tale file, si può lanciare il comando crontab -e , ma personalmente preferisco farlo aprendolo a mano con un editor di testo.
Dopo ogni modifica, è necessario riscrivere il comando scritto poco sopra per associare il crontab all'utente.

lunedì 11 giugno 2007

Creazione di uno shell script per eseguire un JAR

Ubuntu usa shell scripting, paragonabile ai file batch (.bat) di Windows ma molto più potente.
Per associare uno shell script (in genere salvato come .sh anche se l'estensione non è necessaria), aprire un editor di testo e impostare come prima riga:
#!/bin/bash
e in seguito le istruzioni desiderate (nel nostro caso: java -jar nomefile.jar)
Nella parte nomefile.jar è meglio inserire il percorso completo del file JAR per essere sempre sicuri di eseguire quel file, in particolare se si sta eseguendo il file .sh da un'applicazione esterna, come ad esempio crontab (strumento per eseguire operazioni pianificate in Ubuntu).
Salviamo il nostro file come scriptJAR.sh nella cartella del nostro file .jar
Ora bisogna rendere questo file eseguibile: per fare cioè andare nel terminale, spostarsi nella cartella del nostro scriptJAR.sh e digitare:
sudo chmod +x scriptJAR.sh
per rendere il nostro script eseguibile: basterà avviarlo per fare avviare il nostro file JAR.