jueves, 30 de julio de 2009

OCA: Auditoria en base de datos Oracle.

Auditoria significa capturar y almacenar información acerca de lo que está sucediendo en el sistema, este proceso por lo tanto aumenta la cantidad de trabajo que el sistema debe de hacer. La auditoria debe ser enfocada a solo aquellos eventos que son de interes, una auditoria apropiadamente direccionada tiene un mínimo impacto sobre el desempeño del sistema, pero una auditoria no adecuada puede tener un impacto significativo negativo sobre el desempeño del sistema. El monitoreo y la auditoria debe ser una parte integral de tus procedimientos de seguridad, los cuales incluyen:

Auditoria obligatoria:
Todas las bases de datos Oracle auditan ciertas acciones a pesar de que las opciones ó parámetros de auditoria esten desactivados, la razón para una auditoria obligatoria es que la base de datos necesita registrar algunas actividades de base de datos críticas como son el inicio ó apagado del sistema.

Auditoria standard
Este tipo de auditoria es una caracteristica que se usa a nivel del sistema, usando un parámetro de inicialización, dicho parámetro es AUDIT_TRAIL. Después de que habilitaste la auditoria, ahora debes de seleccionar los objetos y privilegios que quieras auditar.

Auditoria basada en valores
Este tipo de auditoría extiende la auditoría standard, capturando no solo los eventos de auditoria que han ocurrido sino tambien los valores actuales que han sido insertados, actualizados o borrados, la auditoría basada en valores es implementada a través de triggers de base de datos.

Auditoría detallada
La auditoria detallada extiende la auditoria standard, capturando las declaraciones SQL actuales que han sido ejecutadas y no solo el evento que ha ocurrido.

Mucha teoria, veamos algo de practica sobre como podemos implementar la auditoría detallada en Oracle:
Supongamos que tú como DBA quieres saber cuando un usuario a seleccionado ciertos registros que son de vital importancia para la empresa, los registros los vamos a crear de la siguiente manera:

Objetos a crear:

Una tabla en el schema hr llamada empleados, el ddl es el siguiente:

create table hr.empleados(
codigo char(2) constraint nn_codigo_emp not null,
nombres varchar2(40) constraint nn_nombres_emp not null,
apellidos varchar2(40) constraint nn_apellidos_emp not null,
sueldo number(10,2) constraint nn_sueldo_emp not null,
primary key(codigo)
);

-- y el dml el siguiente:
insert into hr.empleados values('01','nombres1','apellidos1',1000);
insert into hr.empleados values('02','nombres2','apellidos2',2000);
insert into hr.empleados values('03','nombres3','apellidos3',3000);
insert into hr.empleados values('04','nombres4','apellidos4',4000);
insert into hr.empleados values('05','nombres5','apellidos5',5000);

Una vez creada la tablita vamos a auditar(seguir los pasos) de los usuarios que seleccionan los registros de los empleados que ganan más de S/.3000 (campo sueldo de la tabla hr.empleados)

Creamos un par de usuarios y le asignamos los privilegios de conexion y consulta sobre la tabla creada anteriormente:

create user sapo01 identified by sapo01;
create user sapo02 identified by sapo02;
grant connect to sapo01,sapo02;
grant select on hr.empleados to sapo01,sapo02;

Usamos el paquete dbms_fga para crear una politica de auditoria sobre una tabla o vista determinada(en nuestro caso la tabla hr.empleados), si cualquiera de las filas retornadas desde una consulta(query sql) ejecutadas por cualquier usuario coincide con la columna auditada y la condición de auditoria especificada entonces un evento de auditoria será creado y almacenado en las pistas de auditoria de Oracle. Opcionalmente, el evento de auditoria puede tambien ejecutar un procedimiento, La auditoria detallada se enfoca en un nivel declarativo(sql) es así que una declaración select que retorna cientos de filas generará solo un registro de auditoria.

El bloque pl/sql que crea la politica de auditoria es el siguiente:

begin
dbms_fga.add_policy (
object_schema=>'hr',
object_name=>'empleados',
policy_name=>'auditoria_sueldo_empleado',
audit_condition=>'sueldo>3000',
audit_column=>'sueldo',
handler_schema=>null,
handler_module=>null,
enable=>true,
statement_types=>'select');
end;

Ahora entramos con cualquiera de los usuarios creados enteriormente desde sqlplus y ejecutamos una consulta sobre la tabla que ya hemos configurado para que sea auditada:

C:\Documents and Settings\Pc>sqlplus /nolog
SQL*Plus: Release 10.2.0.1.0 - Production on Sßb Ago 1 22:27:18 2009
Copyright (c) 1982, 2005, Oracle. All rights reserved.
nolog> connect sapo01/sapo01@optimus;
Conectado.
SAPO01: OPTIMUS> select * from hr.empleados where sueldo=4000;
CO NOMBRES
-- ----------------------------------------
APELLIDOS SUELDO
---------------------------------------- ----------
04 nombres4
apellidos4 4000
SAPO01: OPTIMUS>

Ahora como usuario dba vemos los registros de auditoria creados, consultando a la vista dba_fga_audit_trail vemos algunos datos relevantes, entre los que destacan:

DB_USER, el usuario que realizó la consulta
OS_USER, el usuario desde donde se inició la sesión del sistema operatico cliente
USERHOST, nombre de la máquina del usuario que realizó la consulta
OBJECT_SCHEMA, el nombre del esquema auditado(hr en nuestro caso)
OBJECT_NAME, nombre de la tabla ó vista auditada(empleados en nuestro caso)
POLICY_NAME, nombre de la politica creada(auditoria_sueldo_empleado)
SQL_TEXT, el sql que ejecutó el usuario

El proceso de auditoría creado es bastante simple, en tu trabajo quizás quieras auditar tablas o vistas críticas que involucran miles de accesos por minuto, por lo que estos tipos de registros de auditoria debes de hacerlo con mucho cuidado y solo en casos en que lo amerite, como dije al comienzo una auditoría mal creada puede devenir en un performance negativo.

miércoles, 29 de julio de 2009

SCJP Preguntas y Respuestas Serie 1

Preguntas

Pregunta 1:
Dado el siguiente código:
1. public class Test {
2. public static void main(String [] args) {
3. signed int x = 10;
4. for (int y=0; y<5; y++, x--)
5. System.out.print(" " + x);
6. }
7. }

¿Cuál es el resultado? (Selecciona uno.)
A. 10 9 8 7 6
B. 9 8 7 6 5
C. La compilación falla
D. Una excepción es lanzada en tiempo de ejecución

Pregunta 2:
¿Cuál es una palabra reservada en el lenguaje de programación Java? (Selecciona una)
A. method
B. native
C. subclasses
D. reference
E. array

Pregunta 3
¿Cuál de estas listas contiene solo palabras reservadas del lenguaje java?(Selecciona una)
A. class, if, void, long, Int, continue
B. goto, instanceof, native, finally, default, throws
C. try, virtual, throw, final, volatile, transient
D. strictfp, constant, super, implements, do
E. byte, break, assert, switch, include

Pregunta 4
¿Cuáles dos son palabras reservadas? (Selecciona dos)
A. interface
B. unsigned
C. Float
D. this
E. string

Pregunta 5
¿Cuáles tres son declaraciones válidas de un char? (Selecciona tres)
A. char c1 = 064770;
B. char c2 = ‘face’;
C. char c3 = 0xbeef;
D. char c4 = \u0022;
E. char c5 = ‘\iface’;
F. char c6 = ‘\uface’;

Pregunta 6
¿Cuáles dos son declaraciones válidas de un String? (Selecciona dos)
A. String s1 = null;
B. String s2 = ‘null’;
C. String s3 = (String) ‘abc’;
D. String s4 = (String) ‘\ufeed’;
E. String s5 = “strings rule”;

Pregunta 7
¿Cuál es una declaración válida de un tipo de dato boolean? (Selecciona uno)
A. boolean b1 = 0;
B. boolean b2 = ‘false’;
C. boolean b3 = false;
D. boolean b4 = Boolean.false();
E. boolean b5 = no;

Pregunta 8
¿Cuál es el rango númerico de un char? (Selecciona uno)
A. –128 to 127
B. –(2 ^ 15) to (2 ^ 15) - 1
C. 0 to 32767
D. Depende de la plataforma
E. 0 to 65535

Pregunta 9
¿Cuáles tres son declaraciones válidas de un float? (Selecciona tres)
A. float f1 = -343;
B. float f2 = 3.14;
C. float f3 = 0x12345;
D. float f4 = 42e7;
E. float f5 = 2001.0D;
F. float f6 = 2.81F;

Pregunta 10
¿Cuáles tres son declaraciones legales de un arreglo? (Selecciona tres)
A. int [] puntajes [];
B. char [] caracteres;
C. int [6] caracteres;
D. Persona personas [];
E. Persona personas [7];


Si ya llegaste hasta aquí apunta bien tus respuestas y comparalas con las respuestas de abajo, recuerda que para certificarte tienes que sacar un mínimo de 70%(acostumbrate a la autoevaluación)


Respuestas
Respuesta 1:
C. La palabra signed no es un modificador válido como palabra reservada en el lenguaje Java. Todos los números primitivos en java tienen signo, siempre.

Respuesta 2:
B. La palabra native es una palabra reservada válida que es usada para modificar la declaración de un método. Las alternativas A, D, y E no son palabras reservadas. C no puede ser porque la palabra reservada para subclasear(herencia) es extends no subclasses.

Respuesta 3.
B. Todas las palabras en la alternativa B son parte de las palabras reservadas java. A está mal porque la palabra reservada para el primitivo int inicia con una letra minúscula i. C tambien está mal porque virtual es una palabra reservada en C++, no en Java. D tampoco es porque constant
no es una palabra reservada, las constantes en Java son declaradas como static y final. E tampo es porque include es una palabra reservada en C, no en Java.

Respuesta 4.
A y D. Tanto interface y this son palabras reservadas. B esta mal porque unsigned es una palabra reservada en C/C++ pero no en Java. C tambien está mal porque Float es un tipo de clase, la palabra reservada para el primitivo Java es float. E tambien está mal porque aunque String es un tipo de clase en Java, string no es una palabra reservada.

Respuesta 5.
A, C y F. A es una representación octal del valor enter 27128, el cuál es legal porque pertenece a un tipo de dato entero de 16bits sin signo. C es una representación hexadecimal del valor entero 48879, el cuál pertenece tambien a un tipo de dato entero de 16bits sin signo. F es una representación Unicode de un caracter. B está mal porque no podemos colocar más de un caracter en un literal de caracteres.(esto lo podemos saber porque esta entre comillas simples). Los unicos aceptables literales de caracter que pueden ir entre comillas simples son valores Unicode, y los literales Unicode deben siempre iniciar con '\u'. D tambien está mal porque las comillas simples no aparecen. E tambien es incorrecto porque parece ser una representación Unicode pero inicia con '\i' en vez de '\u'.

Respuesta 6.
A y E. A coloca la referencia String a null; E inicializa la referencia String con un literal.
B es incorrecto porque un null no puede estar entre comillas simples. C es incorrecto porque allí existen multiples caracteres entre las comillas simples(‘abc’). D tambien es incorrecto porque no podemos castear(pasar el valor de una variable de un tipo de dato a otro) un primitivo char a un objeto String.

Respuesta 7.
C. A un boolean solo puede ser asignado el literal true o false. A, B, D, and E son todas asignaciones incorrectas para un boolean.

Respuesta 8.
E. Un char es realmente un entero sin signo de 16bits.

Respuesta 9.
A, C, y F. A y C son literales de enteros (32 bits), y los enteros pueden ser legalmente asignados a floats (que tambien son de 32 bits). F es correcto porque F es agregado al literal, declarandolo como float mas que como un double( el tipo de dato por default para literales de punto flotante, osea decimales). B, D, y E son todos doubles.

Respuesta 10.
A, B, y D. En una declaración de arreglo, podemos colocar los corchetes a la derecha o a la izquierda del identificador. A parece extraño, pero es perfectamente legal porque divide los corchetes y hace un arreglo multidimensional, colocando los corchetes a ambos lados del identificador. C y E son incorrectos porque no podemos declarar un arreglo con un tamaño, el tamaño es solo necesario cuando el arreglo va a instanciarse(y la máquina virtual Java necesita conocer cuanto espacio de memoria asignar al arreglo, basado en el tipo del arreglo y su tamaño).

Primera Aplicacion Web, en java porsupuesto

Lo primero que tenemos que hacer es disponer de las herramientas necesarias, entre las cuales debemos tener: un jdk(no necesariamente el de Sun) y de un contenedor web, para eso suponemos que ya hemos instalado el jdk de Sun, descargamos el Tomcat en su versión comprimida en zip(Binary Distributions/Core/Zip). Para hacer las cosas más fáciles vamos a instalar el tomcat en un determinado directorio , yo lo he instalado en H:\appservers>, el proceso de instalar simplemente es copiar lo que hemos descargado a este directorio y descomprimirlo, yo(adicionalmente) le cambio el nombre al directorio.

1. Primero lo copio a un directorio:

H:\appservers>dir
29/07/2009 10:47 a.m. 6,379,115 apache-tomcat-6.0.20.zip

2. Ahora lo descomprimo
29/07/2009 10:47 a.m. 6,379,115 apache-tomcat-6.0.20.zip
29/07/2009 10:51 a.m. apache-tomcat-6.0.20

3. Ahora le cambio el nombre al directorio creado, por ejemplo a tomcat6
29/07/2009 10:47 a.m. 6,379,115 apache-tomcat-6.0.20.zip
29/07/2009 10:51 a.m. tomcat6

Ok ya tienes instalado el Apache Tomcat en tu máquina.

Antes de iniciar el tomcat tenemos que agregar una variable de entorno, la famosa variable JAVA_HOME cuyo valor debe ser el directorio de tu jdk, el mio es 'C:\Archivos de programa\Java\jdk1.6.0_14' esta variable de entorno en Windwos lo podemos agregar en 'Escritorio/Click derecho en el icono Mi PC/Propiedades/Pestaña Opciones Avanzadas/Variables de Entorno'

Ahora si probemos el tomcat que hemos instalado:

1. Nos vamos hacia el directorio donde lo instalamos y nos dirigimos hacia la carpeta bin, cuyo contenido debe de ser el siguiente:

14/05/2009 01:15 a.m. 17,508 bootstrap.jar
14/05/2009 01:15 a.m. 2,374 catalina-tasks.xml
14/05/2009 01:15 a.m. 10,652 catalina.bat
14/05/2009 01:15 a.m. 13,573 catalina.sh
14/05/2009 01:15 a.m. 9,341 commons-daemon.jar
14/05/2009 01:15 a.m. 1,342 cpappend.bat
14/05/2009 01:15 a.m. 2,104 digest.bat
14/05/2009 01:15 a.m. 1,624 digest.sh
14/05/2009 01:15 a.m. 74,398 jsvc.tar.gz
14/05/2009 01:15 a.m. 4,951 service.bat
14/05/2009 01:15 a.m. 3,452 setclasspath.bat
14/05/2009 01:15 a.m. 4,556 setclasspath.sh
14/05/2009 01:15 a.m. 2,096 shutdown.bat
14/05/2009 01:15 a.m. 1,563 shutdown.sh
14/05/2009 01:15 a.m. 2,097 startup.bat
14/05/2009 01:15 a.m. 1,956 startup.sh
14/05/2009 01:15 a.m. 19,399 tomcat-juli.jar
14/05/2009 01:15 a.m. 240,128 tomcat-native.tar.gz
14/05/2009 01:15 a.m. 57,344 tomcat6.exe
14/05/2009 01:15 a.m. 98,304 tomcat6w.exe
14/05/2009 01:15 a.m. 3,189 tool-wrapper.bat
14/05/2009 01:15 a.m. 3,291 tool-wrapper.sh
14/05/2009 01:15 a.m. 2,101 version.bat
14/05/2009 01:15 a.m. 1,567 version.sh

De todos esos archivos solo nos interesan(por el momento) dos de ellos startup.bat(para iniciar el contenedor web) y shutdown.bat(para detenerlo)

2. Ejecutamos el archivo startup.bat de la siguiente manera:

H:\appservers\tomcat6\bin>startup

-- La salida de la ejecución del programa de inicio nos muestra el directorio base, el directorio
-- home y el directorio temporal del contenedor tomcat, todo esto lo podemos cambiar,
-- adicionalmente nos muestra la versión del
-- JRE(Entorno de ejecución java, muy distinto a JDK, JRE pertenece al JDK)
-- que estamos usando

Using CATALINA_BASE: H:\appservers\tomcat6
Using CATALINA_HOME: H:\appservers\tomcat6
Using CATALINA_TMPDIR: H:\appservers\tomcat6\temp
Using JRE_HOME: C:\Archivos de programa\Java\jdk1.6.0_14
H:\appservers\tomcat6\bin>

Como vemos tambien nos sale una ventana emergente con los logs de inicio del tomcat:

29/07/2009 11:06:44 AM org.apache.catalina.core.AprLifecycleListener init
INFO: La biblioteca nativa de Apache Tomcat basada en ARP que permite un rendimiento ¾ptimo en entornos de desarrollo no ha sido h
allada en java.library.path: C:\Archivos de programa\Java\jdk1.6.0_14\bin;.;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS
;C:\WINDOWS\SYSTEM32;C:\WINDOWS;C:\WINDOWS\SYSTEM32\WBEM;C:\Archivos de programa\Java\jdk1.6.0_14\bin;H:\oracle10g\product\10.2.0\
db_1\BIN
29/07/2009 11:06:44 AM org.apache.coyote.http11.Http11Protocol init
INFO: Inicializando Coyote HTTP/1.1 en puerto http-8080
29/07/2009 11:06:44 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1033 ms
29/07/2009 11:06:44 AM org.apache.catalina.core.StandardService start
INFO: Arrancando servicio Catalina
29/07/2009 11:06:44 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.20
29/07/2009 11:06:45 AM org.apache.coyote.http11.Http11Protocol start
INFO: Arrancando Coyote HTTP/1.1 en puerto http-8080
29/07/2009 11:06:45 AM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
29/07/2009 11:06:45 AM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/31 config=null
29/07/2009 11:06:45 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 1121 ms

La ultima línea nos dice que el servidor se inicio en 1121 milisegundos

3. Ahora procedemos a verificar el servicio en un navegador web, abrimos una ventana del navegador y colocamos la siguiente direccion: http://localhost:8080

Lo que debería de aparecer es lo siguiente:

If you're seeing this page via a web browser, it means you've setup Tomcat successfully. Congratulations!

Si tu estas viendo está página por medio de un navegador web, significa que haz instaladao Tomcat satisfactoriamente. Felicitaciones.



Una vez que hemos instalado las herramientas (jdk+contenedor web) ahora procedemos a crear una pequeña aplicacion que mostrará el famoso Hola Mundo

1. Nos vamos hacia el directorio /tomcat6/webapps
2. Una ves allí creamos una estructura de directorios similar a lo siguiente:

webapps(directorio)
-- holamundo(directorio)
-- -- index.jsp(archivo)
-- -- WEB-INF(directorio)
-- -- -- web.xml(archivo)

El contenido de los archivos es el siguiente:

index.jsp Archivo jsp, java server page, que procesará la información del servidor en forma dinámica

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Mi Primera Página Web</title>
</head>
<body>
<%int cantidad = request.getParameter("cantidad")==null?7:Integer.parseInt(request.getParameter("cantidad"));%>
<%for(int i=0; i<cantidad; i++){%>
<h3>Hola Mundo en Java</h3>
<%}%>
</body>
</html>

web.xml Archivo xml, descriptor de despliegue de tu aplicación web, describe como tu aplicación será montada en el contenedor Tomcat, tiene muchos parámetros y etiquetas para que puedas configurar tu aplicación( si quieres certificarte como SCWCD tienes que aprenderte cada una de ellas)


<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<!-- Nombre de nuestra aplicacion Web -->
<display-name>Mi Primera Aplicacion Web</display-name>
<!-- Tiempo en minutos de duracion de una sesion -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<!-- Lista de archivos de bienvenida -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>


