resources: class loaders, environment and ioc
Environment tags configure class-loaders, logging, authentication and resources like databases, JMS queues, EJB servers, and web service clients. Many of the resources are stored in JNDI or in EL variables for later assembly. Any environment resource can appear in any of Resin environments: <resin>, <cluster>, <host> and <web-app>. Resources configured at parent levels are shared among all children, so a database can share connection pools for all web-apps or an authenticator can provide single-signon.
The <authenticator> tag as been replaced by CDI-style authenticator configuration. It exists only for backward compatibility. To upgrade, see the authenticator-specific tags like resin:XmlAuthenticator. The new name will be the old class="..." name. So class="com.caucho.security.XmlAuthenticator" becomes <resin:XmlAuthenticator>. <web-app xmlns="http://caucho.com/ns/resin" xmlns:resin="urn:java:com.caucho.resin"> ... <resin:XmlAuthenticator password-digest="none"> <resin:user name="Harry Potter" password="quidditch" group="user,gryffindor"/> <resin:user name="Draco Malfoy" password="pureblood" group="user,slytherin"/> </resin:XmlAuthenticator> ... </web-app> The <bean> tag as been replaced by CDI-style configuration. It exists only for backward compatibility. The new tag name will be the old class="..." name and the XML prefix will be the package. So class="com.mycom.FooBean" becomes <mycom:FooBean xmlns:mycom="urn:com.mycom">. <web-app xmlns="http://caucho.com/ns/resin" xmlns:resin="urn:java:com.caucho.resin" xmlns:mypkg="urn:java:com.mycom.mypkg"> ... <mypkg:MyBean resin:JndiName="java:comp/env/my-name"> <my-attribute>my-value</my-attribute> </mypkg:MyBean> ... </web-app> <case-insensitive> specifies whether the environment context is case sensitive or insensitive. Because some operating systems are case-insensitive, it is important for security reasons for Resin to behave differently for case-sensitive and case-insensitive directories. For example, when case-insensitive is true, url-patterns will match in a case-insensitive manner, so TEST.JSP will work like test.jsp. r_case-insensitive = element case-insensitive { r_boolean-Type } <character-encoding> specifies the default character encoding for the environment. r_character-encoding = element character-encoding { string } <resin xmlns="http://caucho.com/ns/resin"> <character-encoding>utf-8</character-encoding> ... </resin> <class-loader> configures a dynamic classloader for the current environment. Each environment (<cluster>, <host>, <web-app>) etc, can add dynamic classloaders. The environment will inherit the parent classloaders. Each <class-loader> is comprised of several implementing loader items: library-loader for WEB-INF/lib, compiling-loader for WEB-INF/classes. For web-apps, the classloaders generally belong in a <prologue> section, which ensures that Resin evaluates them first. The evaluation order is particularly important in cases like resin-web.xml vs web.xml, because the resin-web.xml is evaluated after the web.xml.
r_class-loader = element class-loader { r_compiling-loader* & r_library-loader* & r_simple-loader* & r_tree-loader* } <web-app xmlns="http://caucho.com/ns/resin"> <prologue> <class-loader> <compiling-loader path="WEB-INF/classes"/> <library-loader path="WEB-INF/lib"/> </class-loader> </prologue> </web-app> child of class-loader
<compiling-loader> automatically compiles Java code into .class files before loading them.
<web-app xmlns="http://caucho.com/ns/resin"> <prologue> <class-loader> <compiling-loader path="WEB-INF/classes" source="WEB-INF/src"/> </class-loader> </prologue> </web-app> <database> defines a database (i.e. DataSource) resource. The database configuration section has more details on the configuration. A code pattern for using databases is in a DataSource tutorial.
database = element database { backup-driver* & close-dangling-connections? & connection? & connection-wait-time? & driver+ & jndi-name? & max-active-time? & max-close-statements? & max-connections? & max-create-connections? & max-idle-count? & max-idle-time? & max-overflow-connections? & max-pool-time? & name? & password? & ping? & ping-interval? & ping-query? & ping-table? & prepared-statement-cache-size? & save-allocation-stack-trace? & spy? & transaction-timeout? & user? & wrap-statements? & xa? & xa-forbid-same-rm? } backup-driver = element backup-driver { class? & url? & element * { * }? } connection = element connection { catalog? & read-only? & transaction-isolation? } driver = element driver { class? & url? & element * { * }? } <web-app xmlns="http://caucho.com/ns/resin"> <database jndi-name='jdbc/test_mysql'> <driver class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"> <url>jdbc:mysql://localhost:3306/test</url> <user></user> <password></password> </driver> </database> </web-app> <database-default> defines default database values to be used for any <database> definition, or runtime database creation (see DatabaseManager). element database-default { r_database-Content } <web-app xmlns="http://caucho.com/ns/resin"> <database-default> <max-idle-time>10s</max-idle-time> </database-default> </web-app> <dependency> adds dependent files which should force a reload when changed, like web.xml and resin-web.xml.
element dependency { string } <web-app xmlns="http://caucho.com/ns/resin"> <dependency path="WEB-INF/struts-config.xml"/> ... </web-app> <dependency-check-interval> Configures how often the environment context should be checked for changes. The default value is set low for development purposes, deployments should use something larger like 5m or 1h. Resin automatically checks each environment for updates, generally class or configuration updates. Because these checks can take a considerable amount of time, deployment servers should use high values like 60s or more while development machines will want low values like 2s. The interval defaults to the parent's interval. So the web-app will default to the host's value. element dependency-check-interval { string } <resin xmlns="http://caucho.com/ns/resin"> <cluster id="app-tier"> <dependency-check-interval>1h<dependency-check-interval> <server id="app-a" .../> <host id=""/> ... </cluster> </resin> <ejb-message-bean> configures a bean as a message listener.
The listener can be a simple bean that just implements the
The bean has full access to Resin-IoC capabilities, including dependency injection, transaction attributes, and aspect interception. The message bean can plug into custom messaging systems. The
application will need to define a ResourceAdapter and
an
element ejb-message-bean { class & init? & (activation-spec? | (destination? & destination-type? & destination-name? & message-consumer-max?) ) } Configures an EJB server.
element ejb-server { auto-compile & create-database-schema & data-source & config-directory & ejb-descriptor & ejb-jar & jndi-prefix & validate-database-schema & jms-connection-factory & xa-data-source } <ejb-stateful-bean> is deprecated and replaced by CDI-style configuration. EJB stateful beans are now either scanned automatically if configured with the @Stateful annotation or can be configured as CDI beans with the <ee:Stateful> tag. <web-app xmlns="http://caucho.com/ns/resin" xmlns:ee="urn:java:ee" xmlny:mypkg="urn:java:com.mycom.mypkg"> <mypkg:MyBean> <ee:Stateful/> <my-attribute>my-value</my-attribute> </mypkg:MyBean> </web-app> <ejb-stateless-bean> is deprecated and replaced by CDI-style configuration. EJB stateless beans are now either scanned automatically if configured with the @Stateless annotation or can be configured as CDI beans with the <ee:Stateless> tag. <web-app xmlns="http://caucho.com/ns/resin" xmlns:ee="urn:java:ee" xmlny:mypkg="urn:java:com.mycom.mypkg"> <mypkg:MyBean> <ee:Stateless/> <my-attribute>my-value</my-attribute> </mypkg:MyBean> </web-app> <env-entry> configures a JNDI scalar value for JNDI-based application configuration. Some application beans prefer to retrieve configuration data from JNDI, including String, Integer, and Double constants. env-entry configures that data in the current context. The value can not use JSP-EL expressions, because the env-entry is part of the JavaEE spec. To set EL expressions, use resin:set instead.
element env-entry { description*, env-entry-name, env-entry-type, env-entry-value } The example configuration stores a string in java:comp/env/greeting. Following the J2EE spec, the env-entry-name is relative to java:comp/env. If the env-entry is in the <host> context, it will be visible to all web-apps in the host. <web-app xmlns="http://caucho.com/ns/resin"> <env-entry> <env-entry-name>greeting</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>Hello, World</env-entry-value> </env-entry> <servlet ...> </servlet> </web-app> The following servlet fragment is a typical use in a servlet. The servlet only looks up the variable once and stores it for later use. import java.io.*; import javax.naming.*; import javax.servlet.*; import javax.servlet.http.*; public class TestServlet extends HttpServlet { private String greeting; public void init() throws ServletException { try { Context env = (Context) new InitialContext().lookup("java:comp/env"); greeting = (String) env.lookup("greeting"); } catch (NamingException e) { throw new ServletException(e); } } ... } <fileset> provides the ability to match a set of files. It is modelled after the ant tag by the same name. The fileset matches files from a base directory defined by 'dir'. Files can be included by patterns defined by <include> tags or excluded by patterns defined in <exclude> tags. A pattern can contain two special characters: '*' and '**'. '*' matches any part of path, but does not match the path separator. '**' matches any part of a path, including the path separator.
element fileset { dir & exclude* & include* <fileset dir="WEB-INF/lib"> <include name="*.jar"/> </fileset> MATCH lib/foo.jar MATCH lib/bar.jar NO MATCH lib/baz/foo.jar <fileset dir="WEB-INF/tree"> <include name="**/*.jar"/> </fileset> MATCH lib/foo.jar MATCH lib/bar.jar MATCH lib/baz/foo.jar <javac> configures the Java compiler for automatically compiled files. The javac configuration is used for JSP, PHP, EJB and compiling-loader configuration. Thus you can deploy JSPs to Resin and it will use the compiler to generate classes at runtime. In other words, you do not need to precompile your JSPs, Java files, et al. to deploy them on Resin. The internal compiler (recommended) requires tools.jar from the JDK installation, so a JDK must be used (not a JRE). Sometimes the internal compiler causes errors, creating exceptions or simply hanging and taking up a thread. The solution is to change the compiler to use an external compiler. The javac compiler is included with the JDK. It performs the same function as the internal compiler, however it is executed as an external process and is less prone to the problems described for the internal compiler. In resin.xml with the javac configuration option:
element javac { args* & compiler & encoding? & max-batch? } <resin xmlns="http://caucho.com/ns/resin"> <javac compiler="internal" args=""/> </resin> <resin xmlns="http://caucho.com/ns/resin"> <javac compiler="javac" args=""/> ... </resin> <jndi-link> creates a symbolic link from one jndi name to another, or links to a foreign JNDI context. Resin's JNDI can link to foreign JNDI contexts. For example, third-party EJB servers will often expose their EJB beans through a JNDI context. jndi-link will create the appropriate InitialContextFactory, configure it, and lookup the foreign JNDI objects.
element jndi-link { jndi-name & factory? & foreign-name? & init-param* } <web-app xmlns="http://caucho.com/ns/resin"dd> <database jndi-name="jdbc/oracle"> ... </database> <jndi-link jndi-name="java:comp/env/jdbc/gryffindor"> <foreign-name>java:comp/env/jdbc/oracle</foreign-name> </jndi-link> <jndi-link jndi-name="java:comp/env/jdbc/slytherin"> <foreign-name>java:comp/env/jdbc/oracle</foreign-name> </jndi-link> </web-app> <web-app xmlns="http://caucho.com/ns/resin"> <jndi-link jndi-name='java:comp/env/ejb'> <factory>com.caucho.ejb.hessian.HessianContextFactory</factory> <init-param java.naming.provider.url='http://ejb.hogwarts.com:80/hessian'/> </jndi-link> </web-app> <web-app xmlns="http://caucho.com/ns/resin"> <jndi-link jndi-name='java:comp/env/remote-ejb'> <factory>com.caucho.ejb.hessian.HessianContextFactory</factory> <init-param java.naming.provider.url='http://ejb.hogwarts.com:80/hessian'/> </jndi-link> <jndi-link jndi-name="java:comp/env/ejb/Foo"> <foreign-name>java:comp/env/remote-ejb/Foo</foreign-name> </jndi-link> <jndi-link jndi-name="java:comp/env/ejb/Bar"> <foreign-name>java:comp/env/local-ejb/Bar</foreign-name> </jndi-link> </web-app>
element jpa-persistence { create-database-schema? & cache-size? & cache-timeout? & data-source? & jdbc-isolation? & persistence-unit* & persistence-unit-default* & read-data-source? & validate-database-schema? & xa-data-source? } element persistence-unit { name & jta-data-source? & non-jta-data-source? & provider? & transaction-type? & properties? } element persistence-unit-default { & jta-data-source? & non-jta-data-source? & provider? & transaction-type? & properties? } element properties { element property { name & value }* } child of class-loader
<library-loader> configures a jar library, -style class loader.The library-loader will add jar files in its path to the current
classpath. Jar files are recognized wihen they have a filename extension
of See DirectoryLoader.
element library-loader { fileset | path } element fileset { dir & exclude* & include* } <log> configures JDK 1.4 java.util.logger Logger level. The log configuration describes log in detail.
element logger { name & level? & use-parent-handlers? } <resin xmlns="http://caucho.com/ns/resin"> <log name="" level="all" path="log/debug.log"/> <logger name="com.caucho.java" level="fine"/> <cluster id="app-tier"> ... </cluster> </resin> <web-app xmlns="http://caucho.com/ns/resin" xmlns:resin="urn:java:com.caucho.resin"> <resin:MemoryQueue ee:Named="myQueue"/> <logger name="qa.test"> <resin:JmsLogHandler level="warning"> <target>${myQueue}</target> <resin:TimestampLogFormatter/> </resin:JmsLogHandler> </logger> </web-app> <mail> configures a javax.mail.Session object and makes it available in Resin-IoC/WebBeans. Mail properties can be configured using the properties attribute. Some of the most common properties can be configured directly on the <mail> tag.
element mail { authenticator? & debug? & from? & host? & imap-host? & imap-port? & imap-user? & init? & jndi-name? & name? & pop3-host? & pop3-port? & pop3-user? & smtp-host? & smtp-port? & smtp-user? & store-protocol? & transport-protocol? & user? } <web-app xmlns="http://caucho.com/ns/resin"> <mail jndi-name="java:comp/env/mail"> <from>noreply@foo.com</from> <smtp-host>localhost</smtp-host> <smtp-port>25</smtp-port> <properties> mail.smtp.starttls.enable=true </properties> </mail> </web-app> <reference> configures a JNDI ObjectFactory. Some legacy resources are configured using an ObjectFactory syntax. The <reference> tag provides a compatible way to configure those objects. More modern resources should use <bean> or <component> for IoC configuration. JNDI ObjectFactories are used to create objects from JNDI references. The <reference> tag configures the ObjectFactory and stores it in JNDI.
element reference { factory & jndi-name & init-param* } <web-app xmlns="http://caucho.com/ns/resin"> <reference> <jndi-name>hessian/hello</jndi-name> <factory>com.caucho.hessian.client.HessianProxyFactory</factory> <init url="http://localhost:8080/ejb/hello"/> type="test.HelloHome"/> </reference> </web-app> <remote-client> configures a proxy to a web-service. It uses a Java interface and a URI to select the web-service. The URI is defined as: , where location is typically a HTTP URL.
element remote-client { (class|uri) & name? & jndi-name? & interface } resin:choose implements an if, elsif, else. The <resin:choose> schema is context-dependent. A <resin:choose> in a <web-app> will have <web-app> content, while a <resin:choose> in a <host> will have <host> content.
element resin:choose { resin:when*, resin:otherwise } element resin:when { attribute test { string },} element resin:otherwise { } <resin:choose> <resin:when test="${expr1}"> ... </resin:when> <resin:when test="${expr2}"> ... </resin:when> <resin:otherwise> ... </resin:otherwise> <resin:choose> resin:if executes part of the configuration file conditionally. resin:if can be particularly useful in combination with Java command-line properties like -Dfoo=bar to enable development mode or testing configuration. The resin:if schema is context-dependent. For example, resin:if in a <web-app> will have web-app content while resin:if in a <host> will have host content.
element resin:if {
attribute test { string }
}
<resin xmlns="http://caucho.com/ns/resin" xmlns:core="http://caucho.com/ns/resin/core"> <resin:if test="${system['development']}"> <logger name="com.foo" level="finer"/> </resin:if> ... </resin> <resin:import> reads configuration from another file or set of files. For example, the WEB-INF/web.xml and WEB-INF/resin-web.xml files are implemented as <resin:import> in the app-default.xml. The target file is validated by the schema of the including context. So a resin:import in <web-app-default> will have a target with a top-level of <web-app>, and a resin:import in <cluster> will have a top-level tag of <cluster>.
element import { (path | fileset) & optional? } element fileset { dir & exclude* & include* } The following example shows how Resin implements the WEB-INF/web.xml and WEB-INF/resin-web.xml files. Both are simply resin:import in a web-app-default. When Resin configures the web-app, it will process the web-app-default program, and call resin:import for the web.xml file. <resin xmlns="http://caucho.com/ns/resin" xmlns:resin="http://caucho.com/ns/resin/core"> <cluster id="app-tier"> <web-app-default> <resin:import path="WEB-INF/web.xml" optional="true"/> <resin:import path="WEB-INF/resin-web.xml" optional="true"/> </web-app-default> </cluster> </resin> Virtual hosts can use resin:import to add a custom host.xml file. The host.xml can use any <host> attribute, including <host-name> and <host-alias> to customize the virtual host configuration. <resin xmlns="http://caucho.com/ns/resin" xmlns:resin="http://caucho.com/ns/resin/core"> <cluster id="app-tier"> <host-deploy path="/var/www/hosts"> <host-default> <resin:import path="host.xml" optional="true"/> <web-app-deploy path="webapps"/> </host-default> </web-app-default> </cluster> </resin> Some applications may want to split their configuration into multiple files using the fileset. For example, a Resin-IoC application might want to define beans in WEB-INF/beans/*.xml and give the web-app flexibility in which bean files to create. <web-app xmlns="http://caucho.com/ns/resin" xmlns:core="http://caucho.com/ns/resin/core"> <resin:import> <fileset dir="WEB-INF/beans"> <include>*.xml</include> </fileset> </resin:import> </web-app> Logs a message to the given log file. The content of the element is the message. element resin:message { string } <web-app xmlns="http://caucho.com/ns/resin" xmlns:resin="http://caucho.com/ns/resin/core"> <resin:message>Starting server ${server.name}</resin:message> </web-app> resin:set adds an EL variable to the current context.
element set { name & value & default & attribute * { string } } <resin xmlns="http://caucho.com/ns/resin" xmlns:resin="http://caucho.com/ns/resin/core"> <resin:set name="root" value="/var/www"/> <cluster id="app-tier"> <root-directory>${root}</root-directory> ... </cluster> </resin> <resource> is an obsolete synonym for <bean> to define custom singletons. Applications should use the <bean> syntax instead. <resource-ref> declares that the application needs a resouce configuration. resource-ref is not directly used by Resin. It's a servlet configuration item intended to tell GUI tools which resources need configuration. Resource configuration in Resin uses the resource, reference, database, and ejb-server tags. For backwards compatibility, Resin 2.1-style configuration files may still use resource-ref to configure resources, but it's recommended to convert the configuration. element resource-ref { attribute id?, description*, res-ref-name, ref-type, res-auth, res-sharing-scope? } child of web-app
The <scheduled-task> is replaced by bean-style resin:ScheduleTask. <web-app xmlns="http://caucho.com/ns/resin" xmlns:ee="urn:java:ee" xmlns:mypkg="urn:java:com.mycom.mypkg"> <resin:ScheduleTask> <cron>* * 23 * *</cron> <task> <mypkg:MyBean/> </task> </resin:ScheduleTask> </web-app> child of class-loader
Use of servlet-hack is discouraged. Using servlet-hack violates the JDK's classloader delegation model and can produce surprising ClassCastExceptions. servlet-hack reverses the normal class loader order. Instead of parent classloaders having priority, child classloaders have priority. element servlet-hack { boolean } child of class-loader
<simple-loader> Configures a simple -style class loader..class files in the specified directory will be loaded without any special compilation steps (in contrast with compiling-loader.)
element simple-loader { path & prefix? } Configures the destination for The log configuration describes stderr-log in detail.
element stderr-log { (path | path-format) & archive-format? & rollover-period? & rollover-size? & rollover-count? & timestamp? } Configures the destination for The log configuration describes stderr-log in detail.
element stdout-log { (path | path-format) & archive-format? & rollover-period? & rollover-size? & rollover-count? & timestamp? } Sets a Java system property. The effect is the same as if you had called java.lang.System#setProperty(String,String) before starting Resin. element system-property { attribute * { string }+ } <resin xmlns="http://caucho.com/ns/resin"> <system-property foo="bar"/> </resin> <temp-dir> configures the application temp directory. This is the path used in .element temp-dir { string } child of class-loader
<tree-loader> configures a jar library, library-loader, but will also find
element tree-loader { path } <work-dir> configures a work directory for automatically generated code, e.g. for JSP, PHP, and JPA classes. element work-dir { string }
|