For JRuby on Rails project I use warbler to create the war file. To know the details see my previous blog JRuby on Rails building with warbler. Warbler doesn't have support to create ear file but it does a lot to create the war file. Now I will show you how can you create a ear file when you have the war file. I am assuming that you have warbler properly configured so that it can create the war file for you.
Create a new rake file (ear.rake) in RAILS_APP/lib/tasks folder. In this rake file we will define rake tasks to create the ear from the war file. Note that if you define a task in this file you will be able to execute that task from your capistrano capfile. To create the ear we need an application.xml file. We can create the application.xml file externally or we can create the file of our own. I am creating the content of this file using a method create_application_xml. Now in this rake file add the following task that will create the ear file for us:
task 'ear:create' => 'war' do
name = "myapp"
ear_file = "#{name}.ear"
staging = File.join(RAILS_ROOT,'tmp','ear')
File.makedirs(staging) if !File.exists?(staging)
puts "Copying war to #{staging}"
#add the war file to the tmp directory
File.copy("#{name}.war", staging)
puts "Making application.xml"
#create and add application.xml
File.makedirs(File.join(staging, 'META-INF'))
ear_file_dir = File.join(staging, 'META-INF')
application_xml = File.join(staging, 'META-INF', 'application.xml')
# always create a new override file, regardless of whether one exists
File.open(application_xml, 'w') { |out| out << create_application_xml(name) }
puts "Creating the ear ...."
sh "jar cf #{ear_file} -C #{staging} ."
end
The method that is called by the above task to create the ear file content:
def create_application_xml(name)
require 'erb'
template=<<EOFAPPXML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN" "http://java.sun.com/j2ee/dtds/application_1_2.dtd">
<application id="application_myap">
<display-name>myapp</display-name>
<module id="webmodule_myapp">
<web>
<web-uri>#{name}.war</web-uri>
<context-root>/#{name}</context-root>
</web>
</module>
</application>
EOFAPPXML
erb = ERB.new(template)
erb.result(binding)
end
To execute the jar command to create the ear file you need to make sure that JAVA_HOME property is properly set.
Monday, October 19, 2009
Thursday, October 15, 2009
Some good links to learn more about Webservice (SOAP & REST)
This is a little effort for those who wants to know about Webservice, WS-*, SOAP, REST. Here I am mentioning some link from where you will be able to know about all these keywords:
- http://oracled.wordpress.com/2009/03/11/when-to-use-rest-based-web-services/
- http://oracled.wordpress.com/2008/09/12/rpc-style-vs-document-style-web-service/
- http://oracled.wordpress.com/2009/03/07/some-web-services-best-practices/
- http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/
- http://www.ajaxonomy.com/2008/xml/web-services-part-1-soap-vs-rest
- http://www.infoq.com/articles/sanjiva-rest-myths
- http://en.wikipedia.org/wiki/Representational_State_Transfer
- http://java.sun.com/developer/technicalArticles/WebServices/restful/
- http://www.informit.com/guides/content.aspx?g=xml&seqNum=160
- http://www.ibm.com/developerworks/webservices/library/ws-policy.html
- http://www.ibm.com/developerworks/webservices/library/ws-security.html
- http://www.ibm.com/developerworks/library/specification/ws-tx/
- http://www.ibm.com/developerworks/library/specification/ws-fed/
- http://www.ibm.com/developerworks/library/specification/ws-rm/
- http://oracled.wordpress.com/2009/03/11/when-to-use-rest-based-web-services/
- http://oracled.wordpress.com/2008/09/12/rpc-style-vs-document-style-web-service/
- http://oracled.wordpress.com/2009/03/07/some-web-services-best-practices/
- http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/
- http://www.ajaxonomy.com/2008/xml/web-services-part-1-soap-vs-rest
- http://www.infoq.com/articles/sanjiva-rest-myths
- http://en.wikipedia.org/wiki/Representational_State_Transfer
- http://java.sun.com/developer/technicalArticles/WebServices/restful/
- http://www.informit.com/guides/content.aspx?g=xml&seqNum=160
- http://www.ibm.com/developerworks/webservices/library/ws-policy.html
- http://www.ibm.com/developerworks/webservices/library/ws-security.html
- http://www.ibm.com/developerworks/library/specification/ws-tx/
- http://www.ibm.com/developerworks/library/specification/ws-fed/
- http://www.ibm.com/developerworks/library/specification/ws-rm/
Friday, October 9, 2009
Capistrano task to confirm stop of JBoss
This is very common in the domain of automatic deployment to restart the application server and obviously the application server takes sometimes to stop. If we need to make sure the application server is completely stopped before starting it again we need to write some shell script to check that. Capistrano users can use following script to ensure that the application server (in this case JBoss) is completely stopped. The following script will execute the stop script and then check if the server is still running. If it is running then it will sleep for 6 seconds and then check it again. It will do it for 15 times and even then if it is running it will issue kill -9 to kill the process. You can change any of these values. Note that I have assumed the server is running at port 8080.
task :ensure_jboss_stopped do
set :use_sudo, true
set :user, prompt("User to run stop.sh ")
set :is_jboss_running, true
counter = 0
run "/opt/jboss-4.2.3.GA/bin/stop.sh"
while is_jboss_running
counter = counter + 1
run "netstat -an | grep -i listen | grep 8080|wc -l" do |ch, stream, data|
if data.to_i > 0
set :is_jboss_running, true
else
set :is_jboss_running, false
end
end
if is_jboss_running and counter > 15
system "echo JBoss is still running, finding the process id"
run "ps -eaf |grep frengine |grep -v grep |awk '{print $2}'|xargs -I{} echo kill -9 {};"
system "echo Now KILLING JBOSS"
run "ps -eaf |grep frengine |grep -v grep |awk '{print $2}'|xargs -I{} kill -9 {} ;"
sleep 6
elsif is_jboss_running
system "echo JBoss is still running, waiting for 6 seconds"
sleep 6
end
end
system "echo JBoss stopped successfully"
end
How to get the output of Capistrano executed command
Sometimes it is required to get the the output of some executed command in external/deployment server and based on that output you may need to take some decision. Lets say for some reason you are planning for hot deployment to a JBoss application server. So before deployment you want to make sure if the JBoss is running or not. You can do that by following script. Here I am assuming that the JBoss is running at 8080
task :do_something_if_jboss_is_running do
set :use_sudo, true
set :user, prompt("User to check jboss running status: ")
set :is_jboss_running, true
run "netstat -an | grep -i listen | grep 8080|wc -l" do |ch, stream, data|
if data.to_i > 0
set :is_jboss_running, true
else
set :is_jboss_running, false
end
end
if is_jboss_running
#do something
else
#do some other thing
end
end
Run JBoss in background using Capistrano
I had a very hard time to start JBoss as background process using Capistrano. At the I end I found the solution which is so simple. The important point is in you capfile don't execute the commmad with both nohup and ampersand (&). At first create start.sh file that will call run.sh to start the jboss.
The content of start.sh:
/opt/jboss-4.2.3.GA/bin/run.sh &
And in your capfile:
desc "start jboss server"
task :start_jboss do
set :use_sudo, true
set :user, prompt("User to run 'service jboss-frengine start' command: ")
run "nohup /opt/jboss-4.2.3.GA/bin/start.sh" # ONLY NOHUP IS USED, DON'T USE AMPERSAND HERE
end
Make sure the user has permission to write into nohup.out
Tuesday, October 6, 2009
Using JNDI in JRuby on Rails for JBoss
Its very easy to user JNDI with JBoss in your JRuby on Rails application. At first you will need to install all the required gems/plugins and for that please see my previous blog JRuby on Rails: using JDBC driver. Now if you have everything okay that is specified in that post you will have to configure followings.
I am assuming you don't have any JNDI datasource created in your JBoss.
To create a JNDI datasource in your JBoss create a file my-oracle-ds.xml with following content and save it in JBOSS_HOME/server/default/deploy folder:
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>MyDS</jndi-name>
<connection-url>jdbc:oracle:thin:@172.189.171.149:1521:MYDB</connection-url>
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<user-name>dbuser</user-name>
<password>dbpassword</password>
<use-java-context>false</use-java-context>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<metadata>
<type-mapping>Oracle10g</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
In your jboss-web.xml file:
<jboss-web>
.......
<resource-ref>
<res-ref-name>jdbc/MyDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<jndi-name>MyDS</jndi-name>
</resource-ref>
</jboss-web>
In your web.xml file:
<resource-ref>
<res-ref-name>jdbc/MyDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
Now to access the database in your database.yml use following configuration:
development:
adapter: jdbc
jndi: java:comp/env/jdbc/MyDS
driver: oracle.jdbc.driver.OracleDriver
Monday, September 28, 2009
Problem with Warbler
While I was building the war/ear file I was facing problem at the building time as well as after deployment. Here I tried to mention all those problems:
1) Warbler doesn't copy .specifications file: When we execute gems:unpack:dependencies it creates .specifications file for each gem in your vendor/gems folder. Then when we execute 'war' task it doesn't copy this file into the war file. I solved this problem by adding following line in the config/warble.rb file
config.includes = FileList["vendor/gems/*/.specification"]
2) I was getting Don't know how to build task '' when log folder was there: This is something wired I got when I added the gem 'composite_primary_keys'. There are two solutions for this
- rename the log folder to some other name and then execute the war task
- in your warble.rb file use config.gems = []
3) After deployment I was getting undefined method `new' for "Rack::Lock":String: After googling I came to following solution
4) Cannot load gem at [SYSTEM_JRUBY_CACHE_PATH] in MY_APP_FOLDER: I was getting this error when I started using 'composite_primary_keys' gem and trying to execute the war task by jruby rake. The version of this jruby rake is 0.8.7. After some analysis and testing with different version of rake I have identified that if I use older rake (version less then 0.8.4) then the problem is gone. Other thing that you can do is in your warble.rb file use config.gems = []
Some helpful links:
http://kenai.com/jira/browse/JRUBY_RACK-18
http://stufftohelpyouout.blogspot.com/2009/06/how-to-get-warbler-to-include-custom.html
http://stufftohelpyouout.blogspot.com/2009/07/fix-ioerrorio-errorbroken-pipestrange.html
http://wiki.oracle.com/thread/3104945/Error+during+jruby-rack+initialization
Subscribe to:
Posts (Atom)