My favorites | Sign in
Project Logo
                
Search
for
Updated Feb 03, 2009 by leo.soto
Labels: Featured
WarDeployment  
Documentation about the "war" management command

The "war" Command

django-jython includes a "war" management command so you can go to your project directory and type something like this:

lsoto@spirit:~/src/mysite$ jython25 manage.py war --include-java-libs=$HOME/jdbcdrivers/postgresql-8.3-603.jdbc4.jar

And get a single "mysite.war" file which you can deploy in your preferred application server. This file doesn't require anything special installed on the target server. No Django, no Jython, no nothing.

Usage

The first step is to add 'doj' to your list of INSTALLED_APPS on your settings.py file. So this section should look like:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'mysite.polls',
    'mysite.another_app',
    # More apps...
    'doj',
)

Then, the most typical usage is the one exemplified before:

$ jython25 manage.py war --include-java-libs=$HOME/jdbcdrivers/postgresql-8.3-603.jdbc4.jar

Here, you tell the war command that it should include an extra java library to the generated WAR file, because it can't know which java libraries are you using inside your project. In the typical cases, you must at least specify the JDBC driver you are using to connect to the database, which will depend on the configured database backend.

You may also specify more files to include, separating the paths by the special path separator character, which is ":" in Unix based platforms and ";" on Windows platforms.

Thus if you are using, for examlple, the iText library inside your Django project you should specify something like the following when constructing the war file:

$ jython25 manage.py war --include-java-libs=$HOME/jdbcdrivers/postgresql-8.3-603.jdbc4.jar:/usr/share/java/iText-2.1.3.jar 

By the way, the generated WAR file is created on the parent directory of your project directory, in order to avoid cluttering your project space.

Including Extra Python libraries

By default, the war command copies your project directory and the root directory of every django application declared on the INSTALLED_APPS settings inside the generated file (in addition to django itself, of course). It won't detect any other python dependency of your project, like for example PyAMF.

So, in case you have a dependency on a Python library (not included on the standard library of course), you have to specify it with the --include-py-packages option, as the following example:

$ jython25 manage.py war --include-java-libs=$HOME/jdbcdrivers/postgresql-8.3-603.jdbc4.jar --include-py-packages=$HOME/jython25/Lib/site-packages/pyamf

Egg or zip files are also supported, as well as directories meant to be "path entries" (i.e, a directory containing packages). For these cases, use the --include-py-path-entries.

$ jython25 manage.py war --include-java-libs=$HOME/jdbcdrivers/postgresql-8.3-603.jdbc4.jar --include-py-path-entries=$HOME/eggs/PyAMF-0.3.1-py2.5.egg

As with --include-java-libs, multiple entries and/or packages can be specified, by separating them with the path separator character of your platform (":" in Unices and ";" in Windows).

All --include-* flags can be mixed freely.

Media Files and the Context Root Name

In principle, your application could live "inside" any URL, as long as you use the `{% url %}` tag and the `reverse()` to generate links inside your applications. This should decouple your views from the actual url they get "attached" to, and indeed that's true.

But, this isn't true for media files when the prefix is configured on settings.py, such as MEDIA_URL and ADMIN_MEDIA_PREFIX. (Now, if you never planned to serve media on the same server where your django applications live, skip this section. This is all about making easy to serve static files inside the same servlet context as your Django project will live)

So, the war command patches your settings.py files copied on the generated WAR, by appending something like the following, at the end of the file

# Added by django-jython. Fixes URL prefixes to include the context root:
MEDIA_URL='/mysite/site_media/'
ADMIN_MEDIA_PREFIX='/mysite/media/'

(You can check this by yourself, looking at the file /WEB-INF/lib-python/<project_name>/<project_name>/settings.py inside the generated WAR file)

This is done only if these variables are not blank (also, a WARNING is outputted when you build the WAR if any of them is blank) doesn't seem to be a really absolute URL (starting by 'http'), which should mean that media files are not going to live in the same server.

By default, the war command assumes that you will use the name of the project as the name of the context root in the deployed application. You can change this using the --context-root=my_customized_context_root flag of the command.

Please note that this small hack means that you can't simply rename your war file to deploy it on another context name. You must regenerate it specifying the other context name. Or just manually editing the settings.py file inside the WAR, whatever fits you better.

Sample Output

Currently the command is a bit verbose. As a reference, here is what I get when running the command on the project you get after following the official Django tutorial (up to part three):

lsoto@spirit:~/src/mysite$ jython manage.py war

