Archivo

Archivo para la categoría ‘ruby’

Usando Visualvm en StupidZombie con Eclipse y OSX: Resultados mixtos

Jueves, 11 de junio de 2009
StupidZombie memory profile - ping

StupidZombie memory profile - ping

Hoy me decidí a probar VisualVM de Sun (O debería decir Oracle). Bajarselo del sitio web es un paseo y la instalación es trivial (descomprimir, correr y ya). La aplicación a la cual estudié no es más que StupidZombie.

(Si usted tiene Windows entonces quizas no necesite bajarselo ya que viene con la última máquina virtual de Java de Sun).

Correr VisualVM es bastante sencillo, sólo tuve que:

  1. Ejecutar a StupidZombie
  2. Ejecutar a VisualVM (haciendo click en su icono en el directorio bin en donde quedó instalado).

Lo primero que hice fué ver cuanta memoria se estaba comiendo StupidZombie; Una aplicación tan sencilla debería ser liviana y me encontré con que usa sólo 20MB en OSX (Una ridiculez considerando lo que pesan ciertas aplicaciones hoy en día). Sin embargo me soprendió ver que cuando StupidZombie hay más de 5000 mil clases de Java en memoria, (¿porqué tanta basura?).

Esto me hace pensar que es hora de poner a dieta a la aplicación; Por ello me decidí hacer un perfil del uso de memoria (memory profile) y lo dejé corriendo un rato mientras hacia Pings a varios directorios y escribia etiquetas con el generador de etiquetas automático:

StupidZombie and VisualVM

StupidZombie and VisualVM

Mucha creación de arreglos de caracteres. No es soprendente ya que StupidZombie hace mucho “procesamiento” de cadenas de texto, proveniente de los directorios. Sin embargo me gustaría como se porta si lo corro paso a paso desde Eclipse (en mi caso no utilizo NetBeans donde la integración es más natural).

¿Y que sabemos del uso del procesador (CPU)? Bueno, siempre que intentaba cambiar a ese modo la aplicación corria bien un rato y luego se moria, dejandome a un proceso zombie en la máquina (que ironia StupidZombie es ahora un verdadero Zombie :) ):

Nunca pude medir el desempeño del procesador

Nunca pude medir el desempeño del procesador

Por ahora mi opinión de la herramienta es mixta. Si bien es genial que la máquina virtual de Java venga una herramienta de este calibre es también decepcionante que no se pueda medir el desempeño del procesador en OSX.

¿Pero es justa la comparación? Es decir, ¿como se mide en OSX con otras herramientas similares?

Bueno, yo tengo buenas experiencias en mi trabajo con YourKit. Resulta que ellos ofrecen una licencia OpenSource (aunque también tienen una licencia de evaluación de 15 días), así que también me baje esta versión de la herramienta y la probé (primero claro, hubo que hacer ciertos pasos en OSX antes de poder utilizar la herramienta, nada del otro mundo):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
auyan:bin josevnz$ export DYLD_LIBRARY_PATH=/Users/josevnz/Desktop/YourKit_Java_Profiler_8.0.9.app/bin/mac:$DYLD_LIBRARY_PATH
auyan:bin josevnz$ java -agentlib:yjpagent=helpYourKit Java Profiler 8.0.9 JVMTI agent usage: -agentlib:yjpagent=[help]|[option, ...]
 
Option             Description
------------------ ----------------------------------------
port=value       port to listen on (1-65535, by default any free port is chosen)
listen=ip:port same as 'port', but bind agent socket to particular IP only
onlylocal          allow only local connections to profiled application
dir=custom dir   directory where snapshots are created (by default $user home/Snapshots)
telemetrylimit=$n limit telemetry buffer capacity to N hours (approximately)
sampling           startup with CPU sampling
tracing            startup with CPU tracing
                   (cannot be used together with 'disablecounts')
noj2ee             do not perform J2EE high level profiling
                   (use only in combination with 'sampling' or 'tracing')
alloceach=$n      startup with object allocation recording: record each N-th allocation;
                   can be used together with 'allocsizelimit';
                   cannot be used together with 'disablealloc'
allocsizelimit=$b startup with object allocation recording: record objects with size >= B bytes
                   can be used together with 'alloceach';
                   cannot be used together with 'disablealloc'