3. Ahora lo que hacemos es ir hacia la siguiente url:
http://localhost:8080/holamundo/index.jsp?cantidad=10

Ahora verás el procesamiento de tu página jsp q te mostrará el hola mundo 10 veces

4. Si no quieres colocarle el número de puerto a la dirección(o no quieres usar el por default), entonces edita el archivo server.xml que se encuentra en /tomcat6/conf/server.xml allí aproximandamente en la línea 66, encontrarás la siguiente etiqueta:

<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

cambia el valor 8080 del atributo port, por el valor 80, ahora puedes acceder a tu aplicación sin especificar el puerto, es decir así: http://localhost/holamundo/index.jsp?cantidad=12


¿Qué es Spring Security?

Spring Security proporciona servicios de seguridad para aplicaciones de software empresariales basados en J2EE, enfocado particularmente sobre proyectos construidos usando SpringFramework, si ya estas familiarizado con Spring(y particularmente con los principios de inyección de dependencias) será más rápido aprender Spring Security.

Como sabemos la seguridad comprende dos operaciones: La primera operación es conocida como "autenticación", por el cual se establece si un usuario(que quiere realizar una acción en nuestra aplicación) es quien dice ser, y la segunda operación es llamada "autorización" que se refiere al proceso de decidir si a un usuario le es permitido realizar una determinada acción en nuestra aplicación.

Para llegar al punto donde una acción de autorización es necesaria, la identidad del usuario ya ha sido establecida por el proceso de "autenticación", estos conceptos son comunes y no todos son especificos a Spring Security.

En el nivel de "autenticación" Spring Security soporta muchos modelos de autenticación, muchos de estos modelos de autenticación son proporcionados por terceros o son desarrollados por estandares importantes como el IETF(Internet Engineering tTask Force), adicionalmente, Spring Security proporciona su propio conjunto de caracteristicas de autenticación.

Especificamente, Spring Security actualmente soporta integración de autenticación con todas las siguientes tecnologías:

  1. HTTP BASIC authentication headers (an IEFT RFC-based standard).
  2. HTTP Digest authentication headers (an IEFT RFC-based standard).
  3. HTTP X.509 client certificate exchange (an IEFT RFC-based standard).
  4. LDAP (un enfoque muy comun para necesidades de autenticación multiplataforma, especificamente en entornos extensos).
  5. Form-based authentication (necesario para interfaces de usuario simples).
  6. OpenID authentication.
  7. Computer Associates Siteminder.
  8. JA-SIG Central Authentication Service.
  9. Transparent authentication context propagation for Remote Method Invocation (RMI) and HttpInvoker.
  10. Automatic "remember-me" authentication.
  11. Anonymous authentication.
  12. Run-as authentication.
  13. Java Authentication and Authorization Service (JAAS)
  14. Container integration with JBoss, Jetty, Resin and Tomcat (tambien podemos usar autenticación gestionada por el contenedor)
  15. Java Open Source Single Sign On (JOSSO) *
  16. OpenNMS Network Management Platform *
  17. AppFuse *
  18. AndroMDA *
  19. Mule ESB *
  20. Direct Web Request (DWR) *
  21. Grails *
  22. Tapestry *
  23. JTrac *
  24. Jasypt *
  25. Roller *
  26. Elastic Plath *
  27. Atlassian Crowd *
  28. Nuestros propios sistemas de autenticación.
(* Indica proporcionado por un tercero)


Muchos proveedores de software independientes adoptan Spring Security porque tiene modelos flexibles de autenticación, haciendolo les permite rápidamente integrar sus soluciones con cualquier necesidad de su cliente sin emprender un conjunto de ingenierias o requerir al cliente cambiar su entorno.

Si ninguno de los mecanismos de autenticación satisface tus necesidades, Spring Security es una plataforma abierta y además es bastante simple como para poder escribir nuestros propios mecanismos de autenticación, muchos usuarios corporativos de Spring Security necesitan integrarse con sistemas legados que no siguen ningún estandar particular de seguridad por lo que Spring Security se integra fácilmente a estos sistemas

A veces el simple proceso de autenticación no es suficiente. A veces necesitamos tambien diferenciar la seguridad basada en como el usuario interactua con nuestra aplicación, por ejemplo, podríamos querer asegurarnos que las solicitudes solo lleguen a través de https, esto para proteger passwords de terceros que puedan interceptarlo. O tambien podriamos querer asegurarnos que una persona es quien está realizando las solicitudes y no un "robot" o otro proceso automatizado.

Esto es especialmente util para proteger el proceso de recuperación de passwords de ataques de fuerza bruta, o simplemente para hacer más difícil a las personas duplicar el contenido clave de nuestra aplicación. Para ayudar a realizar estas metas, Spring Security soporta completamente "canales de seguridad" automáticos integrandose con JCaptcha para detección de usuarios humanos.

Independientemente de como la autenticación fué realizada, Spring Security proporciona un cunjunto amplio de capacidades de autorización. Existen tres áreas principales de interés respecto a la autorización, que son; autorización basado en solicitudes web, autorización basada en que métodos pueden ser invocados y autorización de acceso a instancias de objetos que pertenecen a un dominio individual, para entender mejor las diferencias considera las capacidades de autorización encontradas en la especificación Servlet del patrón de Seguridad Web, seguridad EJB gestionada por el contenedor y la seguridad de los sistemas de archivos respectivamente.


martes, 28 de julio de 2009

SCJP Declaraciones Inicializacion y Alcance 4

Métodos abstractos
Un método abstracto es un método que ha sido declarado pero que no ha sido implementado, en otras palabras el método no contiene código funcional. Una declaración de método abstracto no tiene las llaves de apertura y de cerradura { } en su lugar tiene un punto y comas ; en otras palabras no tiene un cuerpo, nosotros marcamos los métodos como abstractos para forzar a las subclases la implementación de dicho método. Por ejemplo si tenemos la siguiente clase abstracta:

public abstract class Vehiculo{
public abstract void frenar();
public abstract int kilometraje();
}

entonces las clases que extienden la clase anterior y que no sean abstractas deben dar una implementación a cada uno de los métodos abstractos:

public class Bicicleta extends Vehiculo{
public void frenar(){
-- Aqui la implementación del método frenar.
}
public int kilometraje(){
-- Aqui la implementación del método kilometraje.
}
}

Ojo, no podemos declarar un método abstracto en una clase que no es declarada tambien abstracta, por ejemplo lo siguiente es incorrecto:

-- Esta clase no es abstracta, es concreta.
public class Vehiculo{

-- La clase no es abstracta no tiene el modificador abstract
-- entonces un método abstracto es ilegal aquí.
public abstract void frenar();
}

Veamos otro ejemplo, si tenemos una clase abstracta como:

public abstract class Vehiculo{
public abstract void frenar(String tipoFreno, int tipoVehiculo);
}

y extendemos la clase de la siguiente manera:

public class Omnibus extends Vehiculo{
public void frenar(int tipoFreno, int tipoVehiculo){
-- Aqui la implementación del frenado.
}
}

Ahora, ¿la clase Omnibus extiende e implementa correctamente la clase abstracta Vehiculo?
No, claro que no, porque la clase Omnibus está sobrecargando(overloading) el método frenar no lo sobreescribe(overriding), por lo que la implementación en la subclase(Omnibus) es incorrecta, esto se puede ver porque el argumento en la clase Vehiculo es de tipo String y en la clase Omnibus de tipo int, para que el método abstracto pueda ser implementado correctamente en las subclases, estas deben de corresponder sus tipos de datos con los tipos de datos del método abstracto.

La siguiente clase implementa correctamente la clase abstracta, mira la diferencia con la anterior clase Omnibus:

public class Omnibus extends Vehiculo{
public void frenar(String tipoFreno, int tipoVehiculo){
-- Aqui la implementación del frenado.
}
}

Métodos sincronizados
La palabra clave synchronized indica que un método puede ser accedido solo por un hilo a la vez(saca tus libros de sistemas operativos para recordar que es un hilo), recuerda tambien que la palabra clave synchronized solo puede ser aplicada a métodos y solo a métodos no a variables, ni clases, una declaración típica de un método sincronizado es:

public synchronized long getSaldoDisponible(){
-- Implementación del método sincronizado
}


Métodos nativos
El modificador native indica que un método es implementado con código dependiente del sistema operativo, frecuentemente este código es 'C ' , la palabra clave native solo puede ser aplicado a métodos, no a variables o clases, y como los métodos abstractos no tiene un cuerpo por lo que finalizan con un punto y coma ;

Métodos con una lista de argumentos variable
Desde java5, nosotros podemos crear métodos que permiten tomar un número variable de argumentos, por ejemplo:

public class ClaseSimple{

public int sumar(int... operandos){
int suma = 0;
for(int operando:operandos)
suma = suma + operando;
return suma;
}

public void testSuma(){
-- Aqui podemos observar que la cantidad de
--argumentos para el método puede ser variable
int s0 = sumar();
int s1 = sumar(1,2,3);
int s2 = sumar(1,2,3,4,5);
int s3 = sumar(1,2);
int s4 = sumar(1,2,3,4,5,6,7,8,9);
}
}


Algunas declaraciones legales de métodos con cantidad de argumentos variable:

-- Espera primero un caracter, después cero o más caracteres
private void haceAlgo(char c, char... d){}

-- Espera primero un caracter, después cero o más enteros
private void haceAlgo(char c, int... d){}

-- Espera cero o más instancias de la clase ClaseX
private void haceAlgo(ClaseX... d){}

Algunas declaraciones ilegales de métodos con cantidad de argumentos variable:

-- Sintaxis incorrecta
private void haceAlgo(char d...){}

-- Solo podemos tener un argumento que sea variable
private void haceAlgo(char... d,char... d){}

-- El argumento variable debe de estar al final
private void haceAlgo(char... d,double x){}

Java Básico: Hola Mundo

A ver, muchos aún no han hecho su primea aplicación en Java ó no la han hecho sin un ide(Entorno de Desarrollo Integrado, mismo netbeans ó eclipse), el famoso hola mundo, pues allí les va los pasos:

1. Instalate el jdk(java development kit ó conjunto de herramientas de desarrollo de java), lo puedes descargar desde acá en esa página busca JDK 6 Update XX, descargalo e instalalo.

2. Una vez instalado el jdk coloca las variables de entorno para poder utilizar el jdk desde cualquier directorio o un entorno de mandatos, en windows lo puedes hacer así:

Escritorio/Icono Mi PC(Click Derecho->Propiedades)/Opciones Avanzadas/Variables de Entorno, allí creamos una variable de entorno JAVA_HOME y como valor le colocamos C:\Archivos de programa\Java\jdk1.6.0_14

Además agregamos a la variable de entorno PATH el valor
C:\Archivos de programa\Java\jdk1.6.0_14\bin

Ojo: por default el jdk es instalado en 'C:\Archivos de programa\Java\jdk1.x.0_yz', recuerda donde instalaste el jdk y colocale las variables de entorno adecuadas.

3. Crea tu entorno de desarrollo, es decir, crea las estructuras de directorios básicas, yo hice lo siguiente:

H:\appsjava\app1
H:\appsjava\app2

4. Crea tu archivo fuente(el que contendrá todo el código java), yo creé el archivo HolaMundo.java y lo coloqué en el directorio H:\appsjava\app1, el contenido de dicho archivo es el siguiente:

public class HolaMundo{
public static void main(String[] argumentos){
System.out.println("Hola Mundo en Java");
}
}

5. Compila tu archivo fuente de la siguiente manera:
5.1. Inicia un entorno de línea de comandos(dos) , en windows puedes hacer Inicio/Ejecutar y en la caja de texto coloca cmd, ahora pulsa aceptar, se abrirá el entorno de comandos de dos, desde aquí entra hasta el directorio donde colocaste tu archivo HolaMundo.java de la siguiente manera:

Microsoft Windows XP [Versión 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\Pc>H:
H:\>cd appsjava/app1
H:\appsjava\app1>

5.2 Ahora ya podemos compilar el archivito java que creamos de la siguiente manera:

H:\appsjava\app1>javac HolaMundo.java

5.3 Y si hacemos un listado del directorio con el comando dir, vemos que hay un nuevo archivo llamado HolaMundo.class que contiene el bytecode que la máquina virtual interpretará y ejecutará cuando ejecutemos con el comando java el archivo HolaMundo.class

H:\appsjava\app1>dir
El volumen de la unidad H es DATA_XP3
El número de serie del volumen es: 04B2-3766

Directorio de H:\appsjava\app1

28/07/2009 11:54 a.m. .
28/07/2009 11:54 a.m. ..
28/07/2009 11:54 a.m. 430 HolaMundo.class
28/07/2009 11:49 a.m. 119 HolaMundo.java
2 archivos 549 bytes
2 dirs 6,874,980,352 bytes libres

6. Ejecuta tu archivo con el comando java:
6.1 Ahora una vez compilado y generado el archivo HolaMundo.class procedemos a ejecutarlo con el comando java de la siguiente manera:

H:\appsjava\app1>java HolaMundo
Hola Mundo en Java

La linea anterior Hola Mundo en Java es el resultado de la ejecución de tu programa!.

A ver para los que les gusta algo más complicado, vamos a hacer que la cadena 'Hola Mundo en Java' se ejecute el número de veces que queramos, el numero de veces lo vamos a pasar como un argumento al llamar al programa, veamos como quedaría nuestro código:

public class HolaMundo{
public static void main(String[] argumentos){
for(int i=0; i < Integer.parseInt(argumentos[0]) ; i++)
System.out.println("Hola Mundo en Java");
}
}

Pero que es lo que ha cambiado en el programita?, hemos agregado una estructura repetitiva for y el cuerpo de esta estructura se va a ejecutar tantas veces como indique el primer argumento pasado al programa Integer.parseInt(argumentos[0]) , tenemos que parsear porque el arreglo argumentos contienen valores de tipo String String[] argumentos, por lo que Integer.parseInt(argumentos[0]) nos devolverá un entero

El resultado de la ejecución una vez compilado es el siguiente(vemos que ahora le pasamos un argumento al programa, un número que indica el número de veces que se muestra la cadena 'Hola Mundo en Java'):

H:\appsjava\app1>java HolaMundo 10
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java

H:\appsjava\app1>java HolaMundo 3
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java

H:\appsjava\app1>java HolaMundo 6
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java
Hola Mundo en Java


lunes, 27 de julio de 2009

SCJP Declaraciones Inicializacion y Alcance 3

Declarando miembros de clase
Como vimos una clase puede tener solo 2(default y public) de los 4 modificadores de acceso que los miembros(métodos y variables de instancia) pueden usar: public, protected, default y private.
La protección por default que obtenemos es aquella cuando no escribimos el modificador de acceso en la declaración del miembro como:

public class Algo{
-- Si no escribimos el modificador de acceso a este miembro de
-- clase entonces asume el por default
int x;

-- Este miembro de clase declara explicitamente el tipo de
-- protección a private
private int y;
}

Los controles de acceso default y protected tienen exactamente el mismo comportamiento excepto por una diferencia: el miembro con control de acceso default puede ser accedido solo si la clase accediendo al miembro pertenece a el mismo paquete, a diferencia un miembro con control de acceso protected puede ser accedido(a través de herencia) por una subclase, incluso si la subclase está en un paquete diferente. Veamos algo de código para clarificar la teoria:

package miempresa.core;

public class ClaseA{

-- Si no especificamos el control de acceso a este
-- método entonces se le asigna default
int sumarA(int x,int y){
return (x+y);
}

-- Aqui le asignamos el control de acceso
--explicitamente a protected
protected int restarA(int x,int y){
return (x-y);
}
}


Ahora veamos otra clase que está en otro paquete y que referencia a la clase anterior:

package miempresa.util;
import miempresa.core.ClaseA;

-- La extensión de la ClaseA la podemos realizar ya que su
-- modificador es public
public class ClaseB extends ClaseA{

int sumarB(int x,int y){
-- Lo siguiente es incorrecto ya que sumarA tiene acceso por default
-- y está tratando de ser accedido por la ClaseB que se
-- encuentra en otro paquete
return sumarA(x,y);
}

-- Aqui le asignamos el control de acceso explicitamente a protected
-- Si se compilara solo esta parte entonces todo estaría OK. porque
-- el control de acceso de restarA es protected
protected int restarB(int x,int y){
return restarA(x,y);
}
}

Miembros públicos
Cuando un método o variable miembro es declarado público public significa que todas las otras clases(incluso las que no están en el mismo paquete) pueden acceder al miembro ( asumiendo que la clase es visible )

Miembros privados
Miembros marcados private no pueden ser accedidos por código en cualquier otra clase más que la propia clase en la cual el miembro private fué declarado.

Miembros protected
Veamos un ejemplo:

package miempresa.core;
public class ClaseA{
protected double sueldo;
}


El código anterior declara una variable sueldo como protegida protected. Esto hace la variable accesible a todas las otras clases dentro del paquete miempresa.core así como tambien heredable por cualquier subclase fuera del paquete miempresa.core. Ahora crearemos una subclase en un paquete diferente e intentaremos usar la variable sueldo.

package miempresa.rrhh;
import miempresa.core.ClaseA;
public class ClaseB extends ClaseA{
public void procesar(){
sueldo = 3000;
-- Como vemos heredamos la variable sueldo sin problemas
System.out.println("Mi sueldo fue:"+sueldo);
}
}

El código anterior compila bien, debemos notar que la subclase accede a la variable protegida a través de herencia extends. Pero que pasa si queremos acceder a la variable sueldo sin usar herencia, es decir, usando una instancia de la clase ClaseA, veamos:

package miempresa.rrhh;
import miempresa.core.ClaseA;
public class ClaseB extends ClaseA{
public void procesar(){
sueldo = 3000;
-- Como vemos heredamos la variable sueldo sin problemas
System.out.println("Mi sueldo fue:"+sueldo);

-- Ahora veamos que pasa si instanciamos
-- una clase y tratamos de acceder a la variable protegida
ClaseA claseA = new ClaseA();
-- Lo siguiente nos dará un error de compilación
-- porque la variable es protegida y solo es accesible a través
-- de herencia
System.out.println("Mi sueldo fue:"+claseA.sueldo);
}
}


Variables locales y modificadores de acceso.
Podemos aplicar los modificadores de acceso(public,protected,private) a las variables locales?, es decir el siguiente código es válido?:

public class ClaseA{
public void procesar(){
-- Variable local con modificador de acceso:
private int suma;
}
}

Pues claro que no, no tiene sentido colocar un modificador de acceso a una variable local, esa variable fué declarada solo para ser usada en el ámbito que le corresponde, en el ejemplo el ambito es el método procesar(). Como vemos ningún modificador de acceso puede ser asignado a una variable local, a una variable local solo le podemos asignar un modificador de no-acceso el cual es final, lo cual indica que solo es de lectura(no podemos asignarle un valor).

Métodos finales
La palabra clave final protege a un método de ser sobreescrito en una subclase, veamos un ejemplo, si nosotros tenemos una clase llamada UtilFechas que tiene un método fechaActual, de la siguiente manera:

public class UtilFechas{
public final String fechaActual(){
return "la fecha actual";
}
}

y alguien por allí trata de extender la clase anterior y trata de sobreescribir el método de la siguiente manera:

public class UtilFechasExtendido extends UtilFechas{
-- Esto trata de sobreescribir el método de UtilFechas
public String fechaActual(){
return "la fecha actual de UtilFechasExtendido";
}
}

Entonces el compilador observará que la clase UtilFechas ha marcado su método fechaActual como final (no podemos sobreescribirla) pero la clase UtilFechasExtendido trata de sobreescribirlo, por lo tanto al momento de compilar retornará un error al usuario.

Argumentos Finales
Los argumentos de los métodos son las declaraciones de variables que aparecen entre los parentesis en una declaración de un método, una declaración común de un método con varios argumentos luce así:

public int sumar(int x, int y, int z){
return (x+y+z);
}

El método anterior tiene tres argumentos int x, int y, int z

Los argumentos de los métodos son igual que las variables locales, esto significa que pueden tener el modificador final

public int sumar(int x, final int y, final int z){
return (x+y+z);
}

En el ejemplo anterior los argumentos int y, int z son marcados con el modificador final, lo cuál significa que sus valores no pueden ser cambiados, es decir no pueden asignarseles otro valor(no podemos hacer y = 78; ó z = 100; ) por lo que estos argumentos mantienen su valor como el parametro que fué usado al momento de llamar al método. Es decir si tenemos en otro metodo una llamada al método sumar de la siguiente manera:

int p1 = 10;
int p2 = 20;
int p3 = 30;
int suma = sumar(p1, p2, p3);

Entonces los parametros p2 y p3 se mantendrán inmutables(no cambia su valor) durante la ejecución del método.




domingo, 26 de julio de 2009

SCJP Declaraciones Inicializacion y Alcance 2

Declarando una interface
Cuando creamos una interface, lo que estamos realizando es un contrato de lo que la clase que implementa dicha interface tiene que hacer sin decir nada acerca de como la clase lo hará, en pocas palabras la interface indica que se va a hacer y la clase que implementa dicha interface indica como se va implementar, de esto concluimos que una interface es un contrato que la clase que lo implementa debe de cumplir. Por ejemplo si tenemos la interface Imprimible definida de la siguiente manera:

public interface Imprimible{
public void imprimirAPdf();
public void imprimirAExcel();
}

Y una clase Libro que implementa la interface anterior de la siguiente manera:

public class Libro implements Imprimible{
public void imprimirAPdf(){
-- Aqui va el código que imprime el libro en formato pdf
}
public void imprimirAExcel(){
-- Aqui va el código que imprime el libro en formato excel
}
}

La clase al implementar la interface debe de cumplir con el contrato, es decir debe de proveer una forma de implementación para cada uno de los métodos de la interface, en el ejemplo vemos que la clase implementa los métodos declarando código entre las llaves de apertura y cerradura de dichos métodos, en la interface después de los parentesis termina su declaración con un punto y coma.

Podemos pensar en las interfaces como clases 100% abstractas, asi como una clase abstracta una interface define métodos abstractos que toman la siguiente forma:

abstract void nombreMetodo();

Pero mientras que una clase abstracta puede definir tanto métodos abstractos como no abstractos, una interface solo puede tener métodos abstractos, es decir podemos tener una clase abstracta de la siguiente manera:

public abstract class Libro{
-- Método abstracto:
public abstract void calcularCosto();

-- Método no abstracto:
public void calcularVentas(){
--Aquí la implementación del método.
}
}

Pero no podemos hacer una interface parcialmente abstracta, las interfaces son 100% abstractas, es decir todos sus métodos son abstractos(no tienen una implementación { ... } ), por lo que la siguiente interface es incorrecta:

public interface Imprimible{
-- Método abstracto:
public abstract void imprimirAPdf();

-- Método no abstracto:
public void imprimirAExcel(){
--Aquí la implementación del método.
}
}

Algunas reglas más sobre la declaración de las interfaces son las siguientes:

1. Todos los métodos de las interfaces son implicitamente públicos y abstractos, en otras palabras no necesitamos escribir los modificadores public y abstract en la declaración del método, el método siempre será públic y abstracto. Veamos, si tenemos la siguiente interface:

public interface Imprimible{
void imprimirAPdf();
int imprimirAExcel();
}

Entonces lo que el compilador realmente analizará es:

public interface Imprimible{
public abstract void imprimirAPdf();
public abstract int imprimirAExcel();
}

2. Todas las variables definidas en una interface deben ser públicas estáticas y finales, en otras palabras las interfaces pueden declarar solo constantes, no variables de instancia.

--Recordar una variable de instancia;
public class Libro{
-- variable de instancia:
private int ancho;
}

3. Los métodos de las interfaces no deben ser estáticos. No podemos hacer lo siguiente:
public interface Imprimible{
public static void imprimir();
}

4. Como los métodos de las interfaces son abstractos entonces no podemos definirlos tambien como finales final, strictfp ó native.

5. Una interface puede extender una o más interfaces, es decir podemos hacer lo siguiente:

public interface interface1{
void metodo1();
}

public interface interface2{
void metodo2();
}

public interface interface3 extends interface1,interface2{
void metodo1();
void metodo2();
void metodo3();
}

6. Una interface solo puede extender interfaces no puede extender clases, por ejemplo si tenemos la clase:

public class Descargable{
protected int descargar(){
-- XXX
}
}

entonces la siguiente declaración de interface es incorrecta:

public interface interface3 extends Descargable{
protected int descargar();
}

7. Una interface no puede implementar otra interface o una clase, no podemos hacer lo siguiente:

public interface interface3 implements interface1,interface2{
void metodo1();
void metodo2();
void metodo3();
}

8. Una interface debe ser declarada con la palabra clave interface.

Declarando constantes en interfaces
Nosotros podemos declarar constantes en una interface, haciendolo garantizamos que cualquier clase que implementa la interface tendrá acceso a la misma constante, la regla principal para las constantes es la siguiente:

public static final = ;

Por ejemplo si tenemos la siguiente interface:

public interface Imprimible{
int ancho = 100;
int largo = 170;
public void imprimir( );
}

y la siguiente clase:

public class Libro implements Imprimible{
public void imprimir(){
--Nosotros podemos usar las constantes
System.out.println(ancho*largo):

--Pero no podemos asignarles un valor porque las declaraciones int ancho = 100;
--el compilador lo analiza como public static final int ancho = 100; es decir es
--declarado como final y estático ya no podemos modificarlo, por lo tanto es incorrecto:
ancho = 666;
}
}

SCJP Declaraciones Inicializacion y Alcance 1

Cuando escribimos código en java, lo que estamos escribiendo es justamente clases o interfaces, dentro de estas clases como conocemos pueden haber variables y métodos(y algunas otras cosas más), la forma en la que declaramos las clases, métodos y variables afecta en forma sustancial el comportamiento del código, por ejemplo un método público puede ser accedido desde código ejecutandose en cualquier lugar en tu aplicación, haciendo el método privado lo oculta a cualquier posible llamada(excepto a la clase en la cuál fué declarada).

Reglas de declaración de archivos fuente
  1. Solo puede haber una clase pública por archivo fuente.
  2. Los comentarios pueden aparecer al inicio o al fin de cualquier línea en el archivo de código fuente.
  3. Si es que hay una clase pública el nombre del archivo debe de coincidir con el nombre de la clase, por ejemplo si hay una clase declarada public Casa entonces el nombre del archivo deberá ser Casa.java
  4. Si la clase es parte de un paquete, la declaración del paquete debe ser la primera línea en el archivo de código fuente, antes de cualquier declaración de importacion import que pueda estar presente.
  5. Si hay declaraciones de importacion import, estas declaraciones deben de ir entre la declaración del paquete(si es que lo hubiera) y la declaración de la clase.
  6. Declaraciones de importación import y de paquetes package aplican a todas las clases dentro de un archivo de código fuente, en otras palabras, no hay manera para declarar multiples clases en un archivo y tenerlos en diferentes paquetes o usar diferentes importaciones.
  7. Un archivo puede tener más de una clase no pública.
  8. Archivos con clases no públicas pueden tener un nombre que no coincide con cualquiera de las clases en el archivo.
Declaraciones de clases y modificadores
  1. Modificadores de acceso: public, protected, private
  2. Modificadores de no-acceso: strictfp, final y abstract
Acceso de Clase
Que es lo que significa acceder a una clase?, cuando decimos que el código de una clase(class X) a accedido a otra clase(class Y) esto significa que la clase X puede hacer cualquiera de las 3 siguientes acciones:

Crear una instancia de la clase Y.
class X{
Y y = new Y( );
}

Extender la clase Y.
class X extends Y{ }

Accesar ciertos métodos y variables de la clase Y, dependiendo del control de acceso de estos métodos y variables.
class X{
Y y = new Y( );
X(){
y.holamundo();
}
}

Modificador de Acceso por Defecto.
Una clase con default access no tiene un modificador de acceso que le precede en su declaración, es decir tiene la forma class X{ } y no public class X { } este es el control de acceso que se obtiene cuando no escribimos el modificador en la declaración, las clases con default access pueden ser vistas como clases con nivel de acceso a nivel de paquete, porque una clase con default access puede ser vista solo por clases dentro del mismo paquete. Por ejemplo si tenemos una clase llamada Persona en el paquete miempresa.core declarada de la siguiente manera:

package miempresa.core;
class Persona{ }

y queremos usar la clase anterior pero en otro paquete digamos miempresa.rrhh con la clase Empleado extendiendola de la siguiente manera:

package miempresa.rrhh;
class Empleado extends Persona{ }

Al compilar la clase Persona no hay problema, pero cuando queremos compilar la clase Empleado entonces el compilador nos retorna un error diciendonos que no tiene acceso a la clase Persona esto es cierto porque el modificador de acceso de la clase Persona es por default, es decir no está indicado explicitamente(no está escrito) y por lo tanto solo puede ser visto por aquellas clases declaradas en el mismo paquete, es decir en el paquete miempresa.core, lo anterior se puede solucionar declarando la clase Empleado en el paquete miempresa.core ó declarando el modificador de acceso a public

Modificador de Acceso Público.
Una declaración de clase con la palabra clave public da a todas las clases de todos los paquetes acceso a esta clase pública, es decir en el ejemplo anterior si a la clase Persona la redeclaro como
public class Persona{ } entonces esta clase puede ser accedida desde cualquier clase en cualquier paquete desde mi aplicación. Ojo que si tratamos de usar la clase pública desde otro paquete entonces debemos de importar dicha clase con la palabra clave import

Otros Modificadores de Clase que no son de Acceso.
Podemos modificar la declaración de una clase con las palabras clave final y abstract

Clases Finales.
Cuando es usada en la declaración de una clase, la palabra clave final significa que la clase no puede ser extendida, en otras palabras ninguna clase puede heredar o extender una clase declarada final si intentamos hacerlo en compilador nos retornará un error.

Clases Abstractas.
Una clase abstracta no puede nunca ser instanciada, su único proposito es ser extendida.
Es decir si tenemos:
public abstract class Persona{ }
no podemos hacer esto:
Persona p = new Persona();
lo que debemos de hacer es lo siguiente:
public class Empleado extends Persona{ }

sábado, 25 de julio de 2009

Arquitectura de una Base de Datos Oracle

Un servidor Oracle consiste de una "instancia Oracle" (memoria=SGA+PGA) y de una "base de datos Oracle" (disco=datafiles) esta base de datos en ejecución está asociada con una instancia.

Es así que cuando una base de datos es iniciada sobre un servidor de base de datos, el software de oracle asigna un área de memoria compartida llamada "System Global Area (SGA)" ó "Area Global del Sistema" e inicia varios procesos en background de Oracle, esta combinación del SGA y los procesos Oracle conforma la instancia.

Después de iniciar una instancia, el software de Oracle asocia la instancia con una base de datos específica, dicho proceso es llamado el proceso de montar(STARTUP MOUNT) la base de datos, ahora la base de datos está entonces lista para ser abierta(STARTUP OPEN), lo cual la hace accesible a usuarios autorizados.

Multiples instancias pueden ejecutarse concurrentemente sobre la misma computadora, cada una accesando su propia base de datos física. La arquitectura de la base de datos se puede entonces observar como varios componentes estructurales interrelacionados.

Una base de datos Oracle usa estructuras de memoria y procesos para gestionar y accesar la base de datos, todas estas estructuras de memoria existen en la memoria principal(RAM) del servidor(HW) que constituye el servidor de base de datos.

Los procesos son hilos que trabajan en la memoria de estos servidores(HW), asi un proceso es definido como un hilo de control o un mecanismo en un sistema operativo que puede ejecutar una serie de tareas.

Las estructuras de memoria básicas asociadas con una instancia Oracle incluyen:

System Global Area (SGA): Memoria compartida por todos los procesos.

Program Global Area (PGA): Memoria privada a cada proceso de servicio y de fondo, solo hay una PGA por cada proceso.

El SGA es un área de memoria que contiene datos e información de control para la instancia, incluye las siguientes estructuras de datos:

Database buffer cache: Memoria cache(de rápido acceso) de los bloques de datos recibidos desde la base de datos, es decir cuando queremos obtener un dato y este no está en memoria entonces es primero obtenida del disco y copiada a este buffer para una posterior obtención más rápida, es decir el próximo proceso ya no se vaya a disco sino al buffer.

Redo log buffer: Memoria cache(de rápido acceso) de la información "redo" hasta que pueda ser escrita a los archivos físicos "redo logs" que se encuentran en disco. Cada transacción que realizamos es primero copiada a este buffer y después a los archivos "redo logs" en disco.

Shared pool: Memoria cache(de rápido acceso) que almacena varias estructuras que pueden ser compartidas entre procesos de usuario.

Large pool: Es un área opcional que proporciona grandes asignaciones de memoria para ciertos procesos largos, como son operaciones de backups y de recuperación así como tambien procesos de entrada y salida al disco.

Java pool: Es usado para todas las sesiones específicas a código java y datos dentro de la máquina virtual java.

Streams pool: Es usado por Oracle Streams.

Cuando iniciamos una instancia la cantidad de memoria asignada para el SGA es mostrada en la interface de comandos de sqlplus o en Enterprise Manager, esta información es mostrada en bytes.