JRuby, WAR, and Paperclip

If you deploy a jruby on rails application as a war file, the file structure is different from a normal rails application.

|-- 404.html
|-- 422.html
|-- 500.html
|   |-- app
|   |-- config
|   |-- gems
|   |-- lib
|   |-- log
|   |-- tmp
|   |-- vendor
|   `-- web.xml
|-- favicon.ico
|-- images
|   `-- rails.png
|-- index.html
|-- javascripts
|   `-- application.js
|-- robots.txt
|-- stylesheets
|-- system

The rails directories are under WEB-INF while the files and directories normally on public/ are on the root directory of the j2ee web app. In glassfish, the root of a rails app named ‘labs’ is $GLASSFISH_HOME/domains/domain1/applications/j2ee-modules/labs.

Since the ‘public’ directory is not under RAILS_ROOT, you shouldn’t be using RAILS_ROOT/public when saving files. Instead, use Rails.public_path. Paperclip saves files on “:rails_root/public/system/:attachment/:id/:style/:filename” by default. You can add the :path option to change this.

has_attached_file :image, :styles => { :square => "48x48#" }, :path => "#{Rails.public_path}/system/:attachment/:id/:style/:filename"

The uploaded files should now be saved on the correct directory.

While this works, it’s probably not a good idea to save uploaded files on the j2ee-modules/ directory. When you undeploy the ‘labs’ app on glassfish, it will remove the ‘labs’ directory on j2ee-modules which includes all the uploaded files.

We can symlink labs/system to a directory outside of the glassfish directory. We can also use a different directory for paperclip which doesn’t use Rails.public_path or Rails.root. (I haven’t tested both.)

This is only an issue when deploying your jruby apps as a war file. If you’re using the glassfish gem, you don’t change the file structure at all. You just run jruby -S glassfish. If you’re using directory-based deployment on glassfish, undeploying the app doesn’t remove the directory.

Where are you saving the uploaded files? Let me know in the comments if you have other suggestions.