Assembling WAR on /tmp/tmpHLvVxy/mysite

Copying WAR skeleton...
Copying jython-dev.jar...
Copying jna.jar...
Copying asm-3.1.jar...
Copying asm-commons-3.1.jar...
Copying postgresql-8.3-603.jdbc4.jar...
Copying asm-util-3.1.jar...
Copying servlet-api-2.5.jar...
Copying antlr-3.1.1.jar...
Copying constantine-0.4.jar...
Copying profile.jar...
Copying junit-3.8.2.jar...
Copying jarjar-0.7.jar...
Copying jline-0.9.94.jar...
Copying antlr-2.7.7.jar...
Copying mysql-connector-java-5.1.6.jar...
Copying stringtemplate-3.2.jar...
Copying libreadline-java-0.8.jar...
Copying jna-posix.jar...
Copying xercesImpl-2.9.1.jar...
Copying antlr-3.1.1-runtime.jar...
Extracting modjy JAR from modjy_0_25_2.zip...
Copying Lib...
Copying django...
Copying media...
Copying mysite...
WARNING: Not copying project media, since MEDIA_ROOT is not defined
Copying doj...
Building WAR on /home/lsoto/src/mysite.war...
Cleaning /tmp/tmpHLvVxy...

Finished.

Now you can copy /home/lsoto/src/mysite.war to whatever location your application server wants it.

Note that I'm using an svn checkout of Jython. Currently (2009-02-03), the war command doesn't work with Jython2.5b1, but should work on the next release. Thus, this documentation will be updated when the next Jython beta is released.


Comment by raptopassion, Sep 22, 2008

The most common use of war files is using jndi data sources. Is that possible?

Comment by leo.soto, Feb 03, 2009

Out of the box it is not possible yet, but should be easy to implement, assuming that it only implies a change on the JDBC connection string. See the cursor() function on <http://code.google.com/p/django-jython/source/browse/trunk/doj/backends/zxjdbc/postgresql/base.py>.

Maybe just a setting (JDBC_CONNECTION_STRING) provided by the user overriding the connection string computed by each backend would be good enough.

Comment by WorldDominationkites, Feb 04, 2009

Can you please post a combination of versions that are known to work:

  • django
  • jython
  • django-jython

I'm struggling to get a working rig by trial-and-error.

Comment by leo.soto, Feb 05, 2009

Use both django-jython and jython from svn. And the latest 1.0.X Django release.

When the next beta release (2.5b2) of Jython is out, I'll make a release of django-jython, for everyone out there which doesn't like to work with svn snapshots.

Comment by WorldDominationkites, Mar 22, 2009

OK, these versions worked for me:

  • django1.0.2
  • jython2.5b3 (downloaded .jar, didn't build it)
  • django-jython (trunk today, r61)
  • JDK 1.6.0_06
  • downloaded postgresql-8.3-604.jdbc4.jar, dropped it into my JDK lib/ext directory
  • because I'm on windows, as per this issue, this patch

followed the instructions and it all just worked... when I started using full path to my jdbc driver like this:

jython manage.py war --include-java-libs="C:\Program Files\Java\jdk1.6.0_06\jre\lib\ext\postgresql-8.3-604.jdbc4.jar"

Deployed to JBoss.

Comment by jonathan.buchanan, Jun 15, 2009

The bundled version of jruby-extras-fileservlet.jar appears to have a dependency on having a Java version greater than 1.5 - is this unexpected, or does it need to be documented as such?

I got the following on two different Windows machine while trying to deploy to Tomcat 6, both of which had jdk1.5.0_18 installed:

java.lang.UnsupportedClassVersionError: Bad version number in .class file (unable to load class org.jruby.webapp.FileServlet)

When I upgraded to jdk-6u14 on one of these machines, it worked fine. Alas, I'm not able to upgrade the other.

Also, on both machines (one running XP, one running Vista) I've had to manually zip up the temp directory contents into a .war file. Both fail with the following error when I try to use the war command on my ta project (temp dir path replaced by me as it differs on both systems):

Copying WAR skeleton...
Copying jython.jar...
Copying Lib...
Copying django...
Copying admin_media...
Copying ta...
Copying media...
Copying doj...
Copying ta...
Traceback (most recent call last):
    ...
OSError: [Errno 0] couldn't make directories: 'c:\\(path to temp dir)\\ta\\WEB-INF\\lib-python\\ta'

If I look at the above directory, its contents have been copied successfully.


Sign in to add a comment
Hosted by Google Code