monitors           startup with monitor usage profiling
usedmem=$percent  capture memory snapshot automatically when used heap memory
                   reaches the threshold
onexit=memory      always capture memory snapshot on exit
onexit=snapshot    always capture performance snapshot on exit (i.e. without heap)
disablealloc       do not instrument bytecode for object allocation recording
disablecounts      do not instrument bytecode for CPU tracing
disablej2ee        do not instrument bytecode for J2EE profiling
disablestacktelemetry
                   do not collect thread stack and status information
quiet              suppress diagnostic messages
 
Please find detailed description in the Help section "Startup options":
http://www.yourkit.com/docs/80/help/additional_agent_options.jsp
 
Examples:
java -agentlib:yjpagent FooClass
java -agentlib:yjpagent=alloceach=10,allocsizelimit=1000000,dir=c:\MySnapshots FooClass
java -agentlib:yjpagent=usedmem=70 FooClass

Bueno, funciona. Ahora corremos a StupidZombie con las opciones de YourKit y la cosa se ve más o menos así:

YourKit profiling StupidZombie

YourKit profiling StupidZombie

1
2
3
4
5
6
auyan:bin josevnz$ java -agentlib:yjpagent -jar ~/Documents/stupidzombie/kenai/dist/StupidZombie.jar 
[YourKit Java Profiler 8.0.9] JVMTI version 3001016a; 1.6.0_07-b06-57; Apple Inc.; mixed mode, sharing; Mac OS X; 64-bit JVM
[YourKit Java Profiler 8.0.9] Profiler agent is listening on port 10001...
[YourKit Java Profiler 8.0.9] *** HINT ***: To get profiling results, connect to the application from the profiler UI
Jun 11, 2009 11:15:24 PM com.stupidzombie.gui.StupidZombieGui main
INFO: Starting...

Hice un montón de pruebas y debo decir que YourKit es una opción mucho más madura que VisualVM. Solo me queda ver si la gente de YourKit me dá una licencia OpenSource para seguirla utilizando en StupidZombie por más de 15 días.

¿Y ustedes, que utilizan para medir el desempeño de sus aplicaciones?

comics, internet, java, kodegeek, linux, opensource, programación, ruby , , ,

Resumen de CommunityEastOne Dia 1

Miércoles, 18 de marzo de 2009

Es una de las pocas excepciones en las cuales sólo puedo decir que no sé por donde empezar. ¡WOW!; Este año me decidí a tomar videos sobre mis experiencias en vez de tomar fotos, al mismo tiempo que escribía casi en tiempo real sobre la conferencia en Facebook, Twitter y el blog. Debo decir que es la primera vez que me quedo sin baterías por andar jodiendo la paciencia ;)

El énfasis de la conferencia fué Cloud Computing; Sun definitivamente está apostando a que este va a ser el siguiente gran boom (junto con otras compañías como Amazon.com) y durante el evento mostraron muchas de sus herramientas de desarrollo, administración y virtualización (en el video pueden ver a David Douglas, Senior Vice President, Cloud Computing and Developer Plarforms quien abrió el evento.):

Me encanto ver compañias como ZAmanda, las cuales han llevado el famoso programa de backup Amanda al mundo enpresarial y ahora también soportan el paradigma de respaldos en Cloud Computing.

No pude ir a todas las charlas (si quieren ver los videos revizen mi grupo en Flickr); Por razones de tiempo tuve que escoger entre las que más me interesaban, así que aquí les doy un pequeño resumen:

Moving Forward: High-Performance Application Development in a Multicore World: Michael Marden, de AMD junto con Patrick Leonard (Rogue Wave), David Maples (Allinea Software) y Duncan Mc Callum (Cilk Arts) se encargaron de explicar las últimas tendencias en cuanto al uso de procesadores multicore y como nos afecta a los desarrolladores.

Si bien no hubo demostraciones de productos ni código estuvo interesante en cuanto a las explicaciones de los problemas actuales y sus posibles soluciones. Pero eso si, preparese para ver más cores por procesador (hasta 48 en dos años) y siga el siguiente consejo: Si no tiene que utilizar multithreading entonces no lo haga :)

Les recomiendo el sitio de desarrolladores de AMD el cual tiene varios documentos y herramientas al respecto de este tema.

