Sunday, February 1, 2009

Flex 3 Builder on Mac OSX

I ran into problems installing the Flex 3 Builder Professional edition on my Mac. This was because my current version of Java was set to 1.6.0. Before you install make sure you go in your Java Preferences (from spotlight) and make sure your Java application setting is J2SE 5.0 32 Bit by dragging it to the top of the list (temporarily). Then install Flex Builder 3 from the DMG file. You will not encounter any errors in the installation.

Finally, I needed to use the latest version of Java but Flex Builder still needs to run on the 1.5 JDK. For this I went through Finder to edit

/Applications/Adobe Flex Builder3/Flex Builder.app/Contents/MacOS/FlexBuilder.ini

From here just add these lines to the top of this file so you can use the right version of Java:

-vm
/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0

-vmargs
-Xdock:icon=../Resources/flexbuilder.icns
-Xdock:name=Flex Builder
-XstartOnFirstThread
-Xms128m
-Xmx512m
-XX:MaxPermSize=256m
-XX:PermSize=64m
-Dorg.eclipse.swt.internal.carbon.smallFonts
-Dorg.eclipse.swt.internal.carbon.noFocusRing

Now when Flex Builder starts it will use the right version of Java. Go back into Java Preferences and move Java SE 6 back to the top of the list if that is what you want.

Tuesday, January 20, 2009

Grails Pitfalls and Tips

I have worked with Grails for some time now and thought I would share some of the common mistakes I have made early on. I also thought I could discuss some things that can make developing with Grails easier. Here is my short list of items:

Zero Turnaround Time

One of the convenient features of Grails is the ability to make a change and have that change be available immediately in your application. This is an obvious time saver and allows you to be more productive while developing your application. However, there are times when you will make major refactoring changes on the fly that the JVM cannot deal with. An example of this might be when you introduce something new in the middle of an existing class hierarchy. While it may appear that Grails is happy and your environment is sailing along you might see odd behaviour in the application and see some strange runtime exceptions along the way. What usually remedies this situation is instructing Grails to rebuild the internal structures in your application. This can be done by executing the following command and restarting your application:

# grails clean

Grails Console

One tool that you will want to keep in your Grails toolkit is the Grails console. This allows you to run a your application in an enviroment so you can experiment with code on the fly. One of the main reasons I do this is to try out my unit and integration code in the console before, or during, writing my tests. This is a fast way to get confidence that your test code will provide the results you want. And because you are doing this in the console you do not have to keep executing the grails test-app command to reinitialize the environment.

Since you have the full environment in the Grails console you can easily get references to your Spring beans and services. You are automatically provided a reference to the org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext class with a variable named ctx. This allows you to do things like this in the Grails console:

def service = ctx.bookStoreService
def book = service.getCurrentBook()
println "The most recent book is ${book.name} by ${book.author}"
println book.dump()
You can see all of the defined beans that Grails is aware of like this:

ctx.beanDefinitionNames.sort().each {println it}

Manually Assigning Primary Keys

Most of the time your domain objects will have autogenerated primary key values for the id field. However, I ran into a situation where I needed to manually assign a primary keys for one of my domain objects. This took a little bit of trial and error to make this work. Here is how you do this correctly:

          
String id
static mapping = {
id generator:'assigned', column:'RECORD_ID', type:'string'
}

Also note that you must set the id manually outside of the object constructor on a separate line like this:

def obj = new MyDomainObject(name:'whatever')
obj.id = 'REC000001'
obj.save(flush:true)

Not like this:

def obj = new MyDomainObjects(name:'whatever', id:'REC000001')
obj.save(flush:true)

because the value will not be saved.

Manually Triggering Quartz Jobs in Grails

Grails has an excellent plugin for managing scheduled Quartz jobs. However, I had a situation where I wanted to manually schedule a job. I could not find this in the documentation so after poking around in the source I figured out how to do this using the following technique. First you have to define the job name and group like this:

class MyValidationJob {

def name = 'MyJobName'
def group = 'MyGroup'

// your executable job method here...
}

