Mostrando postagens com marcador weblogic. Mostrar todas as postagens
Mostrando postagens com marcador weblogic. Mostrar todas as postagens

12 de abr. de 2011

Debug do Classloader no Weblogic

É comum ao tentarmos fazer o deploy de uma aplicação recebermos um erro de ClassNotFoundException. Este é o tipo de erro bem chato de descobrir e algumas vezes temos certeza que a classe está presente no lib do domínio ou disponível para aplicação de alguma forma, seja como shared lib ou no classpath do servidor direto. E então o que fazer, como pode estar acontecendo de a classe COM CERTEZA estar disponível e mesmo assim a exceção de ClassNotFound estar ocorrendo? Bem, nesse caso é bastante útil fazer o classloader ficar em modo verbose para vermos direitinho quais as classes e em que ordem o weblogic está carregando-as.

Para fazer isso basta adicionarmos como parâmetro de JVM do servidor desejado o seguinte:

-Dweblogic.utils.classloaders.FilteringClassLoader.Verbose


Feito isso ao reiniciarmos o servidor iremos ver o classloader aparecendo para cada classe que for procurada, neste formato:

...
[FilteringClassLoader] : **** FilteringClassLoader ... findClass(..) weblogic.jndi.WLInitialContextFactory
[FilteringClassLoader] : **** FilteringClassLoader ... findClass(..) weblogic.jndi.factories.java.javaURLContextFactory
[FilteringClassLoader] : **** FilteringClassLoader ... findClass(..) String
[FilteringClassLoader] : **** FilteringClassLoader ... findClass(..) com.bea.common.security.store.data.String
[FilteringClassLoader] : **** FilteringClassLoader ... findClass(..) String
[FilteringClassLoader] : **** FilteringClassLoader ... findClass(..) com.bea.common.security.store.data.String
[FilteringClassLoader] : **** FilteringClassLoader ... findClass(..) String
[FilteringClassLoader] : **** FilteringClassLoader ... findClass(..) com.bea.common.security.store.data.String
[FilteringClassLoader] : **** FilteringClassLoader ... findClass(..) String
...


Com o debug do classloader fica bem mais fácil entender e descobrir a causa do ClassNotFoundException e com isso solucionar o problema.
Fica também uma dica, caso seja necessário pode-se inverter o classloader da aplicação web para que o weblogic utilize como preferenciais os .jar empacotados no lib do seu .war, para isso basta colocar a seguinte configuração no weblogic.xml da sua aplicação:

...
    
        true
    
...


[]s

7 de abr. de 2011

Migração do Projeto Seam para rodar no Weblogic 10.X - Parte 2

Este post dá continuidade a uma série de posts que estou escrevendo sobre a migração de um projeto que utilize JBoss Seam para rodar em weblogic, estou usando neste caso o Weblogic 10.3.3

O que me motivou a fazer este post é que a documentação oficial do JBoss Seam tem um capítulo sobre o Weblogic mas em todas as vezes que tentei seguí-la não obtive sucesso. Então segue o que fiz com as devidas alterações para que funcionasse.

A primeira parte deste post que cobre a criação do projeto com JBoss Seam pode ser encontrada neste link:

http://mmaiacupofcoffee.blogspot.com/2010/05/jboss-seam-criacao-de-projeto.html

Seguindo os passos do projeto criado no link acima temos então um projeto do Seam padrão, o próximo passo é importá-lo no eclipse para alterarmos o que for necessário. Eu utilizei uma versão do Eclipse Helios com JBoss Tools, se precisar de uma referência veja este post.

1) Criação do arquivo weblogic.xml - para este primeiro passo basta criar um arquivo chamado weblogic.xml no mesmo diretório onde está o web.xml


    10.3.3
    seam_weblogic



2) Mudar os arquivos persistence-prod.xml e persistence-dev.xml para funcionar com o weblogic, segue o meu persistence-dev.xml, para o prod fazer as alterações normais necessárias relativas ao banco de dados, criação de tabelas, etc..


             
   
      org.hibernate.ejb.HibernatePersistence
      seam_weblogic_ds
      
         
         
         
         
         
         
         
         
      
   
    



3) No web.xml registrar o seguinte listener:

  com.sun.faces.config.ConfigureListener



4) Mudar no build.xml o default target para archive e complementar as libs a serem copiadas pro pacote conforme fragmento abaixo:


...

    
        
        
        
        
        
         
        
        
        
        
        
        
        
        
             
        
        
        
             
        
        
        
        
        
        
        
    
 



Feito isso basta navegar em um console para a raiz do projeto e executar o ant default mesmo:
ant

Isso irá criar o war compatível com weblogic no diretório dist do seu projeto. Este .war é compatível com weblogic e vc pode fazer o deploy pelo console normalmente ou se o seu weblogic estiver no modo de desenvolvimento simplesmente copiar este arquivo para o diretório autodeploy do seu domínio.

Em alguns casos percebi a necessidade de inverter o classloader do weblogic, se no passo acima vc ainda não conseguir rodar vc pode tentar inverter o classloader do weblogic.