Sigo con la descripción, no hay más vídeos porque mi camara se quedó sin baterías :(


Cloud Computing for the Enterprise Software Developers:
Aburridisima, sólo mostraron herramientas y la teoría detrás del funcionamiento de la plataforma que mostraron fué floja. Parecía más un “informercial” que otra cosa. Perdí una hora de mi vida allí :(

Beyond Impossible: How Jruby Evolved the Java Platform
: La mejor charla del día en mi opinión. El trabajo que el desarrollador Charles Nutter de Sun y sus compañeros hicieron con JRuby es admirable. No sólo reprodujeron a C Ruby en Java, sino que en el proceso le agregaron más funcionalidad a la máquina virtual de Java (versión 7). Nos demostraron como JRuby es más rápido que C Ruby 1.9 en varios demos (uno de fractales en particular), además de las historias heroicas de ciertos desarrolladores, ¡como el que portó la librería de expresiones regulares en C de Ruby (JAnigurama) en sólo un mes!

Yo pregunté cual es la estrategia de Sun a largo plazo con todos estos lenguajes; La respuesta es soportar a aquellos que tengan las comunidades más grandes, pero en teoría todos los lenguajes. Este es el legado de Java, aunque el lenguaje muera este va a seguir con implementaciones de otros lenguajes en la máquina virtual.

Si quiere saber más sobre Jruby y el progreso de otros lenguajes dinamicos en la máquina virtual de Java (como Jython, Groovy, Scala) entonces visite el blog de Chales Nutter

Building an Atom-Enabled, Map-Driven, Location-Aware, Web-Centric Mobile Application with POJOs and Android: Verga, leer el titulo cansa imagine escribirlo ;) . Sin embargo la charla estuvo super interesante ya que el autor (Tim Bray, un experto en Cloud Computing) nos mostró una aplicación que escribió para Android en sólo 4 días (el programa, llamado storyteller, permite guardar historias en el telefono, haciendo anotaciones de texto y voz).

Datos curiosos de esta charla:

  • Microsoft es el jugador más debil del mercado móvil, con sólo %3 de todo la torta. Symbian es el mostruo con más de %27
  • Pese a la recesión mundial y a que menos usuarios compraron celulares el trimestre pasado comparado con el 2007, el mercado creció en un %5. ¡Carajo, este es el único mercado a prueba de recesión en el mundo!
  • El Java de Android no es realmente Java. Por ejemplo, este no puede correr JRuby. Por otro lado, tener root shell en el telefono de desarrollador simplemente no tiene precio :) )
  • Mientras probaba la aplicación, el programa se fué a un sitio que tenía la palabra “f*ck” en todos los colores y tamaños. Tim lo manejó muy bien diciendo que nunca nos ibamos a olvidar de su charla :)

Fué interesante ver como funciona el modelo de programación de aplicaciones en Android (les recomiendo el blog androiddiary.com para más detalles)

Building a Twitter Analisys Tool from Scratch Using PHP, MySQL, Yahoo UI and Netbeans: Eso es lo que yo llamo una demostración en caliente. Justin Bolter, de Sun, se lanzó de cabeza y escribió esa aplicación de memoria en una hora. Paso a paso demostró un dominio increíble de Netbeans (y sus capacidades) y al final nos dejó loco con un programa que mostraba los twitters (y sus detalles) usando un motor de búsqueda el cual guardaba sus datos en MySQL. Demasiado bueno.

JavaFX: The New Platform for Rich Internet Applications: Fué decepcionante ya que Chuk-Munn Lee de Sun sólo leyó la presentación sin detenerse mucho en los ejemplos con código (y Dios, si habia código). Pudo haber sido mejor aunque se nota que Lee sabia de lo que estaba hablando.

