sexta-feira, 27 de novembro de 2009

Remover acentuações de uma NSString

Parece que o tratamento de caracteres acentuados é um dos grandes pontos fracos da maioria das linguagens por aí... Ainda estou pra ver uma linguagem onde isso seja feito de forma simples usando somente as bibliotecas basicas... mas enfim. Após dar várias cabeçadas fuçando no Google e na documentação do Xcode, aí está minha solução:

NSString *stringFrom = @"áéíóú";
NSData  *data = [stringFrom  dataUsingEncoding: NSASCIIStringEncoding  allowLossyConversion: YES ];
NSString  *stringTo = [[ NSString   alloc]  initWithData:data  encoding: NSASCIIStringEncoding];  

quinta-feira, 30 de julho de 2009

Weblogic 8.1.x on Linux 64

Recently I ran into a problem while trying to run Weblogic 8.1.3 on my Ubuntu 9.04 64bit machine... The server startup failed with the following stacktrace:
The WebLogic Server did not start up properly.
java.lang.UnsatisfiedLinkError: no weblogicunix1 in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1491)
        at java.lang.Runtime.loadLibrary0(Runtime.java:788)
        at java.lang.System.loadLibrary(System.java:834)
        at weblogic.platform.Unix.(Unix.java:14)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
        at java.lang.Class.newInstance0(Class.java:308)
        at java.lang.Class.newInstance(Class.java:261)
        at weblogic.platform.OperatingSystem.getOS(OperatingSystem.java:116)
        at weblogic.t3.srvr.SetUIDManager.init(SetUIDManager.java:51)
        at weblogic.t3.srvr.T3Srvr.initializeHere(T3Srvr.java:777)
        at weblogic.t3.srvr.T3Srvr.initialize(T3Srvr.java:670)
        at weblogic.t3.srvr.T3Srvr.run(T3Srvr.java:344)
        at weblogic.Server.main(Server.java:32)
Reason: no weblogicunix1 in java.library.path
It turns out that the libraries for the ia64 arch that comes bundled with the WL JRE cause the server to fail, so you must manually set the LD_LIBRARY_PATH variable. Just run the command below before starting the server:
export LD_LIBRARY_PATH="${BEA_HOME}/weblogic81/server/lib/linux/i686/"
Note that the ${BEA_HOME} variable must point to your Weblogic installation folder.

segunda-feira, 6 de julho de 2009

Começando com o Maven

Depois de algum tempo desenvolvendo em Java é comum que você esbarre em alguns problemas a medida que seus projetos vão crescendo, e ficando cada vez mais complexos. Por exemplo:
  • Controlar as bibliotecas que você utiliza, e as bibliotecas que essas precisam
  • Manter sincronizados vários projetos, que dependem uns dos outros
  • Ter que se lembrar de gerar vários artefatos, para consumir ou expor webservices, processar XML ou então fazer enhance das classes de domínio em um projeto JPA
  • Configurar todo projeto do zero para novos desenvolvedores
  • Configurar builds automáticos para integração contínua
  • Gerar estatísticas a respeito do seu projeto
