martes, 21 de agosto de 2012

Versión de Java de un .class


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

lunes, 20 de agosto de 2012

Provincias, cantones y distritos para seleccionar

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:

<html>
<head>
 <script src="distritos.js" type="text/javascript"></script>
 <script src="jquery-1.7.1.min.js" type="text/javascript"></script> 
 <script type="text/javascript">  
  var separator1 = "~";
  var separator2 = "@";
  
  function cargarProvincias(provinciaId) {
   $("#" + provinciaId).append($("<option></option>")
    .attr("value", -1).text("Elija una provincia"));  
   for (var key in p) {
    $("#" + provinciaId).append($("<option></option>")
     .attr("value", key).text(p[key]));
   }
  }
  
  function cargarCantones(provincia, cantonId) {
   var provinciaSelectedValue =  $(provincia).val();
   $("#" + cantonId + " option").remove();
   
   if(provinciaSelectedValue != -1) {     
    $("#" + cantonId).append($("<option></option>")
     .attr("value", -1).text("Elija un cantón")); 
    
    var cantones = c[provinciaSelectedValue].split(separator1);
    
    for (var i=0; i < cantones.length; i++) {
     var cantonValuePair = cantones[i].split(separator2);
     $("#" + cantonId).append($("<option></option>")
     .attr("value", cantonValuePair[1]).text(cantonValuePair[0]));
    }    
   } else {
    $("#" + cantonId).append($("<option></option>")
     .attr("value", -2).text("Elija una provincia"));
   }
   cargarDistritos($("#" + cantonId), "distritos");
  }
  
  function cargarDistritos(canton, distritoId) {
   var cantonSelectedValue =  $(canton).val();
   $("#" + distritoId + " option").remove();
   
   if(cantonSelectedValue > 0) {      
    $("#" + distritoId).append($("<option></option>")
     .attr("value", -1).text("Elija un distrito")); 
    
    var distritos = d[cantonSelectedValue].split(separator1);
    
    for (var i=0; i < distritos.length; i++) {
     var distritoValuePair = distritos[i].split(separator2);
     $("#" + distritoId).append($("<option></option>")
     .attr("value", distritoValuePair[1]).text(distritoValuePair[0]));
    }    
   } else if(cantonSelectedValue == -1){
    $("#" + distritoId).append($("<option></option>")
     .attr("value", -1).text("Elija un cantón")); 
   } else if(cantonSelectedValue == -2){
    $("#" + distritoId).append($("<option></option>")
     .attr("value", -1).text("Elija una provincia")); 
   }
  }  
 </script> 
</head>

<body onload="cargarProvincias('provincias')">
 <select id="provincias" onchange="cargarCantones(this, 'cantones');"></select>
 <select id="cantones" onchange="cargarDistritos(this, 'distritos');"><option value="-2">Elija una provincia</option></select>
 <select id="distritos"><option value="-2">Elija una provincia</option></select>
</body>
</html>

Resultado Final: