Friday September 18, 2009
Popular Ruby-on-Rails applications on GlassFish v3 – Redmine, Typo, Substruct
Content available at: http://blog.arungupta.me/2009/09/redmine-typo-mephisto-on-glassfish-v3/
Posted by Arun Gupta in web2.0 | Comments[0]
|
|
|
|
|
Tuesday August 11, 2009
TOTD #91: Applying Java EE 6 "web-fragment.xml" to Apache Wicket - Deploy on GlassFish v3
"Extensibility" is a major theme of Java EE 6.
This theme enables seamless pluggability of other popular Web
frameworks with Java EE 6.
Before
Java EE 6, these frameworks have to rely upon registering servlet
listeners/filters in "web.xml" or some other similar mechanism to
register the framework with the Web container. Thus your application
and framework deployment descriptors are mixed together. As an
application developer you need to figure out the magical descriptors of
the framework that will make this registration.
What if you are
using multiple frameworks ? Then "web.xml" need to have multiple of
those listeners/servlets. So your deployment descriptor becomes
daunting and maintenance nightmare even before any application
deployment artifacts are added.
Instead you should focus on your
application descriptors and let the framework developer provide the
descriptors along with their jar file so that the registration is
indeed magical.
For that, the Servlet
3.0 specification introduces "web module deployment
descriptor fragment" (aka "web-fragment.xml"). The spec defines it as:
A
web fragment is a logical partitioning of the web app in such a way
that the frameworks being used within the web app can define all the
artifacts without asking devlopers to edit or add information in the
web.xml.
Basically, the framework configuration
deployment descriptor can now be defined in "META-INF/web-fragment.xml"
in the JAR file of the framework. The Web container picks up and use
the configuration for registering the framework. The spec clearly
defines the rules around ordering, duplicates and other complexities.
TOTD
#86 explained how to get started with Apache Wicket on
GlassFish. This Tip Of The Day (TOTD) explains
how to
leverage "web-fragment.xml" to deploy a Wicket application on
GlassFish v3. The basic concepts are also discussed here.
For the "Hello World" app discussed in TOTD
#86, the generated "web.xml" looks like:
| <?xml version="1.0"
encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>helloworld</display-name> <!-- There are three means to configure Wickets configuration mode and they are tested in the order given. 1) A system property: -Dwicket.configuration 2) servlet specific <init-param> 3) context specific <context-param> The value might be either "development" (reloading when templates change) or "deployment". If no configuration is found, "development" is the default. --> <filter> <filter-name>wicket.helloworld</filter-name> <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class> <init-param> <param-name>applicationClassName</param-name> <param-value>org.glassfish.samples.WicketApplication</param-value> </init-param> </filter> <filter-mapping> <filter-name>wicket.helloworld</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app> |
|
<dependencies> . . . <!-- web-fragment --> <dependency> <groupId>org.glassfish.extras</groupId> <artifactId>wicket-quickstart-web-fragment</artifactId> <version>1.0</version> <scope>runtime</scope> </dependency> </dependencies> . . . <repositories> <repository> <id>maven2-repository.dev.java.net</id> <name>Java.net Repository for Maven</name> <url>http://download.java.net/maven/2/</url> </repository> </repositories> |
| <web-fragment> <filter> <filter-name>wicket.helloworld</filter-name> <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class> <init-param> <param-name>applicationClassName</param-name> <param-value>org.glassfish.samples.WicketApplication</param-value> </init-param> </filter> <filter-mapping> <filter-name>wicket.helloworld</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-fragment> |
|
<plugins> . . . <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.1-beta-1</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> . . . </plugins> |
| helloworld-1.0-SNAPSHOT helloworld-1.0-SNAPSHOT/META-INF helloworld-1.0-SNAPSHOT/WEB-INF helloworld-1.0-SNAPSHOT/WEB-INF/classes helloworld-1.0-SNAPSHOT/WEB-INF/classes/log4j.properties helloworld-1.0-SNAPSHOT/WEB-INF/classes/org helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish/samples helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish/samples/HomePage.class helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish/samples/HomePage.html helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish/samples/WicketApplication.class helloworld-1.0-SNAPSHOT/WEB-INF/lib helloworld-1.0-SNAPSHOT/WEB-INF/lib/log4j-1.2.14.jar helloworld-1.0-SNAPSHOT/WEB-INF/lib/slf4j-api-1.4.2.jar helloworld-1.0-SNAPSHOT/WEB-INF/lib/slf4j-log4j12-1.4.2.jar helloworld-1.0-SNAPSHOT/WEB-INF/lib/wicket-1.4.0.jar helloworld-1.0-SNAPSHOT/WEB-INF/lib/wicket-quickstart-web-fragment-1.0.jar |

Posted by Arun Gupta in web2.0 | Comments[5]
|
|
|
|
|
Friday August 07, 2009
TOTD #91: Retrieve JSON libraries using Maven dependency: json-lib
So you need to include JSON
libraries in your Maven project. The only option that seems to be
currently available is using json-lib
with the following dependencies:
|
<dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.3</version> <classifier>jdk15</classifier> </dependency> |

Posted by Arun Gupta in web2.0 | Comments[6]
|
|
|
|
|
Wednesday August 05, 2009
TOTD #89: How to add pagination to an Apache Wicket application
TOTD
#86 explained how to get started with deploying a Apache Wicket
application on GlassFish.
This Tip Of The Day (TOTD) will show
how to add pagination to your Wicket application.
The blog entry "JPA/Hibernate and Wicket Repeating Views with Netbeans"
Part
1 and 2
explain in detail how to create a CRUD application using NetBeans, JPA,
Hibernate and Wicket. This blog uses the data created in TOTD
#38 for the database table.

| <html> <head> <title>Wicket Quickstart Archetype Homepage</title> </head> <body> <strong>Wicket Quickstart Archetype Homepage</strong> <br/><br/> <span wicket:id="message">message will be here</span> <table> <tr> <th>ID</th> <th>Abbreviation</th> <th>Name</th> </tr> <tr wicket:id="rows"> <td><span wicket:id="id">ID</span></td> <td><span wicket:id="abbrev">Abbreviation</span></td> <td><span wicket:id="name">Name</span></td> </tr> </table> </body> </html> |
| package org.glassfish.samples; import java.util.Iterator; import org.apache.wicket.PageParameters; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.markup.repeater.data.IDataProvider; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; import org.glassfish.samples.controller.StatesJpaController; import org.glassfish.samples.model.States; /** * Homepage */ public class HomePage extends WebPage { private static final long serialVersionUID = 1L; // TODO Add any page properties or variables here /** * Constructor that is invoked when page is invoked without a session. * * @param parameters * Page parameters */ public HomePage(final PageParameters parameters) { // Add the simplest type of label add(new Label("message", "If you see this message wicket is properly configured and running")); // TODO Add your page's components here // create a Data Provider IDataProvider statesProvider = new IDataProvider() { public Iterator iterator(int first, int count) { StatesJpaController sc = new StatesJpaController(); return sc.findStatesEntities(count, first).iterator(); } public int size() { StatesJpaController sc = new StatesJpaController(); return sc.getStatesCount(); } public IModel model(final Object object) { return new LoadableDetachableModel() { @Override protected States load() { return (States)object; } }; } public void detach() { } }; // TODO Add your page's components here DataView dataView = new DataView("rows", statesProvider) { @Override protected void populateItem(Item item) { States state = (States)item.getModelObject(); item.setModel(new CompoundPropertyModel(state)); item.add(new Label("id")); item.add(new Label("abbrev")); item.add(new Label("name")); } }; add(dataView); } } |
| <?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="helloworld" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>org.glassfish.samples.model.States</class> <properties> <property name="hibernate.connection.username" value="app"/> <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.ClientDriver"/> <property name="hibernate.connection.password" value="app"/> <property name="hibernate.connection.url" value="jdbc:derby://localhost:1527/sample"/> </properties> </persistence-unit> </persistence> |
| DataView dataView = new DataView("rows", statesProvider, 5) |
| dataView.setItemsPerPage(5); |
| <span wicket:id="pager">message will be here</span><br> |
|
PagingNavigator pager = new PagingNavigator("pager", dataView); add(pager); |



Posted by Arun Gupta in web2.0 | Comments[3]
|
|
|
|
|
Monday August 03, 2009
TOTD #88: How add pagination to Rails - will_paginate
This Tip Of The Day (TOTD) explains
how to add pagination to your Rails application.
| ~/samples/jruby
>~/tools/jruby/bin/jruby
-S rails paginate ~/samples/jruby/paginate >~/tools/jruby/bin/jruby script/generate scaffold book title:string author:string ~/samples/jruby/paginate >sed s/'adapter: sqlite3'/'adapter: jdbcsqlite3'/ <config/database.yml >config/database.yml.new ~/samples/jruby/paginate >mv config/database.yml.new config/database.yml ~/samples/jruby/paginate >~/tools/jruby/bin/jruby -S rake db:migrate |
| #
Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html one: title: Ultramarathon Man Confessions of an All-Night Runner author: Dean Karnazes two: title: My Life on the Run author: Bart Yasso three: title: 50/50 Secrets I Learned Running 50 Marathons in 50 Days author: Dean Karnazes four: title: Born to Run author: Christopher Mcdougall five: title: Four Months to a Four-hour Marathon author: Dave Kuehls six: title: Galloway's Book on Running author: Jeff Galloway seven: title: Marathoning for Mortals author: John Bingham and Jenny Hadfield eight: title: Marathon You Can Do It! author: Jeff Galloway nine: title: Marathon The Ultimate Training Guide author: Hal Higdon ten: title: Running for Mortals author: John Bingham and Jenny Hadfield |
| ~/samples/jruby/paginate
>~/tools/jruby/bin/jruby
-S rake db:fixtures:load (in /Users/arungupta/samples/jruby/paginate) |
| ~/samples/jruby/paginate
>~/tools/jruby/bin/jruby
-S glassfish -l Starting GlassFish server at: 129.145.132.8:3000 in development environment... Writing log messages to: /Users/arungupta/samples/jruby/paginate/log/development.log. . . . Jul 29, 2009 2:06:44 PM com.sun.grizzly.scripting.pool.DynamicPool$1 run INFO: New instance created in 7,488 milliseconds |

| /tools/jruby
>./bin/jruby -S gem install will_paginate JRuby limited openssl loaded. gem install jruby-openssl for full support. http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL Successfully installed will_paginate-2.2.2 1 gem installed Installing ri documentation for will_paginate-2.2.2... Installing RDoc documentation for will_paginate-2.2.2... |
| require "will_paginate" |
| @books
= Book.paginate(:page => params[:page], :per_page => 5) #@books = Book.all |
| <%= will_paginate @books %> |


Posted by Arun Gupta in web2.0 | Comments[1]
|
|
|
|
|
Friday July 31, 2009
If you are using Warbler to create a WAR file of your application and
deploying on GlassFish
or any other Servlet container, then you are likely seeing the
following error during deployment:
| [#|2009-07-30T15:29:50.788-0700|SEVERE|sun-appserver2.1|javax.enterprise.system.container.web|_ThreadID=17; _ThreadName=httpWorkerThread-4848-0;_RequestID=1d7e8f18-1c9a-4924-bd0b-6a07eba425ba;|WebModule [/session]unable to create shared application instance org.jruby.rack.RackInitializationException: undefined method `new' for "Rack::Lock":String from /Users/arungupta/tools/glassfish/v2.1/glassfish/domains/domain1/applications/j2ee-modules/session/WEB-INF/gems/gems/actionpack-2.3.2/lib/ action_controller/middleware_stack.rb:116:in `inject' from /Users/arungupta/tools/glassfish/v2.1/glassfish/domains/domain1/applications/j2ee-modules/session/WEB-INF/gems/gems/actionpack-2.3.2/lib/ action_controller/middleware_stack.rb:116:in `build' from /Users/arungupta/tools/glassfish/v2.1/glassfish/domains/domain1/applications/j2ee-modules/session/WEB-INF/gems/gems/actionpack-2.3.2/lib/ action_controller/dispatcher.rb:82:in `initialize' . . . |
| # Additional Java .jar files to include.
Note that if .jar files are placed # in lib (and not otherwise excluded) then they need not be mentioned here. # JRuby and JRuby-Rack are pre-loaded in this list. Be sure to include your # own versions if you directly set the value # config.java_libs += FileList["lib/java/*.jar"] config.java_libs.delete_if {|f| f =~ /jruby-rack/ } config.java_libs += FileList["lib/jruby-rack*.jar"] |
| # Additional Java .jar files to include.
Note that if .jar files are placed # in lib (and not otherwise excluded) then they need not be mentioned here. # JRuby and JRuby-Rack are pre-loaded in this list. Be sure to include your # own versions if you directly set the value # config.java_libs += FileList["lib/java/*.jar"] config.java_libs.delete_if {|f| f =~ /jruby-rack/ || f =~ /jruby-complete/ } config.java_libs += FileList["lib/jruby-complete*.jar"] config.java_libs += FileList["lib/jruby-rack*.jar"] |
Posted by Arun Gupta in web2.0 | Comments[7]
|
|
|
|
|
Wednesday July 29, 2009
TOTD# 86: Getting Started with Apache Wicket on GlassFish
![]() |
Apache Wicket is an application framework to build web applications using HTML for markup and POJOs to capture the business logic and all other processing. Why Wicket digs more into the motivation behind this framework. |
| ~/samples/wicket
>mvn
archetype:create -DarchetypeGroupId=org.apache.wicket
-DarchetypeArtifactId=wicket-archetype-quickstart
-DarchetypeVersion=1.3.6 -DgroupId=org.glassfish.samples
-DartifactId=helloworld [INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'archetype'. [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Default Project [INFO] task-segment: [archetype:create] (aggregator-style) [INFO] ------------------------------------------------------------------------ [INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'. [INFO] Setting property: velocimacro.messages.on => 'false'. [INFO] Setting property: resource.loader => 'classpath'. [INFO] Setting property: resource.manager.logwhenfound => 'false'. [INFO] [archetype:create] [WARNING] This goal is deprecated. Please use mvn archetype:generate instead [INFO] Defaulting package to group ID: org.glassfish.samples [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating OldArchetype: wicket-archetype-quickstart:1.3.6 [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: groupId, Value: org.glassfish.samples [INFO] Parameter: packageName, Value: org.glassfish.samples [INFO] Parameter: package, Value: org.glassfish.samples [INFO] Parameter: artifactId, Value: helloworld [INFO] Parameter: basedir, Value: /Users/arungupta/samples/wicket [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] ********************* End of debug info from resources from generated POM *********************** [INFO] OldArchetype created in dir: /Users/arungupta/samples/wicket/helloworld [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3 seconds [INFO] Finished at: Tue Jul 28 15:30:21 PDT 2009 [INFO] Final Memory: 12M/80M [INFO] ------------------------------------------------------------------------ |
| ~/samples/wicket/helloworld
>mvn jetty:run [INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'jetty'. [INFO] ------------------------------------------------------------------------ [INFO] Building quickstart [INFO] task-segment: [jetty:run] [INFO] ------------------------------------------------------------------------ [INFO] Preparing jetty:run [INFO] [resources:resources] [INFO] Using default encoding to copy filtered resources. [INFO] [compiler:compile] [INFO] Compiling 2 source files to /Users/arungupta/samples/wicket/helloworld/target/classes [INFO] [resources:testResources] [INFO] Using default encoding to copy filtered resources. [INFO] [compiler:testCompile] [INFO] Compiling 2 source files to /Users/arungupta/samples/wicket/helloworld/target/test-classes [INFO] [jetty:run] [INFO] Configuring Jetty for project: quickstart [INFO] Webapp source directory = /Users/arungupta/samples/wicket/helloworld/src/main/webapp [INFO] Reload Mechanic: automatic [INFO] Classes = /Users/arungupta/samples/wicket/helloworld/target/classes 2009-07-28 15:31:35.820::INFO: Logging to STDERR via org.mortbay.log.StdErrLog [INFO] Context path = /helloworld [INFO] Tmp directory = determined at runtime [INFO] Web defaults = org/mortbay/jetty/webapp/webdefault.xml [INFO] Web overrides = none . . . INFO - WebApplication - [WicketApplication] Started Wicket version 1.3.6 in development mode ******************************************************************** *** WARNING: Wicket is running in DEVELOPMENT mode. *** *** ^^^^^^^^^^^ *** *** Do NOT deploy to your live server(s) without changing this. *** *** See Application#getConfigurationType() for more information. *** ******************************************************************** 2009-07-28 15:31:37.333::INFO: Started SelectChannelConnector@0.0.0.0:8080 [INFO] Started Jetty Server |

| ~/samples/wicket/helloworld
>mvn package [INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Building quickstart [INFO] task-segment: [package] . . . [INFO] Processing war project [INFO] Webapp assembled in[494 msecs] [INFO] Building war: /Users/arungupta/samples/wicket/helloworld/target/helloworld-1.0-SNAPSHOT.war [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 6 seconds [INFO] Finished at: Tue Jul 28 15:35:59 PDT 2009 [INFO] Final Memory: 14M/80M [INFO] ------------------------------------------------------------------------ |
| ~/samples/wicket/helloworld
>~/tools/glassfish/v3/preview/glassfishv3/bin/asadmin deploy
target/helloworld-1.0-SNAPSHOT.war Command deploy executed successfully. |

Posted by Arun Gupta in web2.0 | Comments[3]
|
|
|
|
|
Thursday July 02, 2009
Rails on GlassFish - "most performant of all", "simpler and just works", "blazing speed"
Here are some quotes about running Rails applications on GlassFish from user@jruby
mailing list:
I find the glassfish gem
to be the most performant of all -- and I don't need to war-up my app.
I also have some mongrel
cluster stuff, but glassfish is simpler and just works.
Voila...blazing speed,
can handle lots of traffic. Note that I am also cominging into apache
from a dyndns name. So, whatever IP I have, I can go straight to
execution on the glassfish gem and NO warring up! What could be easier
deployment, or a faster execution?
It's running fantasticly
and performing like nothing I've seen before :) Completely stable
memory, no wirings or anything bad for 5 days now.. (with several
ab/htperf stresstests).
It's always exciting to get good endorsements of our efforts in the
GlassFish team :)
Other similar stories for using Rails/GlassFish in production are
described at rubyonrails+stories.
Technorati: glassfish
v3 gem rubyonrails
stories
jruby
Posted by Arun Gupta in web2.0 | Comments[3]
|
|
|
|
|
Thursday June 18, 2009
TOTD #85: Getting Started with Django Applications on GlassFish v3
GlassFish v3 is an extensible App server. Basically the core App server
functionality can be easily extended using add-ons such as an OSGi
module. This allows to keep the core light-weight and install the
required features on demand. The add-ons can be easily installed using
the Update
Center. The what/why/how about extensibility is described in
the GlassFish
v3 Extensibility One-pager.
GlassFish v3 provides support for Dynamic Languages and Web Frameworks
such as Ruby-on-Rails, Groovy/Grails, and Python/Django using this
extensibility. This blog has published multiple tips on using
Ruby-on-Rails at rubyonrails+totd
and a few tips on Groovy/Grails at grails+totd.
This blog will explain how to get started with deploying Python/Django
applications on GlassFish
v3 Preview. The blog will use Jython interpreter
which is the Java implemention of Python.
Vivek already blogged about the detailed
instructions and this blog shows how to run the pre-bundled
samples.
| java -jar ~/Downloads/jython_installer-2.5.0.jar |

| alias
jython25=~/tools/jython2.5.0/bin/jython alias django-admin-jy="jython25 ~/tools/jython2.5.0/bin/django-admin.py" |
| ~/tools/jython/jython2.5rc4 >jython25 Jython 2.5rc4 (Release_2_5rc4:6470, Jun 8 2009, 13:23:16) [Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_13 Type "help", "copyright", "credits" or "license" for more information. >>> |
| ~/tools >tar xzvf
~/Downloads/Django-1.0.2-final.tar.gz Django-1.0.2-final/ Django-1.0.2-final/AUTHORS Django-1.0.2-final/django/ . . . Django-1.0.2-final/scripts/rpm-install.sh Django-1.0.2-final/setup.cfg Django-1.0.2-final/setup.py ~/tools/Django-1.0.2-final >jython25 setup.py install running install running build running build_py . . . running install_egg_info Writing /Users/arungupta/tools/jython/jython2.5.0/Lib/site-packages/Django-1.0.2_final-py2.5.egg-info |
| ~/tools/glassfish/v3/preview/glassfishv3/bin >./updatetool |

| ~/tools/glassfish/v3/preview/glassfishv3/glassfish >./bin/asadmin start-domain |
| ~/tools/glassfish/v3/preview/glassfishv3/glassfish
>./bin/asadmin
create-jvm-options -Djython.home=/Users/arungupta/tools/jython2.5.0
created 1 option(s) Command create-jvm-options executed successfully. |
| ~/tools/Django-1.0.2-final/examples >~/tools/glassfish/v3/preview/glassfishv3/glassfish/bin/asadmin
deploy . Command deploy executed successfully. |



| ~/tools/Django-1.0.2-final/examples >jython25 manage.py runserver Validating models... 0 errors found Django version 1.0.2 final, using settings 'examples.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C. |

Posted by Arun Gupta in web2.0 | Comments[3]
|
|
|
|
|
Tuesday June 16, 2009
TOTD #84: Using Apache + mod_proxy_balancer to load balance Ruby-on-Rails running on GlassFish
TOTD
#81 explained how to install/configure nginx for
load-balancing/front-ending a cluster of Rails application running on GlassFish
Gem. Another popular approach in the Rails community is to
use Apache HTTPD
+ mod_proxy_balancer.
A user asked the exact details of this
setup on the GlassFish
Gem Forum. This Tip
Of The Day (TOTD) will
clearly explain the steps.
| LoadModule proxy_balancer_module libexec/apache2/mod_proxy_balancer.so |
| <Proxy balancer://glassfishgem> BalancerMember http://localhost:3000 BalancerMember http://localhost:3001 BalancerMember http://localhost:3002 </Proxy> |
| ProxyPass / balancer://glassfishgem/ CustomLog /var/log/glassfishgem.log/apache_access_log combined |
| CustomLog /var/log/glassfishgem.log/apache_access_log combined |
| ~/tools/jruby/rails/runner >../../bin/jruby -S glassfish -e
production -c myapp Starting GlassFish server at: 10.0.177.178:3000 in production environment... Writing log messages to: /Users/arungupta/tools/jruby-1.3.0/rails/runner/log/production.log. Press Ctrl+C to stop. . . . ~/tools/jruby/rails/runner >../../bin/jruby -S glassfish -e production -c myapp -p 3001 Starting GlassFish server at: 10.0.177.178:3001 in production environment... Writing log messages to: /Users/arungupta/tools/jruby-1.3.0/rails/runner/log/production.log. Press Ctrl+C to stop. . . . ~/tools/jruby/rails/runner >../../bin/jruby -S glassfish -e production -c myapp -p 3002 Starting GlassFish server at: 10.0.177.178:3002 in production environment... Writing log messages to: /Users/arungupta/tools/jruby-1.3.0/rails/runner/log/production.log. Press Ctrl+C to stop. |
| ProxyPass /myapp/
balancer://glassfishgem/myapp/ |
| LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" \"%{BALANCER_WORKER_NAME}e\"" custom |
| CustomLog /var/log/glassfishgem.com/apache_access_log custom |
| ::1 - - [17/Jun/2009:10:53:53 -0700] "GET /runlogs
HTTP/1.1" 304 - "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5;
en-US; rv:1.9.0.11) Gecko/2009060214 Firefox/3.0.11"
"http://localhost:3002" ::1 - - [17/Jun/2009:10:54:04 -0700] "GET /runlogs HTTP/1.1" 200 621 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.11) Gecko/2009060214 Firefox/3.0.11" "http://localhost:3000" ::1 - - [17/Jun/2009:10:54:05 -0700] "GET /runlogs HTTP/1.1" 304 - "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.11) Gecko/2009060214 Firefox/3.0.11" "http://localhost:3001" |
Posted by Arun Gupta in web2.0 | Comments[4]
|
|
|
|
|
Tuesday May 05, 2009
Sea Change Affinity - Why JRuby/GlassFish ?
At Rails Conf
2009, Jay
McGaffigan from Sea
Change talked about why they choose JRuby/GlassFish for their
product Affinity.
Here are some of the reasons he quoted:
Posted by Arun Gupta in web2.0 | Comments[1]
|
|
|
|
|
Monday May 04, 2009
Rails Conf 2009 - Day 1 Trip Report
Rails Conf 2009 started this morning. The first day consists of morning
and afternoon tutorials.
I attended Nick Sieger's JRuby
on Rails tutorial, the slides are available.
A survey in the room showed:
| run
lambda { |env| [ 200, { 'Content-Length' => '2', 'Content-Type' => 'text/html', }, ["hi"] ] } |
| ~/samples/railsconf/sinatra/basic-rack
>~/tools/jruby/bin/jruby
-S rackup [2009-05-04 13:40:18] INFO WEBrick 1.3.1 [2009-05-04 13:40:18] INFO ruby 1.8.6 (2009-03-16) [java] [2009-05-04 13:40:18] INFO WEBrick::HTTPServer#start: pid=90964 port=9292 127.0.0.1 - - [04/May/2009 13:40:27] "GET / HTTP/1.1" 200 2 0.0160 127.0.0.1 - - [04/May/2009 13:40:27] "GET /favicon.ico HTTP/1.1" 200 2 0.0060 127.0.0.1 - - [04/May/2009 13:40:30] "GET /favicon.ico HTTP/1.1" 200 2 0.0100 |
| App
= lambda { |env| [ 200, { 'Content-Length' => '2', 'Content-Type' => 'text/html', }, ["hi"] ] } |
| ~/samples/railsconf/sinatra/basic-rack
>~/tools/jruby/bin/jruby
-S rackup app.rb [2009-05-04 13:43:57] INFO WEBrick 1.3.1 [2009-05-04 13:43:57] INFO ruby 1.8.6 (2009-03-16) [java] [2009-05-04 13:43:57] INFO WEBrick::HTTPServer#start: pid=90990 port=9292 127.0.0.1 - - [04/May/2009 13:44:09] "GET / HTTP/1.1" 200 2 0.0110 |
| class
BasicRack def call(env) body = "Hello from a class" [ 200, { 'Content-Length' => body.size.to_s, 'Content-Type' => 'text/html', }, [body] ] end end run BasicRack.new |

| ~/samples/railsconf/sinatra/basic-rack
>~/tools/jruby/bin/jruby -S gem install shotgun JRuby limited openssl loaded. gem install jruby-openssl for full support. http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL Successfully installed configuration-0.0.5 Successfully installed launchy-0.3.3 Successfully installed shotgun-0.2 3 gems installed Installing ri documentation for launchy-0.3.3... Installing RDoc documentation for launchy-0.3.3... |
| ~/samples/railsconf/sinatra/basic-rack
>~/tools/jruby/bin/jruby -J-Djruby.fork.enabled=true -S shotgun [2009-05-04 13:55:46] INFO WEBrick 1.3.1 [2009-05-04 13:55:46] INFO ruby 1.8.6 (2009-03-16) [java] == Shotgun starting Rack::Handler::WEBrick on localhost:9393 [2009-05-04 13:55:46] INFO WEBrick::HTTPServer#start: pid=91089 port=9393 |
| class
BasicRack def call(env) body = if env["PATH_INFO"] == "/foo" "in foo" else "in other" end [ 200, { 'Content-Length' => body.size.to_s, 'Content-Type' => 'text/html', }, [body] ] end end run BasicRack.new |
| class
BasicRackApp def call(env) body = "hello from app" [ 200, { 'Content-Length' => body.size.to_s, 'Content-Type' => 'text/html', }, [body] ] end end class MyMiddleware def initialize(app) @app = app end def call(env) @app.call(env) end end use MyMiddleware run BasicRackApp.new |
| use Rack::CommonLogger |
|
def call(env) status, headers, body = @app.call(env) body.map! { |part| part.upcase} [status, headers, body] end |
| require
'sinatra' |
| ~/samples/railsconf/sinatra/basic-sinatra
>~/tools/jruby/bin/jruby
-rubygems basic-sinatra.rb == Sinatra/0.9.1.1 has taken the stage on 4567 for development with backup from WEBrick [2009-05-04 14:40:14] INFO WEBrick 1.3.1 [2009-05-04 14:40:14] INFO ruby 1.8.6 (2009-03-16) [java] [2009-05-04 14:40:14] INFO WEBrick::HTTPServer#start: pid=91396 port=4567 |
| require
'rubygems' require 'sinatra' not_found do 'hi from other' end get '/foo' do 'hi from foo' end |
| require
'rubygems' require 'sinatra' get '/env' do env.inspect end |
| require
'rubygems' require 'sinatra' get '/' do end post '/' do end put '/' do end delete '/' do end |
| require
'rubygems' require 'sinatra' get '/' do content_type "application/json" { "foo" => "goo" }.to_json end |
| <html> <body> Hello form Sinatra + ERB </body> </html> |
| require
'rubygems' require 'sinatra' get '/' do erb :index end |
| require
'rubygems' require 'sinatra' require 'haml' get '/' do haml :index end |
| %html %body %h1 Hello from HAML |
| require
'rubygems' require 'sinatra' require 'haml' get '/' do erb :index end use_in_file_templates! __END__ @@ index <html> <body> Hello form Sinatra + ERB in file </body> </html> |
| require
'rubygems' require 'sinatra' require 'haml' get '/' do erb :index end get '/foo' do erb :foo end use_in_file_templates! __END__ @@ index <html> <body> Hello form Sinatra + ERB in file </body> </html> @@ foo <h1>FOO!</h1> |
| require
'rubygems' require 'sinatra' require 'haml' helpers do end |
| require
'rubygems' require 'sinatra' require 'haml' module helpers def self.dosomething(arg) end end get '/' do Helpers.dosomething end |
Friday May 01, 2009
JRuby, Rails, and GlassFish Bootcamp - San Francisco, May 19/20, 2009
![]() |
Would you like to power up your Rails
applications using JRuby
and GlassFish ?
And learn that from the engineers who develop the technology. If yes, then we have organized a bootcamp for you! |
Posted by Arun Gupta in web2.0 | Comments[0]
|
|
|
|
|
Thursday April 30, 2009
TOTD #81: How to use nginx to load balance a cluster of GlassFish Gem ?
![]() |
nginx (pronounced as "engine-ex") is an open-source and high-performance HTTP server. It provides the common features such as reverse proxying with caching, load balancing, modular architecture using filters (gzipping, chunked responses, etc), virtual servers, flexible configuration and much more. |
| ~/tools
> curl -L -O http://sysoev.ru/nginx/nginx-0.6.36.tar.gz ~/tools > tar -xzf nginx-0.6.36.tar.gz ~/tools > curl -L -O http://downloads.sourceforge.net/pcre/pcre-7.7.tar.gz ~/tools > tar -xzf pcre-7.7.tar.gz ~/tools/nginx-0.6.36 > ./configure --prefix=/usr/local/nginx --sbin-path=/usr/sbin --with-debug --with-http_ssl_module --with-pcre=../pcre-7.7 ~/tools/nginx-0.6.36 > make ~/tools/nginx-0.6.36 > sudo make install ~/tools/nginx-0.6.36 > which nginx /usr/sbin/nginx |

| ~/samples/jruby >~/tools/jruby/bin/jruby -S rails
runner ~/samples/jruby/runner >~/tools/jruby/bin/jruby script/generate scaffold runlog miles:float minutes:integer ~/samples/jruby/runner >sed s/'adapter: sqlite3'/'adapter: jdbcsqlite3'/ <config/database.yml >config/database.yml.new ~/samples/jruby/runner >mv config/database.yml.new config/database.yml ~/samples/jruby/runner >~/tools/jruby/bin/jruby -S rake db:migrate |
| ~/samples/jruby/runner >~/tools/jruby/bin/jruby -S
glassfish Starting GlassFish server at: 192.168.1.145:3000 in development environment... Writing log messages to: /Users/arungupta/samples/jruby/runner/log/development.log. Press Ctrl+C to stop. |
| ~/samples/jruby/runner >~/tools/jruby/bin/jruby -S
glassfish -p 3001 Starting GlassFish server at: 192.168.1.145:3001 in development environment... Writing log messages to: /Users/arungupta/samples/jruby/runner/log/development.log. Press Ctrl+C to stop. |
| ~/samples/jruby/runner >~/tools/jruby/bin/jruby -S
glassfish -p 3002 Starting GlassFish server at: 192.168.1.145:3002 in development environment... Writing log messages to: /Users/arungupta/samples/jruby/runner/log/development.log. Press Ctrl+C to stop. |
| upstream
glassfish { server 127.0.0.1:3000; server 127.0.0.1:3001; server 127.0.0.1:3002; } |

| proxy_pass http://glassfish; |

| sudo
kill -15 `cat /usr/local/nginx/logs/nginx.pid` sudo nginx |

| log_format
main '$remote_addr - [$upstream_addr]
$remote_user [$time_local] $request ' '"$status" $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; |
| 127.0.0.1 - [127.0.0.1:3000]
- [29/Apr/2009:15:27:57 -0700] GET
/runlogs/ HTTP/1.1 "200" 3689 "-" "Mozilla/5.0 (Macintosh;
U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/525.27.1 (KHTML, like
Gecko) Version/3.2.1 Safari/525.27.1" "-" 127.0.0.1 - [127.0.0.1:3001] - [29/Apr/2009:15:27:57 -0700] GET /favicon.ico HTTP/1.1 "200" 0 "http://localhost/runlogs/" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1" "-" 127.0.0.1 - [127.0.0.1:3002] - [29/Apr/2009:15:27:57 -0700] GET /stylesheets/scaffold.css?1240977992 HTTP/1.1 "200" 889 "http://localhost/runlogs/" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1" "-" |
| 127.0.0.1 - [127.0.0.1:3000]
- [29/Apr/2009:15:28:53 -0700] GET /runlogs/ HTTP/1.1 "200" 3689 "-"
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us)
AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1"
"-" 127.0.0.1 - [127.0.0.1:3002, 127.0.0.1:3000] - [29/Apr/2009:15:28:53 -0700] GET /favicon.ico HTTP/1.1 "200" 0 "http://localhost/runlogs/" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1" "-" 127.0.0.1 - [127.0.0.1:3001] - [29/Apr/2009:15:28:53 -0700] GET /stylesheets/scaffold.css?1240977992 HTTP/1.1 "200" 889 "http://localhost/runlogs/" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1" "-" |
Posted by Arun Gupta in web2.0 | Comments[8]
|
|
|
|
|
Wednesday April 29, 2009
TOTD #80: Sinatra CRUD application using Haml templates with JRuby and GlassFish Gem
TOTD
#79 showed how to run a trivial Sinatra
application using GlassFish
Gem. Sinatra
provides support for Haml,
Erb,
Builder,
Sass,
and Inline templates as described here.
This TOTD will show how to get started with creating a Sinatra CRUD
application using Haml templates.
![]() |
Haml is based on one primary principle - Markup should be beautiful
because beauty makes
you faster. Get started by installing the Haml gem as:
And follow the tutorial, documentation, and reference page for more details. |
| ~/tools/jruby/samples/sinatra-sample >mysql --user root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 664 Server version: 5.1.30 MySQL Community Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> create database hello_development; Query OK, 1 row affected (0.00 sec) mysql> use hello_development; Database changed mysql> CREATE TABLE `runners` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `distance` float, `minutes` int(11), `created_at` datetime, `updated_at` datetime); Query OK, 0 rows affected (0.06 sec) |
| require 'rubygems' require 'sinatra' require 'activerecord' ## Setup ActiveRecord::Base.establish_connection( :adapter => "jdbcmysql", :host => "localhost", :username => "root", :password => "", :database => "hello_development" ) ## Models class Runner < ActiveRecord::Base end ## Controller Actions get '/hi' do "Hello World!" end get '/' do @runner = Runner.find(:all) haml :index end get '/new' do haml :new end get '/:id' do @runner = Runner.find(params[:id]) if (@runner) haml :show else redirect '/' end end post '/' do @runner = Runner.new(:distance => params[:distance], :minutes => params[:minutes]) if @runner.save redirect "/#{@runner.id}" else redirect '/' end end |
| %h1 Listing all runners ... %table %tr %th Distance %th Minutes - @runner.each do |r| %tr %td= r.distance %td= r.minutes %br %a{:href=>"/new"} New Runner |
| %h1 Adding a new runner log ... %form{:method=>"post", :action=>"/"} Distance: %input{:type=>"text", :name=>"distance"} %br Minutes: %input{:type=>"text", :name=>"minutes"} %br %input{:type=>"submit", :value=>"Submit"} %br |
| %h1 Showing a runner log ... Distance: = @runner.distance %br Minutes: = @runner.minutes %br %br %a{:href=>"/"}= "Show All!" |
| . ./hello.rb ./views ./views/index.haml ./views/new.haml ./views/show.haml |
| ~/tools/jruby/samples/sinatra-sample >../../bin/jruby -S glassfish Starting GlassFish server at: 192.168.1.145:3000 in development environment... Writing log messages to: /Users/arungupta/tools/jruby-1.2.0/samples/sinatra-sample/log/development.log. Press Ctrl+C to stop. |





Posted by Arun Gupta in web2.0 | Comments[5]
|
|
|
|
|
Today's Page Hits: 3445
Total # blog entries: 994
| « November 2009 | ||||||
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
1 | 2 | 4 | 6 | 7 | ||
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | |||||
| Today | ||||||