En general hubo muchos participantes de otros países (yo conté un viaje de gente de Japón, Alemania y Rusia por ejemplo. Sólo conté dos hispanos, yo y un Mejicano) y aproveche para preguntar sobre algunas cosas interesantes:

  • La adquisión de SUN por parte de IBM: Nadie quiso hablar de eso. Sin embargo el precio de SUN subió hoy de $4 a $8 :)
  • Open Storage:Mi grupo tiene un apetito inmenso por almacenamiento y Sun procalama que sus Storage Servers 7000 cuestan %75 menos que la competencia ya que estan basados en Open Solaris, y utilizan componentes comunes (han estado en venta desde Noviembre del año pasado, estoy averiguando a ver que tal)
  • Sun está alejandose de Java.net y en cambio está proponiendo una nueva plataforma, la cual va a soportar Cloud Computing: Kenai.com. Por haber asistido al evento y por tener un proyecto en java.net me dieron una cuenta, ya les contaré como me fué con esta nueva iniciativa de SUN en el mundo OpenSource la cual compite con SourceForge
  • Bueno, mañana me toca el dia 2 del evento, llamado “Deep Dive“. Son los tutoriales pagos en tecnologías OpenSource, me voy a lanzar un curso completo de un día sobre MySQL. Ya les comentaré como me fué ;)

Veneblogs: , , , , , , , , , , , ,

Blogalaxia: , , , , , , , , , , , ,

To2blogs: , , , , , , , , , , , ,

Technorati: , , , , , , , , , , , ,

Del.icio.us: , , , , , , , , , , , ,

comics, java, kodegeek, linux, opensource, programación, ruby , , , , , , , , , , , , ,

Escribiendo desde CommunityOne

Miércoles, 18 de marzo de 2009

Bueno, ya estoy en el Marriot. Tratare de escribir Durante el Dia de hoy, sin embargo siganme en twitter para actualizaciones en tiempo real: http://twitter.com/josevnz

java, kodegeek, linux, opensource, ruby , ,

Mañana es Sun CommunityOne East

Martes, 17 de marzo de 2009

Bueno, ya quedan sólo horas para el Sun CommunityOne East. Yo ando imprimiendo mis entradas, preparando mi camara y sobre todo abriendo el cerebro para todo lo que voy a aprender el día de mañana.

Ya les contaré como me fué, esten pendientes por este espacio. También puede seguir el progreso del evento en Twitter y Facebook.

Blogalaxia: , , , ,

To2blogs: , , , ,

Technorati: , , , ,

Del.icio.us: , , , ,

java, linux, opensource, programación, ruby , , ,

Construyendo un servidor de logs usando Netcat, tail y Bash

Sábado, 14 de marzo de 2009

Me toco entre estos días escribir un hack (no por lo malo sino por lo rápido que tenia que hacerlo) un servidor que debía proporcional el contenido de una bitacora la cual crece de manera continua durante el día. El grupo que nos pidio esto es de auditoria, lo cual implica que no debe perderse información.

Primero les muestro el código del programa y explico como funciona:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash
# author: josevnz@kodegeek.com
#
set -o monitor
declare -a pids
declare -r SCRIPT=${0##*/}
declare -r FIFO="/tmp/$SCRIPT-$$.fifo"
 
if [ -z "$1" ]; then
        echo "Please provide the file to tail and try again"
        exit 192
fi
 
if [ -z "$2" ]; then
        echo "Please provide port and try again"
        exit 192
fi
 
trap cleanup exit INT TERM
 
if [ ! -e "$FIFO" ]; then
        mkfifo "$FIFO"
        if [ $? != 0 ]; then
                exit $?
        fi
fi
 
tail -F "$1" > "$FIFO" &
trap "test -e $FIFO && rm -f $FIFO" exit INT TERM
while true; do
        test -e "$FIFO" && netcat -v -v -v -l -p $2 < "$FIFO"
done
trap "kill -9 $! $$" exit INT TERM

La idea es revisar los contenidos del archivo usando ‘tail -F’. La opción ‘-F’ le dice a tail que reintente si tiene problemas eyendo el archivo; De allí redirigimos los contenidos a una cola (FIFO, first in first out) en Unix la cual garantiza que aunque el servidor TCP muera los datos estaran allí listos para ser enviados al cliente. Dejamos a tail corriendo en segundo plano…

El siguiente paso es arrancar nuestro servidor TCP. Netcat recibe los contenidos de la cola que creamos en el paso anterior. Fijense como lo encerramos en un ciclo infinito ya que si el cliente se muere (o desconecta por otra razón) Netcat cerrará la conexión.

Finalmente le decimos al script que mate todos los procesos hijos o el mismo programa si decidimos matar al servidor o nos matan el proceso.

Bueno, aqui les muestro como correr el servidor:

auyan:~ josevnz$ ./nettail fakelog.log 9000
Listening on any address 9000 (cslistener)
Connection from 127.0.0.1:50754
Total received bytes: 0
Total sent bytes: 432
Listening on any address 9000 (cslistener)
Connection from 127.0.0.1:50819

Y un ejemplo de como conectarse:

auyan:~ josevnz$ nc -v -v -v localhost 9000
nc: connect to localhost port 9000 (tcp) failed: Connection refused
Connection to localhost 9000 port [tcp/cslistener] succeeded!
This is a kodegeek test: Sat Mar 14 00:02:15 EDT 2009
This is a kodegeek test: Sat Mar 14 00:02:45 EDT 2009
This is a kodegeek test: Sat Mar 14 00:03:15 EDT 2009
This is a kodegeek test: Sat Mar 14 00:03:45 EDT 2009
This is a kodegeek test: Sat Mar 14 00:04:15 EDT 2009
This is a kodegeek test: Sat Mar 14 00:04:45 EDT 2009
This is a kodegeek test: Sat Mar 14 00:05:15 EDT 2009
This is a kodegeek test: Sat Mar 14 00:05:45 EDT 2009
This is a kodegeek test: Sat Mar 14 00:06:15 EDT 2009

Espero les guste esta solución de 5 minutos :)

