Hace poco tuve un pequeño problema con un código que nos enviaron ya compilado. A la hora de hacer deployment en el servidor obteníamos una excepción de tipo:
javax.servlet.ServletException: Bad version number in .class file
Según lo que leí la excepción se da porque la clase fue compilada con una versión más alta de Java que la que corre en la máquina virtual. Por ejemplo que la clase fue compilada en Java 6 y la máquina virtual corre Java 5.
Para confirmar esto indague un poco en Google como averiguar la versión de una clase. Para ello existe un comando: javap -verbose ClassName
(El .exe se puede encontrar en la carpeta bin del JDK)
Es conveniente guardar en un archivo el resultado del comando pues tira bastante información. Dentro de esa información hay que buscar la combinación de minor y major version que se encuentra al puro comienzo para determinar la versión de Java utilizada.
major minor Java platform version
45 3 1.0
45 3 1.1
46 0 1.2
47 0 1.3
48 0 1.4
49 0 1.5
50 0 1.6
Basado en una entrada anterior donde puse a disposición un script para crear las tablas que representan la estructura de provincias, cantones y distritos, he creado un script PHP que genera unos arreglos en JavaScript para poder utilizarlos en selectores de manera que carguen dinámicamente según la selección anterior. Básicamente, si selecciona una provincia, cargue los cantones de esa provincia, y si selecciona un cantón, cargue los distritos de ese cantón.
El script en PHP sería este:
<?php
mysql_connect("localhost","root","") or die("Unable to connect to SQL server");
@mysql_select_db("data_base_name") or die("Unable to select database");
$provincias_result = mysql_query("select * from PROVINCIA_CR");
echo "var p=new Array();var c=new Array();var d=new Array();";
while ($provincia_row = mysql_fetch_row($provincias_result)) {
echo "p[" . $provincia_row[0] . "]='" . $provincia_row[1] . "';";
$cantones_result = mysql_query("select * from CANTON_CR where codigo_provincia = "
. $provincia_row[0]);
$canton_line = "c[". $provincia_row[0] . "]='";
$distrito_lines = "";
while ($canton_row = mysql_fetch_row($cantones_result)) {
$canton_line = $canton_line . $canton_row[2] ."@" . $canton_row[1] . "~";
$distritos_result = mysql_query("select * from DISTRITO_CR where codigo_canton = "
. $canton_row[0]);
$distrito_line = "d[". $canton_row[1] . "]='";
while ($distrito_row = mysql_fetch_row($distritos_result)) {
$distrito_line .= $distrito_row[2] ."@" . $distrito_row[1] . "~";
}
$distrito_line=substr_replace($distrito_line ,"",-1); // Remueve último caracter.
$distrito_lines .= $distrito_line . "';";
}
$canton_line=substr_replace($canton_line ,"",-1); // Remueve último caracter.
echo $canton_line . "';";
echo $distrito_lines;
}
?>
Este script genera un código como este (también dejo a disposición el script generado):
var p=new Array();var c=new Array();var d=new Array();p[1]='San José';c[1]='San José@1~Escazú@1~Desamparados@1~Puriscal@1~Tarrazú@1~Aserrí@1~Mora@1~Goicoechea@1~Santa Ana@1~Alajuelita@1~Vasquez de Coronado@1~Acosta@1~Tibás@1~Moravia@1~Montes de Oca@1~Turrubares@1~Dota@1~Curridabat@1~Pérez Zeledón@1~León Cortés@1';d[1]='Carmen@101~Merced@101~Hospital@101~Catedral@101~Zapote@101~San Francisco de Dos Ríos@101~Uruca@101~Mata Redonda@101~Pavas@101~Hatillo@101~San Sebastián@101';d[1]='Escazú@102~San Antonio@102~San Rafael@102';d[1]='Desamparados@103~San Miguel@103~San Juan de Dios@103~San Rafael Arriba@103~San Antonio@103~Frailes@103~Patarrá@103~San Cristóbal@103~Rosario@103~Damas@103~San Rafael Abajo@103~Gravilias@103~Los Guido@103';d[1]='Santiago@104~Mercedes Sur@104~Barbacoas@104~Grifo Alto@104~San Rafael@104~Candelaria@104~Desamparaditos@104~San Antonio@104~Chires@104';d[1]='San Marcos@105~San Lorenzo@105~San Carlos@105';d[1]='Aserrí@106~Tarbaca o Praga@106~Vuelta de Jorco@106~San Gabriel@106~La Legua@106~Monterrey@106~Salitrillos@106';d[1]='Colón@107~Guayabo@107~Tabarcia@107~Piedras Negras@107~Picagres@107';d[1]='Guadalupe@108~San Francisco@108~Calle Blancos@108~Mata de Plátano@108~Ipís@108~Rancho Redondo@108~Purral@108';d[1]='Santa Ana@109~Salitral@109~Pozos o Concepción@109~
...
Con ese código se puede agregar lógica JavaScript, sazonada con JQuery, para cargar las opciones dinámicamente:
Continuando con mis experiencias en este aprendizaje del framework CakePHP, quiero poner a disposición una receta en la cual tardé bastante en encontrar y personalizar, de cómo preparar una carga dinámica de un select box a partir de una selección anterior.
En este ejemplo cargo las opciones de raza a partir de una selección previa de una especie.
Ingredientes:
1. Función en el controlador para listar las especies (primer select box):
public function add() {
if ($this->request->is('post')) {
// Código para salvar el anuncio.
} else {
$especie = new Especie();
$especies = $especie->find('list', array(
'fields' => array('Especie.id', 'Especie.nombre')
));
$this->set('especies', $especies);
}
}
3. Función en el controlador para retornar un JSON con las razas pertenecientes a la especie:
public function getRazasByEspecie() {
if ($this->request->is('ajax')) {
$idEspecie = $this->params['data']['idEspecie'];
$raza = new Raza();
$razas = $raza->find('all',array(
'fields' => array('Raza.id', 'Raza.nombre'),
'conditions'=>array('Raza.id_especie'=>$idEspecie)));
$this->RequestHandler->respondAs('json');
$this->autoRender = false;
echo json_encode ( $razas );
}
}
Preparación:
Agregar el código JavaScript que una (binding) la siguente lógica al evento de modificación del primer select box. La función hace un llamado Ajax al controlador para pedir las razas. Estas son retornadas en formato JSON el cual es procesado para agregar las nuevas opciones del segundo select box.