Then you can manually trigger the job like this:

          // trigger the job manually by job name and group from your controller/service/whatever
def quartzScheduler // inject this in your class
quartzScheduler.triggerJob("MyJobName", "MyGroup")

Using Packages in the Grails

Grails provides a directory structure for your application components by convention similar to Rails. However, this can cause issues if you put your classes directly inside of these folders because they seen by Java in the default package. Using the default package can cause you issues when compiling your classes. Since we are using Groovy (and really Java) it is my opinion that you should add packages to your Groovy classes. I also think that modules in Ruby translate better than package structures at this point but we are stuck with Java constraints.

You can add packages to the provided services and domain folders and Grails will make Spring beans out of them. You just need to be careful not to use the same name for the bean twice. You just reference the bean by the name of the class. For example let's say you have a service called com.myco.service.validation.MyValidationService. Grails will expose this as a bean reference named myValidationService.


Base Classes with GORM

It is common practice that developers make a base domain class with common features of your subclassed domain objects. By defining an abstract class you can define common properties for your domain objects. There is a catch however. The GORM DSL allows you to define constraints and mappings blocks in these classes for validation purposes and defining ORM mappings respectively. The current problem is that if your subclasses have their own mappings and/or constraints defined they will override what is in your superclass instead of being merged with the superclass blocks. I am hoping that a future version of Grails addresses this issue (1.1 hopefully).


Unexpected NPEs

One of the earliest mistakes I made when working with Grails was generating NullPointerExceptions without much to decipher in the stack trace. The most common problem for me (which you will overcome quickly) was to make sure you validate your domain objects and handle the errors appropriately in your controllers. The errors object is automatically added to your domain objects and can be checked with the hasErrors method on those objects.


Viewing the Source of your GSP Files

This is just a quick tip that allows you to view the generated source of you GSP files. This is a simple as adding the 'showSource' parameter to your URL like this:

http://localhost/yourapp/yourController/list?sort=dateCreated&max=20&showSource

Monday, September 8, 2008

Generating GORM Domain Classes

I am on a project that already had a legacy database in place with about 100 tables. I did not want to create my GORM domain classes manually for my Grails project. I am surprised that I did not find any existing code to handle this code generation so I created a Groovy script to handle this. I am sure this code could use some improvements such as handling more SQL types so I will just call it a 0.1 release because it does what I needed for now. Modify the sql varible so it has the right database connection information. Also, modify the tables hash so you can control which domain classes to generate based on a [tableName:className] structure.

   1  import groovy.sql.Sql
2 import java.sql.Types
3
4 sql = Sql.newInstance("jdbc:mysql://localhost:3306/pts_development",
5 "root",
6 "password",
7 "com.mysql.jdbc.Driver")
8
9 // tables hash format => table : className
10 tables = ['PTS_REG_DTL':'Detail','PTS_REG_MST':'Master']
11 tables.each { table, className ->
12 File file = new File("${className}.groovy")
13 sb = new StringBuilder()
14
15 fieldNames = []
16 fieldTypes = []
17
18 query = "select * from ${table}"
19 sql.query(query.toString()){ rs ->
20
21 sb << "class ${className} {\n"
22
23 def meta = rs.metaData
24 if(meta.columnCount <=0) return
25
26 for(i in 1..meta.columnCount){
27
28 fieldName = meta.getColumnName(i).toLowerCase().replaceAll(/_[\w]/,{ it[1].toUpperCase()})
29 fieldNames << fieldName
30 fieldType = ""
31
32 switch(meta.getColumnType(i)) {
33 case Types.BIGINT:
34 fieldType = "Long"
35 break
36 case [Types.BINARY, Types.BIT, Types.BOOLEAN, Types.SMALLINT]:
37 fieldType = "Boolean"
38 break
39 case [Types.CHAR, Types.VARCHAR]:
40 fieldType = "String"
41 break
42 case [Types.DATE, Types.TIMESTAMP]:
43 fieldType = "Date"
44 break
45 case [Types.DECIMAL, Types.FLOAT]:
46 fieldType = "Decimal"
47 break
48 case [Types.INTEGER, Types.NUMERIC]:
49 fieldType = "Integer"
50 break
51 default:
52 fieldType = "Object"
53 }
54 fieldTypes << fieldType
55 sb << "\t${fieldType} ${fieldName}\n"
56 }
57
58 // Print out the table mappings
59 sb << "\tstatic mapping = {\n"
60 sb << "\t\ttable '${table.toString()}'\n"
61
62 for(j in 1..meta.columnCount) {
63 sb << "\t\t${fieldNames[j-1]} column:'${meta.getColumnName(j)}'\n"
64 }
65 sb << "\t}\n"
66
67 // Print out the table constraints
68 sb << "\tstatic constraints = {\n"
69
70 for(k in 1..meta.columnCount) {
71 sb << "\t\t${fieldNames[k-1]}("
72 sb << "nullable:${meta.isNullable(k) ? 'true': 'false'}"
73
74 if(fieldTypes[k] == 'String') {
75 sb << ", maxSize:${meta.getColumnDisplaySize(k)}"
76 }
77 sb << ")\n"
78 }
79 sb << "\t }\n"
80 sb << "}\n"
81 }
82 file.write(sb.toString())
83 }