Veneblogs: , , , ,

Blogalaxia: , , , ,

To2blogs: , , , ,

Technorati: , , , ,

Del.icio.us: , , , ,

java, linux, opensource, ruby, venezuela

Vamonos al CommunityOne East

Miércoles, 25 de febrero de 2009

Este año se celebra en New York City por primera vez el CommunityOne East, patrocinado por Sun Microsystems. En este evento se van a tratar diversos tópicos sobre tecnología OpenSource como Java, Ruby Rails y MySQL.

Yo ya me inscribí para el 18 y el 19 de Marzo, si alguno de ustedes piensa ir al evento gratis del 18 y quiere ganarse una franela avisenme para darles el código de inscripción para que participen.

Nos vemos allí.

Nota: No creo que vaya al JavaOne del 2009 año. Los temas se parecen mucho a los del año pasado, voy a esperar a que haya más variedad.
Veneblogs: , , , ,

Blogalaxia: , , , ,

To2blogs: , , , ,

Technorati: , , , ,

Del.icio.us: , , , ,

java, linux, opensource, programación, ruby , , , , ,

¿Como encontrar el último día hábil del mes en Java?

Lunes, 26 de enero de 2009

Quizas a usted alguna vez le toco programar como encontrar el último día hábil del mes. La definición:

Es el último día del mes, que no cae un fin de semana y que no es un día feriado.

Para trabajar este ejemplo utilizaremos fechas de los Estados Unidos, mercado de finanzas. En el caso de los días feriados, vamos a utilizar el calendario de OCC (Options Clearing Corporation). Dependiendo del área y país en donde usted trabaje el calendario de las fechas será distinto (por ejemplo Estados Unidos y Venezuela).

La solución en Java es sencilla, usando la clase Calendar. Después de jugar un poco al final terminé escribiendo esta clase que muestra el último día hábil del mes y le dice a usted si la fecha entrada por el teclado es un día hábil o no:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package com.kodegeek.blog.finance;
 
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.ResourceBundle;
import java.util.Scanner;
import java.util.Set;
import java.util.logging.Logger;
 
/**
 * Helper date methods tailored for the financial industry.
 * License: LGPL
 * BLOG: http://kodegeek.com
 * @author josevnz@kodegeek.com
 *
 */
public final class DateHelper {
 
	private final static ResourceBundle BUNDLE;
	private final static Logger log;
	private static final Set holidays;
 
	static {
 
		BUNDLE = ResourceBundle.getBundle(DateHelper.class.getName());
 
		log = Logger.getLogger(DateHelper.class.getName());
 
		// Populate the holidays set
		holidays = new HashSet();
		for (String dateStr: BUNDLE.getString("com.kodegeek.blog.finance.DateHelper.holidays").split(";\\s*", -1)) {
			try {
				holidays.add(DateFormat.getDateInstance(DateFormat.DEFAULT).parse(dateStr));
			} catch (ParseException e) {
				log.warning(String.format(BUNDLE.getString("com.kodegeek.blog.finance.DateHelper.error.badDate"), dateStr));
				continue;
			}
		}
 
	}
 