Alguns desses problemas podem ser resolvidos por IDEs mais espertas, outros por ferramentas como o ANT. Mas depender de uma IDE específica pode limitar a capacidade de automatizar os builds do seu projeto, e o ANT sozinho não resolve o problema das dependências do projeto. Para resolver esses problemas existe o Apache Maven. Segundo o seu site Maven é:
... a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.
Ou seja, utilizando um arquivo de meta-dados, você consegue descrever todo o seu projeto, e os recursos necessários para poder desenvolver, compilar e executar tudo de forma automática. O arquivo que descreve esses meta-dados se chama pom.xml, e por convenção fica na raiz do seu projeto. E falando em convenção, o Maven utiliza o conceito de conversão sobre configuração, que no geral significa que se você fizer as coisas do jeito que o Maven espera não vai precisar configurar quase nada. A estrutura de pastas de um projeto web configurado para utilizar Maven é igual a que está na figura abaixo: Um arquivo pom.xml bem simples é parecido com o exemplo abaixo:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>mixer</artifactId>
<groupId>com.b2w.m3</groupId>
<version>2.5-SNAPSHOT</version>
</parent>
<artifactId>web</artifactId>
<groupId>${parent.groupId}</groupId>
<version>${parent.version}</version>
<packaging>war</packaging>
<name>web</name>
<build>
<resources>
   <resource>
       <filtering>true</filtering>
       <directory>src/main/webapp</directory>
       <includes>
           <include>**/*.html</include>
       </includes>
   </resource>
</resources>
<plugins>
   <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-resources-plugin</artifactId>
   </plugin>
</plugins>
</build>
<dependencies>
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>
   <scope>provided</scope>
</dependency>
</dependencies>
</project>
O pom.xml tem 3 partes básicas:
  1. identificação do projeto - Aqui você vai definir as informações que irão diferenciar o seu projeto dos demais. Essas informações são muito importantes para que o Maven identifique o seu projeto no meio dos demais que estão em seu repositório, assim você vai poder, por exemplo, re-utilizar o seu projeto futuramente incluindo ele como dependência de outro projeto.
  2. configurações de build - Essa é a parte onde definimos como o JDK vai processar o seu projeto, configurações de compilador, versão do código e JVM. Além de podermos configurar qualquer pré ou pós processamento que seja necessário. Como por exemplo, geração de artefatos a partir de um WSDL, ou então enhance das classes de persistência.
  3. dependências - São as bibliotecas e frameworks que você utiliza em seu projeto, o maven faz download e gerencia qualquer dependência adicional. Por exemplo, o hibernate precisa do antlr, mas você não precisa declara-lo, o Maven automaticamente baixa e o coloca no classpath do projeto.
Quem começa a utilizar o Maven normalmente faz para poder gerenciar as dependências do projeto, então vamos começar assim também. Depois de instalar o Maven, vamos configurar um projeto básico com Spring e Hibernate, e configurar o Eclipse para utilizar esse projeto.A boa notícia é que não precisamos criar toda a estrutura do projeto manualmente, podemos usar o plugin archetype para criar o esqueleto do nosso projeto. Execute o comando abaixo para ter uma lista de templates básicos para escolher:
mvn archetype:generate
Para o nosso teste vamos criar uma aplicação web simples, então escolha a opção com o texto:
internal -> maven-archetype-webapp (A simple Java web application)
O plugin vai perguntar algumas informações básicas sobre o projeto, responda como listado abaixo:
[INFO] artifact org.apache.maven.archetypes:maven-archetype-webapp: checking for updates from central
Define value for groupId: : com.teste
Define value for artifactId: : webapp
Define value for version:  1.0-SNAPSHOT: :
Define value for package:  com.teste: :
Confirm properties configuration:
groupId: com.teste
artifactId: webapp
version: 1.0-SNAPSHOT
package: com.teste
Se tudo ocorreu bem, deve ter sido criada uma pasta webapp com uma estrutura de pastas parecida com a que eu mostrei acima. Mais importante, você tem um arquivo pom.xml novinho em folha, pronto para ser utilizado. Vamos ver o que tem dentro?
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.teste</groupId>
<artifactId>webapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>webapp Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
 <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>3.8.1</version>
   <scope>test</scope>
 </dependency>
</dependencies>
<build>
 <finalName>webapp</finalName>
</build>
</project>
Você pode ver os valores que preenchemos, e mais uma dependência do JUnit, para podermos executar testes unitários. Pois bem, vamos adicionar mais algumas dependências, adicione a esse pom:
    <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>servlet-api</artifactId>
         <version>2.5</version>
         <scope>provided</scope>
     </dependency>
     <dependency>
         <groupId>org.hibernate</groupId>
         <artifactId>hibernate-core</artifactId>
         <version>3.3.1.GA</version>
     </dependency>
     <dependency>
         <groupId>org.hibernate</groupId>
         <artifactId>hibernate-annotations</artifactId>
         <version>3.3.1.GA</version>
     </dependency>
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring</artifactId>
         <version>2.5.5</version>
     </dependency>
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-mock</artifactId>
         <version>2.0.8</version>
         <scope>test</scope>
     </dependency>
     <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-simple</artifactId>
         <version>1.5.2</version>
     </dependency>
     <dependency>
         <groupId>org.hsqldb</groupId>
         <artifactId>hsqldb</artifactId>
         <version>1.8.0.10</version>
     </dependency>
     <dependency>
         <groupId>commons-dbcp</groupId>
         <artifactId>commons-dbcp</artifactId>
         <version>1.2.2</version>
     </dependency>
     <dependency>
         <groupId>javassist</groupId>
         <artifactId>javassist</artifactId>
         <version>3.8.0.GA</version>
     </dependency>
Depois de modificar o pom.xml chegou a hora de integrar o Maven com sua IDE. Se você utiliza Netbeans a partir da versão 6.5 não precisa fazer nada, ele reconhece projetos Maven nativamente, mas caso prefira o Eclipse existem alguns passos a serem dados. Para gerar os arquivos de projeto que o eclipse precisa, execute esse comando dentro da pasta do projeto maven:
mvn -Dwtpversion=2.0 eclipse:eclipse -DdownloadSources=true -DdownloadJavadocs=true
Para criar as variáveis necessárias para o Eclipse encontrar as bibliotecas baixadas pelo Maven, execute o comando abaixo, colocando o caminho para o workspace que você utiliza:
mvn eclipse:configure-workspace -Declipse.workspace=/Projects/Workspaces/maven_tut/ 
O próximo passo é instalar um plugin que integre o Maven ao Eclipse, como o m2eclipse ou o eclipse iam. Se você não quer esperar meu próximo passo-a-passo sobre o Maven, eu recomendo ler o ótimo Better Builds with Maven, que está disponível como PDF AQUI.

sexta-feira, 3 de julho de 2009

Weblogic OSX and Java 1.6 doesn't mix

If you ever see a stacktrace like the one listed below, change the default version of you JVM from 1.6 to 1.5, and them restart your IDE and the Weblogic Server.
javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException
        at weblogic.deploy.api.spi.deploy.WebLogicDeploymentManagerImpl.(WebLogicDeploymentManagerImpl.java:121)
        at weblogic.deploy.api.spi.factories.internal.DeploymentFactoryImpl.getDeploymentManager(DeploymentFactoryImpl.java:84)
        at weblogic.deploy.api.tools.SessionHelper.getDeploymentManager(SessionHelper.java:432)
        at weblogic.deploy.api.tools.SessionHelper.getDeploymentManager(SessionHelper.java:450)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.netbeans.modules.j2ee.weblogic9.WLDeploymentFactory.getVendorDeploymentManager(WLDeploymentFactory.java:162)
        at org.netbeans.modules.j2ee.weblogic9.WLDeploymentManager.getDeploymentManager(WLDeploymentManager.java:137)
        at org.netbeans.modules.j2ee.weblogic9.WLDeploymentManager.getTargets(WLDeploymentManager.java:578)
        at org.netbeans.modules.j2ee.deployment.impl.ServerInstance.getTargetMap(ServerInstance.java:539)
        at org.netbeans.modules.j2ee.deployment.impl.ServerInstance.getTargets(ServerInstance.java:497)
        at org.netbeans.modules.j2ee.deployment.impl.ServerInstance.initCoTarget(ServerInstance.java:1555)
        at org.netbeans.modules.j2ee.deployment.impl.ServerInstance._start(ServerInstance.java:1360)
        at org.netbeans.modules.j2ee.deployment.impl.ServerInstance.startTarget(ServerInstance.java:1297)
        at org.netbeans.modules.j2ee.deployment.impl.ServerInstance.startTarget(ServerInstance.java:1102)
        at org.netbeans.modules.j2ee.deployment.impl.ServerInstance.start(ServerInstance.java:979)
        at org.netbeans.modules.j2ee.deployment.impl.TargetServer.startTargets(TargetServer.java:498)
        at org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment.deploy(Deployment.java:181)
        at org.netbeans.modules.maven.j2ee.ExecutionChecker.performDeploy(ExecutionChecker.java:155)
        at org.netbeans.modules.maven.j2ee.ExecutionChecker.executionResult(ExecutionChecker.java:111)
        at org.netbeans.modules.maven.execute.MavenCommandLineExecutor.run(MavenCommandLineExecutor.java:187)
        at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:151)
Caused by: weblogic.deploy.api.spi.exceptions.ServerConnectionException
        at weblogic.deploy.api.spi.deploy.internal.ServerConnectionImpl.init(ServerConnectionImpl.java:143)
        at weblogic.deploy.api.spi.deploy.WebLogicDeploymentManagerImpl.getNewConnection(WebLogicDeploymentManagerImpl.java:148)
        at weblogic.deploy.api.spi.deploy.WebLogicDeploymentManagerImpl.(WebLogicDeploymentManagerImpl.java:118)
        ... 23 more
Caused by: javax.naming.CommunicationException [Root exception is java.net.ConnectException: t3://localhost:7001: Destination unreachable; nested exception is: 
        java.net.ConnectException: Connection refused; No available router to destination]
        at weblogic.jndi.internal.ExceptionTranslator.toNamingException(ExceptionTranslator.java:40)
        at weblogic.jndi.WLInitialContextFactoryDelegate.toNamingException(WLInitialContextFactoryDelegate.java:773)
        at weblogic.jndi.WLInitialContextFactoryDelegate.getInitialContext(WLInitialContextFactoryDelegate.java:363)
        at weblogic.jndi.Environment.getContext(Environment.java:307)
        at weblogic.jndi.Environment.getContext(Environment.java:277)
        at weblogic.jndi.Environment.createInitialContext(Environment.java:200)
        at weblogic.jndi.Environment.getInitialContext(Environment.java:184)
        at weblogic.jndi.Environment.getInitialContext(Environment.java:162)
        at weblogic.deploy.api.spi.deploy.internal.ServerConnectionImpl.getContext(ServerConnectionImpl.java:330)
        at weblogic.deploy.api.spi.deploy.internal.ServerConnectionImpl.getEnvironment(ServerConnectionImpl.java:302)
        at weblogic.deploy.api.spi.deploy.internal.ServerConnectionImpl.init(ServerConnectionImpl.java:141)
        ... 25 more
Caused by: java.net.ConnectException: t3://localhost:7001: Destination unreachable; nested exception is: 
        java.net.ConnectException: Connection refused; No available router to destination
        at weblogic.rjvm.RJVMFinder.findOrCreate(RJVMFinder.java:204)
        at weblogic.rjvm.ServerURL.findOrCreateRJVM(ServerURL.java:154)
        at weblogic.jndi.WLInitialContextFactoryDelegate$1.run(WLInitialContextFactoryDelegate.java:342)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
        at weblogic.security.service.SecurityManager.runAs(Unknown Source)
        at weblogic.jndi.WLInitialContextFactoryDelegate.getInitialContext(WLInitialContextFactoryDelegate.java:337)
        ... 33 more
Caused by: java.rmi.ConnectException: Destination unreachable; nested exception is: 
        java.net.ConnectException: Connection refused; No available router to destination
        at weblogic.rjvm.ConnectionManager.bootstrap(ConnectionManager.java:472)
        at weblogic.rjvm.ConnectionManager.bootstrap(ConnectionManager.java:323)
        at weblogic.rjvm.RJVMManager.findOrCreateRemoteInternal(RJVMManager.java:263)
        at weblogic.rjvm.RJVMManager.findOrCreate(RJVMManager.java:206)
        at weblogic.rjvm.RJVMFinder.findOrCreateRemoteServer(RJVMFinder.java:226)
        at weblogic.rjvm.RJVMFinder.findOrCreateRemoteCluster(RJVMFinder.java:308)
        at weblogic.rjvm.RJVMFinder.findOrCreate(RJVMFinder.java:194)
        ... 38 more
javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException
        at weblogic.deploy.api.spi.deploy.WebLogicDeploymentManagerImpl.(WebLogicDeploymentManagerImpl.java:121)
        at weblogic.deploy.api.spi.factories.internal.DeploymentFactoryImpl.getDeploymentManager(DeploymentFactoryImpl.java:84)
        at weblogic.deploy.api.tools.SessionHelper.getDeploymentManager(SessionHelper.java:432)
        at weblogic.deploy.api.tools.SessionHelper.getDeploymentManager(SessionHelper.java:450)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.netbeans.modules.j2ee.weblogic9.WLDeploymentFactory.getVendorDeploymentManager(WLDeploymentFactory.java:162)
        at org.netbeans.modules.j2ee.weblogic9.WLDeploymentManager.getDeploymentManager(WLDeploymentManager.java:137)
        at org.netbeans.modules.j2ee.weblogic9.WLDeploymentManager.getTargets(WLDeploymentManager.java:578)
        at org.netbeans.modules.j2ee.deployment.impl.ServerInstance.getTargetMap(ServerInstance.java:539)
        at org.netbeans.modules.j2ee.deployment.impl.ServerInstance.getTargets(ServerInstance.java:497)
        at org.netbeans.modules.j2ee.deployment.impl.ServerString.getTargets(ServerString.java:114)
        at org.netbeans.modules.j2ee.deployment.impl.ServerString.toTargets(ServerString.java:152)
        at org.netbeans.modules.j2ee.deployment.impl.TargetServer.startTargets(TargetServer.java:502)
        at org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment.deploy(Deployment.java:181)
        at org.netbeans.modules.maven.j2ee.ExecutionChecker.performDeploy(ExecutionChecker.java:155)
        at org.netbeans.modules.maven.j2ee.ExecutionChecker.executionResult(ExecutionChecker.java:111)
        at org.netbeans.modules.maven.execute.MavenCommandLineExecutor.run(MavenCommandLineExecutor.java:187)
        at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:151)
Caused by: weblogic.deploy.api.spi.exceptions.ServerConnectionException
        at weblogic.deploy.api.spi.deploy.internal.ServerConnectionImpl.init(ServerConnectionImpl.java:143)
        at weblogic.deploy.api.spi.deploy.WebLogicDeploymentManagerImpl.getNewConnection(WebLogicDeploymentManagerImpl.java:148)
        at weblogic.deploy.api.spi.deploy.WebLogicDeploymentManagerImpl.(WebLogicDeploymentManagerImpl.java:118)
        ... 20 more
Caused by: javax.naming.CommunicationException [Root exception is java.rmi.UnmarshalException: failed to unmarshal class weblogic.security.acl.internal.AuthenticatedUser; nested exception is: 
        java.io.StreamCorruptedException: invalid type code: 31]
        at weblogic.jndi.internal.ExceptionTranslator.toNamingException(ExceptionTranslator.java:74)
        at weblogic.jndi.internal.ExceptionTranslator.toNamingException(ExceptionTranslator.java:32)
        at weblogic.jndi.WLInitialContextFactoryDelegate.toNamingException(WLInitialContextFactoryDelegate.java:773)
        at weblogic.jndi.WLInitialContextFactoryDelegate.pushSubject(WLInitialContextFactoryDelegate.java:673)
        at weblogic.jndi.WLInitialContextFactoryDelegate.newContext(WLInitialContextFactoryDelegate.java:466)
        at weblogic.jndi.WLInitialContextFactoryDelegate.getInitialContext(WLInitialContextFactoryDelegate.java:373)
        at weblogic.jndi.Environment.getContext(Environment.java:307)
        at weblogic.jndi.Environment.getContext(Environment.java:277)
        at weblogic.jndi.Environment.createInitialContext(Environment.java:200)
        at weblogic.jndi.Environment.getInitialContext(Environment.java:184)
        at weblogic.jndi.Environment.getInitialContext(Environment.java:162)
        at weblogic.deploy.api.spi.deploy.internal.ServerConnectionImpl.getContext(ServerConnectionImpl.java:330)
        at weblogic.deploy.api.spi.deploy.internal.ServerConnectionImpl.getEnvironment(ServerConnectionImpl.java:302)
        at weblogic.deploy.api.spi.deploy.internal.ServerConnectionImpl.init(ServerConnectionImpl.java:141)
        ... 22 more
Caused by: java.rmi.UnmarshalException: failed to unmarshal class weblogic.security.acl.internal.AuthenticatedUser; nested exception is: 
        java.io.StreamCorruptedException: invalid type code: 31
        at weblogic.rjvm.ResponseImpl.unmarshalReturn(ResponseImpl.java:229)
        at weblogic.rmi.internal.BasicRemoteRef.invoke(BasicRemoteRef.java:224)
        at weblogic.common.internal.RMIBootServiceImpl_1001_WLStub.authenticate(Unknown Source)
        at weblogic.security.acl.internal.Security$1.run(Security.java:185)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
        at weblogic.security.service.SecurityManager.runAs(Unknown Source)
        at weblogic.security.acl.internal.Security.authenticate(Security.java:181)
        at weblogic.jndi.WLInitialContextFactoryDelegate.authenticateRemotely(WLInitialContextFactoryDelegate.java:734)
        at weblogic.jndi.WLInitialContextFactoryDelegate.pushSubject(WLInitialContextFactoryDelegate.java:667)
        ... 32 more
Caused by: java.io.StreamCorruptedException: invalid type code: 31
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1356)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
        at weblogic.utils.io.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:195)
        at weblogic.rjvm.MsgAbbrevInputStream.readObject(MsgAbbrevInputStream.java:565)
        at weblogic.utils.io.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:191)
        at weblogic.rmi.internal.ObjectIO.readObject(ObjectIO.java:62)
        at weblogic.rjvm.ResponseImpl.unmarshalReturn(ResponseImpl.java:227)
        ... 40 more


quarta-feira, 1 de julho de 2009

Debug Grails with app-engine plugin on NetBeans 6.7

Grails has plugin that adds support for Google AppEngine, and the recently released Netbeans 6.7 has a great support for Grails development. But, how do you make everything work together? First of all, when you install the AppEngine plugin on a Grails project it will refuse to run using the default Grails run-app command, you'll have to use the app-engine run command instead. So, to run your application you'll have to right-click you project root and select Run Grails Command... from the context menu. Then you'll run the app-engine task using run --debug as the parameters, to launch your application with remote debug enabled. When you hit the Run button, the application will launch, and at some point the following message will appear in the Output console:
[java] Listening for transport dt_socket at address: 9999
This means that the JVM is expecting a connection for debug sessions on port 9999. Now we just have to attach the debugger: And that's it! Now the application will stop at your break-points, show the variables and everything you would expect from a debug session.