Este é o procedimento que funcionou no meu caso com .war gerado no seam. Não tentei e não recomendo utilização do Seam com EJBs no weblogic até este momento, por questões de estabilidade e aderência às especificações. Recomendo somente utilização do seam com pojos de camada web se for utilizá-lo com weblogic, mas se este for o seu caso vc encontra informações de como fazer isso na doc. oficial do Seam.

[]s

4 de mai. de 2010

JBoss Seam - Criação de Projeto. Migração para Weblogic - Parte 1

Este post é o primeiro de uma série baseada na documentação do Seam e mostra um passo a passo detalhado de como fazer uma aplicação com extensão .war com jboss seam rodar no próprio JBoss e na sequência de posts irei mostrar a migração deste projeto para o Weblogic Server 10 em Ubuntu 10.04 com Mysql. Não entro em detalhes sobre download e da configuração do Seam, Jboss, Weblogic ou MySQL neste post e pressuponho que o ambiente utilizado já tenha estes produtos instalados.

Vamos ao passo a passo:

O primeiro passo é gerar um novo setup de projeto do Seam abrindo um console shell e navegando para o diretório raiz do seam no seu ambiente e então executar o comando:

./seam setup

Dica: Para o comando executar corretamente coloquei a seguinte entrada apontando para uma instalação válida de JDK no meu ambiente bem no início do arquivo seam antes do comentário "# Validate the JDK installation".

JAVA_HOME=/home/mmaia/Oracle/Middleware_wl10.3.3/jdk160_18 export JAVA_HOME

Na execução do setup basta responder aos questionamentos conforme seu ambiente local.

Segue abaixo a saída do comando seam setup que utilizei no meu computador para este exemplo abaixo, favor adaptar ao seu ambiente conforme necessidade:


mmaia@mmaia-laptop:~/tools/jboss-seam-2.2.0.GA$ ./seam setup
SEAM_HOME: /home/mmaia/tools/jboss-seam-2.2.0.GA
Using seam-gen sources from: /home/mmaia/tools/jboss-seam-2.2.0.GA/seam-gen
Buildfile: /home/mmaia/tools/jboss-seam-2.2.0.GA/seam-gen/build.xml

init:

setup:
[echo] Welcome to seam-gen 2.2.0.GA :-)
[echo] Answer each question or hit ENTER to accept the default (in brackets)
[echo]
[input] Enter the directory where you want the project to be created (should not contain spaces) [/home/mmaia/projects] [/home/mmaia/projects]
/home/mmaia/workspaceGalileoJBossSeam
[input] Enter your JBoss AS home directory [C:/Program Files/jboss-5.1.0.GA] [C:/Program Files/jboss-5.1.0.GA]
/home/mmaia/tools/jboss-5.1.0.GA
[input] Enter your JBoss AS domain [default] [default]
seamWeblogic
[input] Enter your GlassFish V2 or V3 home directory (Ignore if you aren't deploying to GlassFish) [C:/Program Files/glassfish-v2.1] [C:/Program Files/glassfish-v2.1]

[input] Enter your GlassFish domain (Ignore if you aren't deploying to GlassFish) [domain1] [domain1]

[input] Enter the project name [myproject] [myproject]
seam_weblogic
[echo] Accepted project name as: seam_weblogic
[input] Do you want to use ICEfaces instead of RichFaces? [n] (y, [n])
n
[input] skipping input as property icefaces.home.new has already been set.
[input] Select a RichFaces skin [glassX] (blueSky, classic, darkX, deepMarine, DEFAULT, emeraldTown, [glassX], japanCherry, laguna, ruby, wine)
wine
[input] Is this project deployed as an EAR (with EJB components) or a WAR (with no EJB support)? [war] (ear, [war])
war
[input] Enter the base package name for your Java classes [com.mydomain.seam_weblogic] [com.mydomain.seam_weblogic]
seamweblogic     
[input] Enter the Java package name for your session beans [seamweblogic.action] [seamweblogic.action]
[input] Enter the Java package name for your entity beans [seamweblogic.model] [seamweblogic.model]

[input] Enter the Java package name for your test cases [seamweblogic.test] [seamweblogic.test]

[input] What kind of database are you using? [hsql] ([hsql], mysql, derby, oracle, postgres, mssql, db2, sybase, enterprisedb, h2)
mysql
[input] Enter the filesystem path to the JDBC driver jar [] []
/home/mmaia/Oracle/Middleware_wl10.3.3/wlserver_10.3/server/lib/mysql-connector-java-commercial-5.0.3-bin.jar
[input] skipping input as property driver.license.jar.new has already been set.
[input] Enter the Hibernate dialect for your database [org.hibernate.dialect.MySQLDialect] [org.hibernate.dialect.MySQLDialect]

[input] Enter the JDBC driver class for your database [com.mysql.jdbc.Driver] [com.mysql.jdbc.Driver]

[input] Enter the JDBC DataSource class for your database [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] [com.mysql.jdbc.jdbc2.optional.MysqlDataSource]

[input] Enter the JDBC URL for your database [jdbc:mysql:///test] [jdbc:mysql:///test]
seamweblogic
[input] Enter the database username [sa] [sa]
seamweblogic
[input] Enter the database password [] []
seamweblogic
[input] skipping input as property hibernate.default_schema.entered has already been set.
[input] Enter the database catalog name (Enter '-' to clear previous value) [] []
seamweblogic
[input] Are you working with tables that already exist in the database? [n] (y, [n])
n
[input] Do you want to recreate the database tables and execute import.sql each time you deploy? [n] (y, [n])
y
[propertyfile] Creating new property file: /home/mmaia/tools/jboss-seam-2.2.0.GA/seam-gen/build.properties
[echo] Installing JDBC driver jar to JBoss AS
[copy] Copying 1 file to /home/mmaia/tools/jboss-5.1.0.GA/server/seamWeblogic/lib

init:

init-properties:
[echo] /home/mmaia/tools/jboss-5.1.0.GA

validate-workspace:

validate-project:

settings:
[echo] JBoss AS home: /home/mmaia/tools/jboss-5.1.0.GA
[echo] GlassFish home: C:/Program Files/glassfish-v2.1
[echo] Project name: seam_weblogic
[echo] Project location: /home/mmaia/workspaceGalileoJBossSeam/seam_weblogic
[echo] Project type: war
[echo] IceFaces: n
[echo] Action package: mmaia@mmaia-laptop:~/tools/jboss-seam-2.2.0.GA$ ./seam.sh setup
[echo] Model package: seamweblogic.model
[echo] Test package: seamweblogic.test
[echo] JDBC driver class: com.mysql.jdbc.Driver
[echo] JDBC DataSource class: com.mysql.jdbc.jdbc2.optional.MysqlDataSource
[echo] Hibernate dialect: org.hibernate.dialect.MySQLDialect
[echo] JDBC URL: seamweblogic
[echo] Database username: seamweblogic
[echo] Database password: seamweblogic
[echo]
[echo] Type './seam create-project' to create the new project

BUILD SUCCESSFUL




O próximo passo é gerar o projeto de fato, para isso executar o comando:

./seam new-project

Agora vamos testar primeiro o projeto no jboss. Nesse momento vou começar a utilizar comandos ant navegando para a raiz do projeto criado, na verdade os comandos poderiam ser dados utilizando a chamada ./seam do diretório do seam onde estava, mas como o setup do projeto no seam pode mudar e ele só armazenda os dados do último, sugiro que se acostumem com os comandos ant sempre navegando para a raiz do projeto que o sem criou, é assim que vou continuar aqui.

Com o projeto gerado, navegar então para a raiz do projeto criado e digitar o comando para fazer o deploy expandido no jboss. Nesse momento certifique-se que o servidor e a base de dados que vc especificou no setup do seam acima existem no mysql e na sua instalação de jboss respectivamente digite então o comando no shell:

ant explode

Este comando irá fazer o deploy expandido em modo de desenvolvimento no servidor jboss especificado no setup. Para testar a aplicação inicialize a isntância do jboss e navegue no browser:

http://localhost:8080/seamweblogic

Se tudo for bem deve aparecer uma página do Seam com a mensagem: Welcome to Seam

Bom isso é tudo no que diz respeito à criação do projeto. No próximo post sobre esse assunto iremos migrar o .war do jboss para rodar no weblogic.

[]s

20 de fev. de 2010

Oracle Fusion Middleware 11g - Oracle Enterprise Pack for Eclipse (OEPE)

Após a instalação e configuração de domínio do weblogic vou mostrar a integração da ferramenta de desenvolvimento da Oracle OEPE que pode ser baixada no link: http://www.oracle.com/technology/software/products/oepe/index.html.

Após baixar e descompactar a ferramenta, basta entrar na pasta eclipse e utilizar o atalho "eclipse" existente neste diretório para executá-la. O vídeo abaixo mostra a integração da ferramenta com um domínio local de weblogic server na versão 11g(10.3.2).


[]s

15 de set. de 2009

Gzip no Weblogic

Outro dia precisei que as aplicações rodando em weblogic server utilizassem recursos de compactação Gzip para conteúdos de texto, html, css e javascript. O Gzip compacta estes recursos para transimtir pela internet e posteriormente o browser descompacta o que pode aumentar sensivelmente a performance percebida pelo usuário final da aplicação em diversos casos.

No ambiente em questão o weblogic está configurado para servir também o conteúdo estático e neste caso a solução padrão no mundo java é utilizar a configuração por Filtros.

Felizmente já existe um filtro Open Source disponibilizado para o weblogic para este fim e por isso basta configurarmos o pacote para utilizá-lo. Segue um passo-a-passo.

1) Baixar o .jar com as classes do filtro Gzip que vc preferir ou então escrever e gerar seu .jar com o filtro. Se preferir utilizar um filtro já escrito seguem links com posts e código fonte para tal. Links em inglês. blog do Markus Eisele ou blog do Nagesh Susarla. Se você preferir desenvolver o seu filtro de compactação Gzip pode se basear em artigos já escritos a respeito filtros, gzip e performance no On Java, no JavaWorld ou no Java Boutique, dentre outros.

2) O segundo passo é configurar o seu filtro no web.xml da apliação web que irá utilizar o Gzip, essa configuração deve variar um pouco depedendo do filtro que for ser utilizado conforme mencionado no passo 1, portanto segue um exemplo meramente ilustrativo abaixo:


  

    GZIPFilter

    weblogicx.servlet.gzip.filter.GZIPFilter

  



  

  

    GZIPFilter

    /*.html

  



  

    GZIPFilter

    /*.htm

  



  

    GZIPFilter

    /*.log

  

  

  

    GZIPFilter

    /*.txt

  



Finalmente, para checar a compactação utilizo o web developer toolbar do firefox em Information > View Document Size mostra a compactação de cada recurso carregado em uma página. Ver exemplo nas 2 imagens abaixo(ilustrativo).

Outra possibilidade é utilizar o plugin do Apache para Weblogic Server e habilitar a configuração de compactação do Apache para recursos estáticos. []s

18 de mai. de 2009

Monitorando status e "Health" de uma Aplicação no Weblogic

Motivado por um post no javaranch fiz este script simples que checa status e saúde de uma aplicação em um servidor weblogic.

O script é bem simples e por isso estou omitindo maiores explicações. Segue o script.

#variable definitions================
username='weblogic'
password='weblogic'
urladmin='t3://localhost:7001'
appName='applicationName'
serverName='serverName'
#end variable definitions============



#connects to admin server
connect(username, password, urladmin)

cd('domainRuntime:/AppRuntimeStateRuntime/AppRuntimeStateRuntime')
#get intended state for application
intendedState = cmo.getIntendedState(appName)

print 'Intended state for app ' + intendedState

#get current real state for app in specific server
currentState = cmo.getCurrentState(appName, serverName)

print 'Current state in server '+ serverName + ' ==>> ' + currentState

cd('domainRuntime:/ServerRuntimes/'+ serverName +'/ApplicationRuntimes/'+appName)

#shows app attributes including current health.
print 'Current information for app ' + appName + ' in server ' + serverName + ' ==>> ' + ls('a')


[]s

11 de abr. de 2009

Oracle Weblogic Server Tutorial. Parte 3 - Criação de cluster Multicast

Este post mostra a criação e configuração de machine, servidores e um cluster utilizando o console de administração do domínio criado na parte 2 do tutorial. Par ver todos os posts relacionados a este tutorial clique no Título deste post!

O link do vídeo com o tutorial é: http://screencast.com/t/UBN4Zd3BixX

[]s

6 de abr. de 2009

Weblogic - Como acessar arquivos em disco

Esta é uma questão frequente nos fórums de weblogic e por isso estou postando aqui.

É comum que uma aplicação web precise acessar conteúdo estático existente em algum diretório compartilhado em servidor, disco de storage externo ou até mesmo em um diretório no Sistema operacional em ambientes não clusterizados.

No weblogic tem uma maneira bem simples de resolver este problema para isso utiliza-se uma tag no arquivo weblogic.xml que irá apontar para um diretório especificado e criará um url-pattern de acesso ao conteúdo desejado.

Para ilustrar o exemplo, suponhamos que seja desejado compartilhar o conteúdo estático que está disponível no caminho: /var/docs/weblogic/estatico no servidor onde o weblogic está instalado. Imagine que exista um arquivo chamado meuPdf.pdf que está diretamente neste diretório, para acessar este arquivo queremos que uma url direta aponte para o pdf em questão. Para isso deve-se configurar a tag virtual-directory-mapping, local-path e url-pattern no weblogic.xml:


  /var/docs/weblogic
  /estatico/*



Isso irá permitir que uma url como: http://seudominio.com/estatico/meuPdf.pdf encontre corretamente o arquivo desejado. Se houver pastas no diretório basta apendar a pasta depois do url-pattern definido para acessar corretamente o conteúdo.

Esta dica possibilita também que conteúdo estático seja disponibilizado e acessado corretamente fora do pacote dinâmico no weblogic, tornando o pacote dinâmico bem menor facilitando as atualizações.

Simples assim. Fica aí a dica.

[]s

4 de abr. de 2009

Oracle Weblogic Server Tutorial. Parte 2 - Criação de domínio

Na primeira parte deste tutorial mostrei a instalação do Oracle Weblogic Server no windows. Neste post irei mostrar a criação de um domínio que será utilizado para criação de um cluster nos próximos posts deste tutorial.

Um domínio no weblogic server é utilizado para controlar um conjunto de servidores realcionados. Tipicamente um domínio tem 1 Administration server e N servidores gerenciados por ele. Tenha em mente que um domínio do weblogic server pode se extender por vários hardwares e não tem relaçao com o conceito de domínio utilizado por sistemas operacionais. A definição direta é: Um domínio é um conjunto de servidores gerenciados por um Administration Server. Inicialmente irei utilizar apenas o meu desktop no tutorial mas este domínio pode posteriormente ser facilmente adequado para outros hardwares(Escalabilidade Horizontal).

Para entender melhor o conceito de domínios no Oracle Weblogic Server veja o site:
http://download.oracle.com/docs/cd/E12840_01/wls/docs103/domain_config/understand_domains.html

Para ver o vídeo-tutorial de configuração de domínio veja o link abaixo(5 minutos):
http://screencast.com/t/841WKSRfBUp

[]s

29 de mar. de 2009

Monitoração de domínio e gravação de thread dump automático com WLST

Outro dia me deparei com um questionamento no fórum de discussão sobre como conseguir retirar os thread dumps do Servidor de aplicações, Oracle Weblogic, em momento oportuno, ou seja, quando o ambiente estiver passando por um momento de contingência. A discussão do problema pode ser vista detalhadamente no fórum do javaranch no link: http://www.coderanch.com/t/427054/BEA-Weblogic/Issue-with-WeblogicServer

Devido a este problema decidi escrever um artigo mostrando como podemos utilizar a linguagem de scripts do Weblogic Server, Weblogic Scripting Tool(WLST), para fazer monitoramento de servidores. Um ponto importante nestes script é que ele permite inclusive que este monitoramente seja feito de forma independente do Admin Server, pois neste caso, o script mostra conexão direta com servidores gerenciados de um domínio. Para escrevê-lo estou utilizando WLST que por sua vez utiliza linguagem Jython e é padrão para configuração do Oracle Weblogic.

O script:

O script demonstrado aqui é bem simples e o que ele faz basicamente é:

1) Carregar informações de um arquivo de propriedades.

2) Tenta conectar com cada um dos servidores da lista de servidores configurada no arquivo de propriedades.

3) Verifica status do servidor e caso o servidor estiver com um número maior que o definido de threads com delay na resposta gera um thread dump do servidor para posterior análise.

Abaixo segue o código do script comentado e logo em seguida um exemplo de arquivo de propriedades que pode ser utilizado como template.

from java.util  import Properties
from java.io  import FileInputStream
from java.io  import File

#============DEFINICAO DE FUNCOES============
#funcao que carrega dados de arquivo de propriedades
def carregaArquivoPropriedades(nomeArquivo) :
    print 'carregando propriedades do arquivo: ' + nomeArquivo
    #arquivo de propriedades a ser carregado
    localizacaoArquivoPropriedadesConfiguracao = nomeArquivo    
    myProps = Properties()
    #carrega arquivo de propriedades
    myProps.load(FileInputStream(File(localizacaoArquivoPropriedadesConfiguracao)))
    return myProps

#funcao que retorna lista de todos os servidores configurados para este domínio.
def getServidoresDominio():
    print 'executando funcao getServidoresDominio']
    domainConfig()
    servidores = cmo.getServers()
    return servidores

#funcao que pega lista de servidores como parametro e verifica o status de cada um deles.
def mostraStatusServidores(servidores): 
    print '=======================STATUS dos servidores do domínio==============='
    domainRuntime()
    for servidor in servidores:
        try:
            cd('/ServerRuntimes/' + servidor.getName())
            #ls()
            print servidor.getName() + ': ' + get('State')
        except WLSTException,e:
            servidoresNaoAcessiveis.append(servidor)
    servidoresAlerta = []
    #testa novamente servidores que não estava acessíveis para ter certeza
    for servidor in servidoresNaoAcessiveis : 
        try:
            cd('/ServerRuntimes/' + servidor.getName())
            #ls()
            print servidor.getName() + ': ' + get('State')
        except WLSTException,e:
            servidoresAlerta.append(servidor)
    if len(servidoresAlerta) > 0 :
        print 'ALERTA == ALERTA == ALERTA == ALERTA == ALERTA == ALERTA =='
        print 'Os seguintes servidores estão inacessíveis para monitoração, favor checar!'
        for servidor in servidoresAlerta :
            print servidor.getName()
            
#faz checagem de memória nos servidores do domínio especificado.
def listaConfiguracoesMemoriaServidoresDomino():
    servidoresComBaixoHeapMemoria = []
    for servidor in servidores:
        try:
            cd("domainRuntime:/ServerRuntimes/" + servidor.getName() + "/JVMRuntime/" +servidor.getName())
            heapSizeMax = cmo.getHeapSizeMax()/1048576
            heapMemoriaLivre = cmo.getHeapFreeCurrent()/1048576
            heapMemoriaLivrePercentagem = cmo.getHeapFreePercent()
            #adiciona na lista de servidores com pouca memoria se servidor tiver menos de 2% de memória livre
            if heapMemoriaLivrePercentagem < 2 :
                servidoresComBaixoHeapMemoria.append(servidor)
            #memoriaMB = memoria/1048576 #transforma os bytes em MB para mostrar
            print '\n================================================================='
            print "O servidor " + servidor.getName() + " esta com :"
            print 'Memoria total alocada(MB): ' + str(heapSizeMax)
            print 'Memoria total disponivel(MB): ' + str(heapMemoriaLivre)
            print 'Memoria livre(%): ' + str(heapMemoriaLivrePercentagem)
        except WLSTException,e:
            print 'AVISO: O servidor ' + servidor.getName() + ' nao esta acessivel atraves do admin server'
    #faz novo teste de heap de memória e caso continuem com pouca memória disponível, mostra ALERTA para observação do servidor.
    for servidor in servidoresComBaixoHeapMemoria :
        try:
            cd("domainRuntime:/ServerRuntimes/" + servidor.getName() + "/JVMRuntime/" +servidor.getName())
        except WLSTException,e:
            print 'AVISO: O servidor ' + servidor.getName() + ' nao esta acessivel atraves do admin server'
            heapMemoriaLivrePercentagem = cmo.getHeapFreePercent()
            #adiciona na lista de servidores com pouca memoria se servidor tiver menos de 2% de memória livre
            if heapMemoriaLivrePercentagem < 2 :
                print 'ALERTA == ALERTA == ALERTA == ALERTA == ALE RTA == ALERTA =='
                print 'O servidor ' + servidor.getName() + ' está com heap de memória < que 2% e deve ser observado!'
#faz checagem de threads dos servidores do domínio
def checaThreadsServidoresDominio() :
    servidoresComThreadsProblematicas = []
    for servidor in servidores :
        try:
            cd("domainRuntime:/ServerRuntimes/" + servidor.getName() + "/ServerChannelRuntimes/DefaultSecure[https]")
            numeroConexoes = cmo.getConnectionsCount()
            print '==============================================='
            print 'Dados do servidor ' + servidor.getName() + ': '
            print 'Conexoes https: ' + str(numeroConexoes)
            cd('domainRuntime:/ServerRuntimes/' + servidor.getName() + '/ExecuteQueueRuntimes/weblogic.socket.Muxer')
            fila = cmo.getPendingRequestCurrentCount()
            print 'Requisicoes de usuarios pendentes: ' + str(fila)
            cd('domainRuntime:/ServerRuntimes/' + servidor.getName() + '/ThreadPoolRuntime/ThreadPoolRuntime')
            hoggingThread = cmo.getHoggingThreadCount()
            print 'Quantidade de threads com status hogging: ' + str(hoggingThread)
            print '===============================================\n'
        except WLSTException,e:
           print 'Erro servidor não acessivel para ServerRuntimes ==>> ' + servidor.getName()

#faz health check nos pools de conexao do ambiente.
def checaPoolsConexoes() :
    domainConfig()
    #recupera lista de pools de conexões configuradas no domínio.
    connectionPools = cmo.getJDBCSystemResources()
    for pool in connectionPools : 
        print pool.getName()
        cd('domainConfig:/JDBCSystemResources/' +pool.getName()+ '/JDBCResource/' +pool.getName()+ '/JDBCConnectionPoolParams/' + pool.getName())
        print '==============================================='
        print 'Dados do pool: ' + pool.getName()
        capacidadeInicialPool = cmo.getInitialCapacity()
        capacidadeMaximaPool = cmo.getMaxCapacity()
        print 'Capacidade maxima do pool: ' + str(capacidadeMaximaPool)
        cd('domainConfig:/JDBCSystemResources/' + pool.getName())
        targetServers = cmo.getTargets()
        print 'targets do pool'
        for targetServer in targetServers :
            print targetServer.getName()
#=================FIM DEFINICAO DE FUNCOES======================
propriedades = carregaArquivoPropriedades('config.properties')
username = propriedades.get('username')
password = propriedades.get('password')
url = propriedades.get('url')
connect(username, password, url)
#lista para armazenar servidores não acessíveis através do admin server.
servidoresNaoAcessiveis = []
servidores = getServidoresDominio()
mostraStatusServidores(servidores)
listaConfiguracoesMemoriaServidoresDomino()
checaThreadsServidoresDominio()
checaPoolsConexoes()
disconnect()
exit()


E o arquivo de propriedades de exemplo:
#este arquivo de propriedades é utilizado para configurar os   
#servidores em um ambiente. Todas as chaves devem ter o formato  
#do nome utilizando sempre _ (underscore) pois é o que define a   
#busca dos nomes dos elementos e separa durante a configuarção   
#no script criaInstancias.py  
USUARIO_ADMIN=user  
SENHA_ADMIN=pwd  
   
PORTA_HTTPS_SERVIDORES=443  
   
#parametro que configura com que quantidade de threads com delay o thread dump deve ser tirado para o servidor.  
PARAMETRO_THREAD_DUMP=10  
   
#Dados dos servidores a serem monitorados pelo script  
SERVIDOR_1=server1  
IP_SERVIDOR_1=xxxxxx  
  
SERVIDOR_2=server2  
IP_SERVIDOR_2=xxxxxxx  
   
SERVIDOR_3=server3  
IP_SERVIDOR_3=xxxxxx  
   
SERVIDOR_4=server4  
IP_SERVIDOR_4=xxxxxx  
   
# .... you may add as many servers as you want here...  


Para este script ficar realmente funcional eu programaria para que ele ficasse conectado com os servidores por um período definido em ciclos e que verificasse o status de cada um de tempos em tempos(3 em 3min por exemplo). E caso o servidor apresentasse algum problema considerável dispararia uma rotina que seria responsável por tirar thread dumps com intervalo de cerca de 20s entre um e outro por um período de 2 min. Os thread dumps retirados seriam de extrema utilidade para definir qual o real problema com o ambiente.

[]s

10 de mar. de 2009

Weblogic - Travamento ao clicar no Activate do Admin Console

Hoje foi um dia muito corrido no trabalho, trabalhei bastante e não deu tempo de implementar a API de persistência e nem trabalhar no módulo Struts. Começei a escrever um tópico sobre upload no struts 2 que devo terminar amanhã.

Vou então deixar uma dica rápida relativa ao weblogic 10.X. No admin console depois de clicar em Lock & Edit e editar as altarações que deseja e voltar em clicar em Activate o console trava, fica processando e nada acontece. É um erro que infelizmente vem ocorrendo com certa frequência no trabalho do dia a dia com weblogic. 
São 2 as principais e mais usuais causas deste tipo de problema: 

1) Quando o domínio do weblogic é distribuído em mais de um hardware e está configurado para conectar no nodemanager e este não está funcionando corretamente.

2) Quando alguma permissão no diretório de instalação do weblogic ou do domínio perderam a permissão de escrita ou direito de apagar arquivos, renomear etc... Isso é comum quando, por exemplo, em qualquer ambiente unix ou derivado é criado um usuário e um grupo para o weblogic como: weblogic:weblogic e alguém editou ou manipulou algum arquivo como root retirando a permissão do usuário. Isso faz com que o console tenha o mesmo comportamento de impossibilidade de ativar as alterações.

As situações acima são as que mais comumente causam o problema do aparente "travamento" ao clicar em Activate, na verdade não trava o console mas o activate nunca consegue completar. O chato desta situação é que o console não mostar nenhuma mensagem e também nada sai no log do Admin console informando o que está causando o problema, o que dificulta muito descobrir o que está acontecendo.
Fica esta dica e lembrete sobre o problema. 
[]s

16 de fev. de 2009

Certificação Weblogic 10

A Oracle liberou a nova certificação de weblogic 10 a algum tempo, vou iniciar uma revisão geral dos itens e pretendo fazer a prova em breve.

Documentos de estudos, resumos e outros materiais que utilizo para síntese dos assuntos pretendo postar aqui neste site.
O nome oficial da certificação é "Oracle WebLogic Server 10g System Administrator Certified Expert".

O link para o site oficial da oracle é: http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=283

Detalhamento dos itens cobrados nas provas, cursos recomendados e outras informações mais detalhadas veja no link: http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=41&p_exam_id=1Z0_108

Comecei a fazer um mapa mental com os tópicos do exame, postarei em breve. []s

12 de ago. de 2008

Como definir uma função com WLST?

Para definir uma função com WLST basta utilizar a instrução def que tem o formato:
def nomeFuncao(Parametros)
como no exemplo a seguir:
def carregaPropriedades(nomeArquivo):
  #carrega arquivo de propriedades
  myProps.load(FileInputStream(File(nomeArquivo)))
A função chamada carregaPropriedades é definida recebendo como parâmetro o nome do arquivo a ser carregado. Depois para chamar a função:
#chama a função definida acima
carregaPropriedades('exemplo.properties')

no exemplo acima um arquivo de propriedades chamado exemplo.properties é carregado e deve existir no mesmo diretório do script.

Segue exemplo completo, lembre-se de criar no mesmo diretório do arquivo .py um arquivo chamado exemplo.properties com chave valor no padrão .properties de java.
from java.util  import Properties
from java.io  import FileInputStream
from java.io  import File
from java.util  import Enumeration

myProps = Properties()

def carregaPropriedades(nomeArquivo):
  #carrega arquivo de propriedades
  myProps.load(FileInputStream(File(nomeArquivo)))

#chama a função definida acima
carregaPropriedades('exemplo.properties')

propertyNames = myProps.propertyNames()
while propertyNames.hasMoreElements():
  #imprime on nomes de todas as chaves carregadas do arquivo de propriedades
  chave = propertyNames.nextElement()
  print str(chave)
  print '' + myProps.getProperty(chave)


É isso, em outro artigo mostrarei como fazer herança utilizando WLST e portanto como pode-se definir funções reutilizáveis em seus scripts WLST.
[]s

5 de ago. de 2008

Configuração de log dos servidores com WLST

Para fazer a configuração de log padrão e http de um servidor utilizando WLST utilizo os seguintes comandos:

username='weblogic'
password='weblogic'
adminurl='t3://localhost:7001'

SERVIDOR='managedServer1'

DIRETORIO_LOG='/var/logs'

NOME_ARQUIVO_LOG='server.log'

# Conecta com Admin server do domínio
connect(username, password, adminurl)

edit()
startEdit()

print 'INICIANDO CONFIGURACAO DE LOG DO SERVIDOR ...'
cd('Servers/' + SERVIDOR + '/Log/' + SERVIDOR)
cmo.setFileName(DIRETORIO_LOG+ '/' + SERVIDOR + '/' + NOME_ARQUIVO_LOG)
cmo.setRotationType('byTime')
cmo.setFileTimeSpan(6)
cd('/')
#====CONFIGURANDO LOG HTTP====
cd('Servers/' + SERVIDOR + '/WebServer/' + SERVIDOR + '/WebServerLog/' + SERVIDOR)
cmo.setFileName(DIRETORIO_LOG + '/' + SERVIDOR + '/access.log')
cmo.setRotationType('byTime')
cmo.setFileTimeSpan(6)
print 'LOG DO SERVIDOR CONFIGURADO\n\n'
cd('/')
activate()


Neste caso será feita uma conexão com o Admin server rodando em localhost na porta 7001, depois no primeiro bloco navega para o MBean de log da instância passada na variável SERVIDOR e finalmente seta o arquivo de log para, neste caso, diretório /var/logs/managedServer1/server.log usando o setFileName finalmente configura o arquivo de log para rotacionar por tempo e seta o tempo para 6 horas. Depois inicia configuração do log http para isso navega para local de configuração do WebServer do servidor em questão e configura a saída para /var/logs/managedServer1/access.log, configura para rotacionar por tempo de 6 em 6 horas ativa as configurações e termina o script.

[]s

Como rodar um script WLST

Este post mostra como executar um script WLST do Oracle BEA Weblogic Server 10.

Para executar o script recomendo utilizar a JVM da BEA que vem com o Weblogic server. Para isso neste exemplo como modelo didádito irei passar o caminho completo da JVM utilizada assim como o classpath completo. No seu ambiente vc pode setar o Path e Classpath para simplificar este comando.

O Script WLST tem a extensão python .py portanto o script terá o formato xxxxx.py onde xxxxx pode ser qualquer nome de arquivo válido no sistema operacional.

Para executar o script chamado criaDominioWeblogic.py de um console DOS no windows o comando, pressupondo que vc esteja no mesmo nível do diretório onde se encontra o script mencionado, seria:

C:\bea\jrockit_150_11\bin\java -cp C:\bea\wlserver_10.0\server\lib\weblogic.jar weblogic.WLST criaDominioWeblogic.py

[]s

Criação de domínio com WLST

Script para criação de um domínio default utilizando WLST este script foi escrito para Weblogic 10 MP1.

Neste exemplo foi criado um script wlst com o nome criaDominioBasico.py com a seguinte estrutura:

#Constantes utilizadas para criação do domínio
NOME_DOMINIO='dominioTutorial'
PORTA_HTTP=7001
PORTA_HTTPS=7002


#Utiliza um template padrão do weblogic 10 como base para criação do domínio.
readTemplate("C:/bea/wlserver_10.0/common/templates/domains/wls.jar")

#Configura o Admin Server para o domínio.
cd('Servers/AdminServer')
set('ListenAddress','')
set('ListenPort', PORTA_HTTP)

#Configura porta SSL para domínio
create('AdminServer','SSL')
cd('SSL/AdminServer')
set('Enabled', 'True')
set('ListenPort', PORTA_HTTPS)

#Define a senha para usuário default do weblogic(usuario=weblogic, senha=weblogic).
cd('/')
cd('Security/base_domain/User/weblogic')
cmo.setPassword('weblogic')

#configura o domínio com os valores passados e cria o domínio
setOption('OverwriteDomain', 'true')
writeDomain('c:\\tools\\dominiosWeblogic\\' + NOME_DOMINIO)

print('Dominio chamado: ' + NOME_DOMINIO + ' criado com sucesso')

closeTemplate()
exit()

Este script utiliza WLST offline e cria um domínio do weblogic no diretorio c:\tools\dominiosWeblogic\dominioTutorial, configura a porta http para 7001 e https para 7002, cria usuário de administraçao para o domínio com nome weblogic e senha weblogic.

[]s

30 de jul. de 2008

Como capturar informações de um arquivo de propriedades utilizando WLST

Irei mostrar aqui um script criado para carregar valores de variáveis de um arquivo de propriedades.
O Script irá chamar carregamentoPropriedades.py e o arquivo configuracoes.properties.
O script carregamentoPropriedades.py segue abaixo:

#Script simples que lê um arquivo de propriedades e depois imprime em um loop as chaves e valores carregados.
#algums imports necessários
from java.util  import Properties
from java.io  import FileInputStream
from java.io  import File
from java.util  import Enumeration
#arquivo de propriedades a ser carregado
localizacaoArquivoPropriedades = 'D:\\eclipse_workspace\\scriptsWLST\src\\carregamentoArquivoProperties\\configuracoes.properties'
#instancia objeto Properties
listaPropriedades = Properties()
#carrega efetivamente o arquivo de propriedades
listaPropriedades.load(FileInputStream(File(localizacaoArquivoPropriedades))
#carrega lista Enum com os valores das chaves contidos no arquivo de propriedades.
nomesPropriedades = listaPropriedades.propertyNames()
#loop para imprimir chave=valor
while nomesPropriedades.hasMoreElements():
  #imprime on nomes de todas as chaves carregadas de um arquivo de propriedades
  #perceba que esta rotina não garante que a ordem será a mesma do arquivo carregado.
  chave = nomesPropriedades.nextElement()
  print str(chave) + '=' + listaPropriedades.getProperty(chave)


É isso, bem direto neste caso no arquivo de propriedades com a seguinte estrutura:
adminserverurl=t3://localhost:7001
usuario=weblogic
senha=weblogic


temos uma saída de console:



É isso! Note que nesta imagem estou executando o WLST utilizando o eclipse. Irei mostrar como fazer isso em uma próxima oportunidade!