	/**
	 * Default constructor
	 */
	private DateHelper() {
		// Only static methods go on this class
	}
 
	/**
	 * Check if a given date is the last business day of the month
	 * @param aDate The date to test
	 * @return True if is the last day of the month, false otherwise
	 */
	public final static boolean isLastBusinessDayOfMonth(final Date aDate) {
		boolean isLastBusinessDay = false;
 
		// Can do a comparison?
		if (aDate == null) {
			return isLastBusinessDay;
		}
 
		Calendar calendar = Calendar.getInstance();
 
		// Current date on a weekend
		calendar.setTime(aDate);
		int day = calendar.get(Calendar.DAY_OF_MONTH);
		int month = calendar.get(Calendar.MONTH);
		int year =  calendar.get(Calendar.YEAR);
 
		int lastbusinessDayOfMonth = getLastBusinessDayOfMonth(month, year);
		if (lastbusinessDayOfMonth == day) {
			isLastBusinessDay = true;
		}
 
		return isLastBusinessDay;
	}
 
	/**
	 * Get the last business day of the month for a given month / year combination
	 * @param month The month
	 * @param year The year
	 * @return The last business day
	 */
	public static int getLastBusinessDayOfMonth(final int month, final int year) {
		int day = -1;
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.MONTH, month);
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
 
		// Keep looking backwards until the day is not a weekend or a holiday
		while(true) {
			if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
				calendar.add(Calendar.DAY_OF_MONTH, -1);
				continue;
			} else if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
				calendar.add(Calendar.DAY_OF_MONTH, -2);
				continue;
			} else if (holidays.contains(calendar.getTime())) {
				calendar.add(Calendar.DAY_OF_MONTH, -1);
				continue;
			}
			break;
		} // End while
		day = calendar.get(Calendar.DAY_OF_MONTH);
		return day;
	}
 
	/**
	 * Unit test, load today date and check if is a end of the month
	 * @param args The date to test from the command line
	 * @throws Exception If the date is invalid for the given local
	 */
	public static void main(String [] args) throws Exception {
		Scanner scan = new Scanner(System.in);
		do {
			String currDateStr = null;
			SimpleDateFormat format = new SimpleDateFormat("yy-M-d");
			try {
				System.out.println("Please enter a date to check (YYYY-MM-DD, Ctrl-C to exit):");
				currDateStr = scan.nextLine();
				Date date = format.parse(currDateStr);
 
				if (date != null) {
					Calendar calendar = Calendar.getInstance();
					calendar.setTime(date);
					int month = calendar.get(Calendar.MONTH);
					int year =  calendar.get(Calendar.YEAR);
					System.out.println(String.format("Last business day of the month: %d", getLastBusinessDayOfMonth(month, year)));
					System.out.println(String.format("%s %s", currDateStr,isLastBusinessDayOfMonth(date) == true? "Is the last business day": "Is not the last business day"));
				}
			} catch (ParseException pExp) {
				System.err.println(String.format("Ignoring bad date: '%s'", currDateStr));
			}
		} while (true);
	}
 
}

El resource bundle lo único que contiene son los días feriados:

1
2
3
# Bank holidays per OCC calendar 2009 - http://www.optionsclearing.com/market/infomemos/2008/oct/24961.pdf
com.kodegeek.blog.finance.DateHelper.holidays=Jan 01, 2009;January 19, 2009; Feb 26, 2009;Apr 10, 2009;May 25, 2009;July 3, 2009; Sep 7, 2009; Nov 26, 2009; Dec 25, 2009; Oct 12, 2009; Nov 11, 2009
com.kodegeek.blog.finance.DateHelper.error.badDate=Got bad date '%s' from property

La idea es buscar el último día del mes y de allí contar hacia atrás, esquivando fines de semana y días feriados.

Please enter a date to check (YYYY-MM-DD, Ctrl-C to exit):
2009-02-27
Last business day of the month: 27
2009-02-27 Is the last business day

En una siguiente entrega les mostraré como hacer lo mismo en Ruby.

Blogalaxia:, , ,
Technorati:, , ,
To2blogs:, , ,
Del.icio.us:, , ,

java, linux, programación, ruby , , ,