2011-04-01 30 views
55

NotaCómo integrar aplicaciones web Clojure en Apache

Dada esta OP fue escrito hace unos dos años, en lugar de hacer la misma pregunta de nuevo, me pregunto si existen instrucciones paso a paso así, que puedo integrar una aplicación web Noir u otra aplicación web Clojure en Apache, ya sea Jetty, Tomcat u otra cosa. Existen instrucciones similares para Django, y creo que entiendo que Python se está ejecutando en el caso de Django como un motor en lugar de un anillo de marco, por lo que las cosas son más complicadas con las aplicaciones web de Clojure.

Nota final

estoy profundamente enamorado de Clojure y Compojure parece un framework web ordenada.

Pero todo se vino abajo cuando quise implementar mi aplicación en un servidor de aplicaciones normal como Tomcat como GUERRA. De hecho, tuve que escribir controladores de timbre personalizados para los archivos estáticos y los recursos que funcionarían tanto en Jetty local y Tomcat porque los controladores de stock no, y tuve que anteponer la raíz de contexto en todas partes de forma manual.

Estoy sorprendido negativamente de tener que escribir todo este código para crear la aplicación web más simple que se pueda ejecutar en Jetty y Tomcat. Tengo sólo tres posibles explicaciones para esto:

  1. Nadie utiliza Clojure/Compojure para otra cosa que el desarrollo local con embarcadero, es decir, en la producción de cualquier cosa
  2. Todo el mundo despliega aplicaciones Clojure/Compojure en un embarcadero dedicado sin raíz de contexto (como la gente lo hace con aplicaciones Node.js)
  3. Hay una manera muy sencilla de evitar los problemas me encontré con que no estaba al tanto de

Cuál de estos es en su opinión el caso? ¿O es otra cosa?

Editar:

Tenga en cuenta que la creación de un archivo de la guerra es una obviedad con Maven/Leiningen y no lo que quiere decir. Me pregunto si tengo que escribir tanto código para hacer que Compojure funcione con Tomcat, cosas básicas como el servicio de archivos estáticos y el conocimiento de raíz de contexto que debería funcionar de de fábrica.

+4

+1 Me interesaría mucho el resultado de esta pregunta. –

+0

La plantilla de proyecto de pastel adjunta a mi respuesta se ocupa de los problemas que surgen al servir la aplicación tanto de Jetty para desarrollo * como de * Tomcat. – mac

Respuesta

9

Las personas están implementando aplicaciones de Compojure en contenedores de servlets que no son de Jetty.

Salida:

También puedes ver Lein-guerra

+0

Ver mi comentario a la respuesta del stand. – futlib

+0

Perdón por ser tan ignorante antes, mezclando lein-ring con leiningen-war. Lein-ring es de hecho impresionante y hace todo lo que quiero: lein ring server para iniciar un Jetty, lein ring uberwar para construir una guerra que funcione en Tomcat sin ninguna modificación de ruta. Ojalá Maven tuviera algo así, me mudé a Leiningen por el momento. – futlib

2

Si va a implementar en Google App Engine, aquí hay un gran blog http://compojureongae.posterous.com/

Usted todavía puede obtener algunos consejos útiles incluso si no se están implementando a GAE.

+0

Este ejemplo parece lanzar su propio Jetty. Entonces, ¿ese es el caso común? – futlib

6

que he tenido cierto éxito utilizando leiningen-war para generar un archivo de la guerra genérica (suponiendo estás usando leiningen, por supuesto). Le permite especificar ubicaciones para html estático, la ubicación de un web.xml y otros recursos en su archivo project.clj.

No fue demasiado difícil para mí producir un archivo de guerra genérico que pude implementar en JBoss (ejecutando Tomcat como un contenedor de servlets) pero creo que tiene que estar bastante familiarizado con el formato web.xml. Me siento más cómodo con la creación de mi propio web.xml, por lo que puede ser más útil para mi gusto.

Parece que la persona detrás de leiningen-war está recomendando lein-ring ahora. Empecé a ver eso, pero hasta ahora no he podido obtener un archivo de guerra genérico fácilmente.

Estoy de acuerdo, sin embargo, que la contabilidad para la implementación de producción es una debilidad aquí.

+0

Crear un archivo war no es un problema para mí, estoy usando Maven y es obvio. Pero ajustar mi aplicación para que funcione con problemas del servidor de aplicaciones, como la entrega de archivos estáticos y la raíz de contexto, requiere demasiado trabajo. – futlib

11