This code will generate a separate file for each domain class you specified in the tables hash in the current directory. Just make sure you have your database jar file in your classpath. Here is how you could run this code from the command line:

groovy -cp .:/Users/meagle/java/api/mysql-connector-java-5.0.4/mysql-connector-java-5.0.4-bin.jar GormGenerator.groovy

Friday, August 15, 2008

Securing a Grails application with Acegi and Crowd (Revisited)

I recently had a need to combine these technologies to provide authentication and authorization with Crowd in my Grails application. I ran across a very good article that handholds you through this process. You can reference the original aricle here.

However, I ran into several issue when I tried to apply the configuration in the article. The original article uses Grails 1.0.1, the Acegi Security Plugin v0.2, and Crowd 1.3. When I attempted to follow the instructions I attempted to use Grails 1.0.3, the Acegi Security Plugin v0.3, and Crowd 1.4. If you are still reading then make sure that you continue to use 0.2.1 version of the plugin because the Crowd integration module has not been updated to reference the latest Acegi/Spring Security framework updates such as pack naming. From here I will reference where you will need to make modifications for each step that requires it in the original article.

Step 1: Grails & Acegi Installation

Again, use the Acegi Security Plugin v0.2.1

Step 2: Create Grails Application with Acegi Security

Download and install the Acegi Security Plugin v0.2.1 in your Grails project.

Step 3: Crowd Download

Download Crowd v.1.4.4 from the Atlassian website.

Step 4: Crowd Installation & Configuration

The installation and configuration is surprisingly as easy as the original author suggests. Just follow the installation instructions.

Step 5: Grails + Acegi + Crowd Integration

Make absolutely sure that you do not skip the step regarding crowd.properties. If the application name and password do not match the same values in the application configuration you will not be allowed to attempt authentication against Crowd. You can setup these values in the Crowd administration console by navigating to the Applications tab and selecting the application from the list. From there click the Details tab and ensure the name and password are set to the same values as crowd.properties. Also, make sure that the application.login.url value is modified to the correct login url. The one specified in the article should be consistent with the example.

I did follow the author's lead and copied the applicationContext-CrowdClient.xml file from the
CROWD_HOME/client/crowd-integration-client-1.4.4.jar file and positioned it in the ACEGI_APP/conf/spring/ directory and then renamed the file to resources.xml.

The modifications I had to make to resources.xml were different from the author's article. Here are the beans I added:

   1  <bean id="crowdUserDetailsService" class="com.atlassian.crowd.integration.acegi.user.CrowdUserDetailsServiceImpl">
2 <property name="authenticationManager" ref="crowdAuthenticationManager"/>
3 <property name="groupMembershipManager" ref="crowdGroupMembershipManager"/>
4 <property name="userManager" ref="crowdUserManager"/>
5 <!--<property name="authorityPrefix" value="ROLE_"/>-->
6 <property name="authorityPrefix" value=""/>
7 </bean>
8
9 <bean id="crowdAuthenticationProvider" class="com.atlassian.crowd.integration.acegi.CrowdAuthenticationProvider">
10 <property name="userDetailsService" ref="crowdUserDetailsService"/>
11 <property name="authenticationManager" ref="crowdAuthenticationManager"/>
12 <property name="httpAuthenticator" ref="httpAuthenticator"/>
13 </bean>
14
15 <bean id="crowdLogoutHandler" class="com.atlassian.crowd.integration.acegi.CrowdLogoutHandler">
16 <property name="httpAuthenticator" ref="httpAuthenticator"/>
17 </bean>
18
19 <bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
20 <constructor-arg value="/"/>
21 <constructor-arg>
22 <list>
23 <ref bean="crowdLogoutHandler"/>
24 <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
25 </list>
26 </constructor-arg>
27 <property name="filterProcessesUrl" value="/j_acegi_logout"/>
28 </bean>
29
30 <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
31 <property name="filterInvocationDefinitionSource">
32 <value>
33 CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
34 PATTERN_TYPE_APACHE_ANT
35 /images/**=#NONE#
36 /scripts/**=#NONE#
37 /styles/**=#NONE#
38 /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
39 </value>
40 </property>
41 </bean>

AcegiGrailsPlugin.groovy


Instead of making this modification to this file I put the change inside of resources.xml. If you make this modificaiton inside the plugin code and you upgrade it you will need to remember this. Instead Grails will override the authenticationManager in AcegiGrailsPlugin with this definition inside of resources.xml:

   1      <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
2 <property name="providers">
3 <list>
4 <ref local="crowdAuthenticationProvider"/>
5 <ref bean="anonymousAuthenticationProvider"/>
6 <ref bean="rememberMeAuthenticationProvider"/>
7 </list>
8 </property>
9 </bean>

Wednesday, April 30, 2008

Deploying Rails 2.0.2 applications with Tomcat 5.5.x using Warbler

After working with Rails for some time I wanted to determine how to deploy an application on Tomcat. I will discuss how to build a war file that can be used on Tomcat and show pitfalls I experienced along the way. Here are the technologies I am using for this deployment:
  • JRuby 1.1.1
  • Rails 2.0.2
  • Warbler 0.9.5
  • MySQL 5.0.4
To package up my Rails application I am using Warbler as indicated above. This is an alternative to Goldspike but allows a better packaging scheme and an easier configuration. Warble is actually a wrapper to Goldspike and includes these dependencies when you install the gem. You can read more about Warbler here.

I will assume you have Rails installed as a gem in JRuby. To make a standalone war file make sure you run this command to freeze Rails in your project:

$ jruby -S rails:freeze:gems

This will write the standard Rails gem information to your RAILS_ROOT/vendor/rails directory. Here is how you install Warbler from JRuby:

$ jruby -S gem install warbler

After this is configured switch to the root of your Rails project and execute this command:

$ jruby -S warble

This will build an exploded war file in a temporary directory within your project. This path can be changed in the warble.rb file that gets installed. Now create a Warble configuration file by executing this command since we will need it (not sure why this is done after the fact):

$ jruby -S warble config

After generating a configuration file you should consider updating the JRuby jar file that comes with Warble since you will want the latest version packaged with your war file. If you do not do this Warble will always include the original version of the JRuby jar with your war file. Add the jruby-complete-1.1.1.jar file which can be obtained here) to your RAILS_HOME/lib directory. Grab the latest Goldspike jar file and place it in your RAILS_HOME/lib directory. Now add this code to the configuration:

config.java_libs.reject! {
|lib| lib =~ /jruby-complete|goldspike/
}


This allows you to externally package your own versions of JRuby and Goldspike and reject the verions of these jar files that come bundled in the gem directory ($JRUBY_HOME/lib/ruby/gems/1.8/gems/warbler-0.9.5/lib/warbler).

Also, you can delete the exploded directory and the war file by issuing this command:

$ jruby -S warble war:clean

From this point you just move the war file to your Tomcat webapps directory and start the server. This is great when everything works. However, I was lucky enough to run into some issues while making this happen.

The first issue occurred when I started Tomcat with the war file I built with Warble (remember that this is using Goldspike under the covers) and got this error message in the Tomcat logs:

“Could not load Rails. See the logs for more details.”

Yipee! So when I went to look in the Tomcat logs there was no additional information. Great! It turns out that the stack trace output gets swallowed on a Mac. This is fairly easy to fix (but should be patched by the Goldspike team) by modifying the source code for the goldspike-1.6.1.jar file to emit the full stack trace. Grab the latest Goldspike code from here:

svn checkout
svn://rubyforge.org/var/svn/jruby-extras/trunk/rails-integration


You will have to modify src/main/java/org/jruby/webapp/RailsFactory.java like this:

} catch (RaiseException e) {
//added this line so the full stack trace is shown
e.printStackTrace();

logRubyException("Failed to load Rails", e);
throw new ServletException(
"Could not load Rails. See the logs for more details.");
}
After you rebuild the Goldspike jar add it to your RAILS_ROOT/lib. Now re-warble your war file and put it on your Tomcat server. Now you should be able to find your error. In my case I was not making a connection to my database. I was clearly missing gems in my war file. Great!

This really is not too big of a deal. You can explain to Warbler what gems need to be packaged with your war file. Here is a snippet from my warble.rb file that shows how I included the missing gems:

# Gems to be packaged in the webapp. Note that Rails
#
gems are added to this list if vendor/rails is not
#
present, so be sure to include rails if you overwrite
# the value

config.gems = ["activerecord-jdbc-adapter", "jruby-openssl", "activerecord-jdbcmysql-adapter", "jdbc-mysql"]


Alright re-warble and... still no connectivity. Awesome! This time I was missing my MySQL jar file in my war file and the activerecord-jdbcmysql-adapter gem could not communicate with the implementation jar. To fix this copy your MySQL jar file to the RAILS_ROOT/lib directory in your Rails project.

One more re-warbling and more good news:

“Rails Error: No :secret given to the #protect_from_forgery call. Set that or use a session store capable of generating its own keys (Cookie Session Store)”.

This is a known bug with Goldspike and Rails 2.0. So edit your web.xml file and add the following:
<context-param>
<param-name>jruby.session_store</param-name>
<!-- This value really means let Rails take care
of session store -->
<param-value>db</param-value>
</context-param>
OK, please just one more re-warbling and deployment to Tomcat and a successful standalone war file has been created and deployed. *birds singing*

I would also suggest increasing the Java memory setting in the JAVA_OPTS of Tomcat to at least -Xmx512m to improve performance. Also keep in mind that Warble is configured to use the production environment for your Rails application so make the appropriate migrations before starting the application. You can make further modification to the Goldspike configuration within the warble.rb file to tweak the pool of Rails runtimes. Once I made these changes it was pretty transparent where I was running my Rails application.

I hope this saves other people time when running into issues. This was kind of a frustrating process since it should be a simple one line deployment. However, I was happy with the end results.

Friday, January 18, 2008

Migrating to Grails?

The last time I looked at Grails it was around version 0.4. Now that we are approaching a 1.0 release I wanted to see how much further the Grails team has advanced. I wanted to start by using my existing Spring and Hibernate components from my Java project (I am currently using Stripes for our presentation layer). Benefits for doing this might include:
  • Abstracting your Java domain model and services so they are not coupled to Grails.

  • The ability to continue using your Java services and model objects outside of Web applications or have the ability to integrate with other Web presentation frameworks.

  • A migration path to Groovy if you want to rid yourself of straight Java altogether. I am sure that there would be massive redux in LOC. For me it was experimenting with the intersection of my experiences with Rails and Java Web development.

Does this mean that if you reuse your Hibernate Java domain objects you do not get all of the GORM features like (order.save())? No, your domain objects transparently take full advantage of the mixed in methods in Grails. You might find that the services you are reusing from Spring are mostly passthroughs to DAO that you do not need anymore because of GORM. Here is a trivial example showing how to use a Grails controller to use existing Spring services to perform DAO operations and how to use your Hibernate domain objects directly as GORM objects:


UserService userService  // This is injected in via auto-wiring

def index = {

// Using Java Services
def user = userService.find(1, User.class)
println user.firstName
user.firstName = 'Mark'
userService.save user
println User.get(1).firstName

// Using strait Grails
user = User.get(1)
println user.firstName
user.firstName = 'Phil'
user.save()
println User.get(1).firstName
}

Here is how we took our annotated Hiberate classes so Grails would recognize them:

Edit your hibernate.cfg.xml file in the GRAILS_APP/grails_app/conf/hibernate directory and add your domain objects:

<!DOCTYPE hibernate-configuration SYSTEM
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="com.meagle.common.bo.Address" />
<mapping class="com.meagle.common.bo.User" />
</session-factory>
</hibernate-configuration>
In your DataSource.groovy configuration file add the configClass line to your datasource configuration so your annotated Hibernate classes will be recognized by Grails:
dataSource {
pooled = false
driverClassName = "com.ibm.db2.jcc.DB2Driver"
username = "meagle"
password = "******"
configClass
=org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration.class
}
Here is how you expose your existing Spring beans to your Grails application:
  1. Edit your GRAILS_APP/grails_app/conf/spring/resources.xml file and add the following line:
    <import resource="applicationContext-core.xml"/>
    This tells Grails to include your Spring resources (We put our Spring config file in the same directory as the resources.xml file).

  2. Make sure all of your Spring and Hibernate domain objects written in Java are on the classpath. We put ours in a jar file in the GRAILS_APP/lib directory.

One gotcha here to remember is that your Spring configuration file should not include any definition to a SessionFactory and your services and DAOs that reference a SessionFactory needs to be the name "sessionFactory". Otherwise, you will end up with multiple session factory objects which is probably not what you want.

Overall I am very impressed with Grails at this point and would challenge Java developers to take a serious look at this framework. If you are fortunate enough to have IntelliJ 7 then there is decent plugin support for building Grails applications.

Saturday, December 15, 2007

NetBeans 6.0 and Rails

I have been looking for a good Rails IDE and think I have found one. I was using TextMate which has lots of great quick templating commands for Rails concepts for migrations, rhtml, and navigating between files and methods. However, I enjoy working with IDEs and tried some Eclipse based versions but felt that they were inadequate. My paying job at the time is mostly Java based and I use IntelliJ which makes my development more productive for that type of development.

I had not looked at NetBeans in some time because most Java developers were using Eclipse and that was fine for me at the time. So when I saw that NetBeans had a Rails related version of their IDE I was willing to give it another look. I can only say that for me this is a very nice IDE that has full functionality around the way I develop with Rails. Here are some of the features I find handy:

  • A simple IDE layout for components that is similar to IntelliJ. There are no unnecessary perspectives that Eclipse users have.
  • Support for auto-completion of methods with rdoc helpers.
  • Debugging capabilites that are simple to use.
  • Integration with version control repositories like Subversion.
  • Tools to manage your Gems and Plugins from the Tools menu
  • Easy navigation between Rails controllers and views as well as opening files via keystrokes.
  • Decent refactoring built in
  • Generators for creating Rails components.
  • Menus to run Rake and Migration scripts
  • Built in functionality to start a Rails console from your project
  • It works great on my Mac and much more than I expected...


  • Just to whet your appetite to get you more excited about this IDE here are a couple of screenshots from how I use this IDE:
    Here is what it looks like when editing files with code completion and quick docs:



    And here is a shot of what debugging looks like in NetBeans:



    If you are working on a Mac make sure you look at this link for setting up the fast debugger gem. You will also need to have XCode installed for compilation.
    I think you will agree that this is the best IDE for Rails at this time.