que utilizan una combinación de lo siguiente para que esta bastante indoloro:

Cake (Incl. El mandato de despliegue)

Una plantilla de la torta por webprojects desarrollados por Lau Jensen.

Vagrant (rubí VM (Virtualbox) herramienta de gestión, que se basa en Chef o de marionetas)

VPS (de Slicehost)

La parte clave es la plantilla webdev que Lau hizo. La carpeta webdev debe colocarse en el ~/.cake/templates. Para crear un nuevo proyecto basado en el uso de TI:

cake new webdev *projectname* 

nota de Pls que la plantilla incluye correo log4j y Java que puede/debe ser excluida si no es necesario. Supone además que estás usando Enlive y Moustache, pero cambiar eso a Compojure/Hiccup es trivial si ese es tu veneno.

La plantilla se encarga de servir la aplicación desde embarcadero en desarrollo (simplemente evalúa server.clj) y funciona como una guerra cuando se ejecuta bajo Tomcat. Las rutas permanecen idénticas si se implementan en el servidor como ROOT.war bajo Tomcat. Todos los archivos estáticos deben estar ubicados en el directorio de recursos. Jetty les servirá desde allí (gracias al middleware de archivos Ring). En producción, estos se mueven a la raíz de la aplicación web y son servidos desde allí por Tomcat (el web.xml se encarga de eso).

La carpeta devbox contiene un Vagrantfile y libros de cocina necesarios para crear una VM virtualbox con Tomcat instalado. Uso Cake para implementar el archivo .war en el directorio /home/vagrant (esto se controla desde la definición del contexto dev en project.clj). El archivo .war se enlaza en el directorio webapps de Tomcat (/var/lib/tomcat6/webapps) como ROOT.war. Para obtener más información sobre cómo usar Vagrant, consulte Vagrant site.

Este gist muestra un ejemplo de cómo adaptar el proyecto.clj para usar el comando cake deploy. El ejemplo crea dos contextos @dev y @prod cuales se pueden distribuir a utilizar:

cake deploy @dev/cake delpoy @prod 

he recogido la plantilla WebDev la torta y los archivos de Vagrant en este zip.

+1

'webdev' debería ser el primero de una serie de recetas en la melodía de algo como esto: https://github.com/klang/cake-recipes – klang

+2

Esta es una respuesta fantástica. – mtnygard

+0

Gracias, por alguna razón el asker parece estar en desacuerdo :-) – mac

2

He lanzado en producción (durante más de 6 meses) una aplicación Compojure + Vaadin. El empaquetado se hizo usando el plugin lein-war y no encontré ningún problema importante.

La aplicación se llama halo, contenida en un archivo halo.war, el contexto es/halo y el servidor tomcat también está ejecutando Hudson, y otra aplicación personalizada. Vaadin está resolviendo correctamente todos mis archivos estáticos, CSS, imágenes ... Utilicé principalmente ese blog post para escribir el pequeño pegamento necesario para él.

En otra nota, también estoy ejecutando Noir en Heroku y no he tenido ningún problema con el embalaje y la implementación, y esto también está en producción.

Esto no está directamente relacionado con su pregunta Compojure, pero Clojure en producción en aplicaciones web, sí, definitivamente.

3

Estoy usando Noir, un marco web construido sobre Ring y Compojure.

He creado un proyecto usando lein noir new my-proj. Entonces creé my-proj/web directorio y añadí siguientes líneas a

project.clj:  
    :compile-path "web/WEB-INF/classes" 
    :library-path "web/WEB-INF/lib" 
    :ring {:handler project.server/handler} 

he puesto my-proj/web directorio raíz de contexto como durante el desarrollo de Tomcat.

Para la entrega de archivos estáticos, puse cosas en el directorio my-proj/resources/public. Para acceder (leer/escribir) archivos a través del código, se puede usar :servlet-context del encabezado de solicitud de llamada. Con la configuración anterior, la ruta contextual sería: (.getRealPath (ring-request-header :servlet-context) "/WEB-INF/classes/myfile.txt"). Myfile.txt está bajo my-proj/resources.

1

Si está utilizando un servidor basado en anillo (compojure, noir/lib-noir, luminus, etc.), y desea implementar como un uberjar, para evitar

"Failed to load Main-Class manifest attribute from your-uberjar.jar" 

simplemente crear el uberjar con lein ring uberjar. Tenga en cuenta la adición de 'anillo' a lein uberjar. Esto supone que estás usando el complemento lein-ring.

Cuestiones relacionadas