You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by "Henning Schmiedehausen (JIRA)" <de...@velocity.apache.org> on 2007/03/08 01:04:34 UTC

[jira] Closed: (VELOCITY-176) DataSourceResourceLoader throws null pointer exception

     [ https://issues.apache.org/jira/browse/VELOCITY-176?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Henning Schmiedehausen closed VELOCITY-176.
-------------------------------------------


> DataSourceResourceLoader throws null pointer exception
> ------------------------------------------------------
>
>                 Key: VELOCITY-176
>                 URL: https://issues.apache.org/jira/browse/VELOCITY-176
>             Project: Velocity
>          Issue Type: Bug
>          Components: Engine
>    Affects Versions: 1.3.1
>         Environment: Operating System: All
> Platform: PC
>            Reporter: Vlad Mangeym
>         Assigned To: Velocity-Dev List
>             Fix For: 1.5
>
>         Attachments: DataSourceResourceLoader.java.patch
>
>
> Hi,
> I am trying  to use DB (Oracle) as a storage for my templates, but using
> org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader class I am 
> getting consistently null pointer exception.
> I was able to debug it and it seems that this could be the fix for this problem:
> change getResourceStream function to return StringBufferInputStream(strField), 
> where strField is: String strField = rs.getString(templateColumn);
> (not  BufferedInputStream(rs.getAsciiStream(templateColumn)) )
> Note: this also will require import java.io.*;
> Please see the modified class below.
> Please let me know if this change make sense or is there something else I 
> should do to avoid this problem.
> Thanks.
> package org.apache.velocity.runtime.resource.loader;
> import java.io.*;
> /*
>  * The Apache Software License, Version 1.1
>  *
>  * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
>  * reserved.
>  *
>  * Redistribution and use in source and binary forms, with or without
>  * modification, are permitted provided that the following conditions
>  * are met:
>  *
>  * 1. Redistributions of source code must retain the above copyright
>  *    notice, this list of conditions and the following disclaimer.
>  *
>  * 2. Redistributions in binary form must reproduce the above copyright
>  *    notice, this list of conditions and the following disclaimer in
>  *    the documentation and/or other materials provided with the
>  *    distribution.
>  *
>  * 3. The end-user documentation included with the redistribution, if
>  *    any, must include the following acknowlegement:
>  *       "This product includes software developed by the
>  *        Apache Software Foundation (http://www.apache.org/)."
>  *    Alternately, this acknowlegement may appear in the software itself,
>  *    if and wherever such third-party acknowlegements normally appear.
>  *
>  * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
>  *    Foundation" must not be used to endorse or promote products derived
>  *    from this software without prior written permission. For written
>  *    permission, please contact apache@apache.org.
>  *
>  * 5. Products derived from this software may not be called "Apache"
>  *    nor may "Apache" appear in their names without prior written
>  *    permission of the Apache Group.
>  *
>  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>  * SUCH DAMAGE.
>  * ====================================================================
>  *
>  * This software consists of voluntary contributions made by many
>  * individuals on behalf of the Apache Software Foundation.  For more
>  * information on the Apache Software Foundation, please see
>  * <http://www.apache.org/>.
>  */
> import java.io.InputStream;
> import java.io.BufferedInputStream;
> import java.util.Hashtable;
> import javax.sql.DataSource;
> import javax.naming.InitialContext;
> import org.apache.velocity.runtime.Runtime;
> import org.apache.velocity.runtime.resource.Resource;
> import org.apache.velocity.exception.ResourceNotFoundException;
> import org.apache.commons.collections.ExtendedProperties;
> import java.sql.Connection;
> import java.sql.ResultSet;
> import java.sql.Statement;
> import java.sql.SQLException;
> /**
>  * This is a simple template file loader that loads templates
>  * from a DataSource instead of plain files.
>  *
>  * It can be configured with a datasource name, a table name,
>  * id column (name), content column (the template body) and a
>  * datetime column (for last modification info).
>  * <br>
>  * <br>
>  * Example configuration snippet for velocity.properties:
>  * <br>
>  * <br>
>  * resource.loader = file, ds <br>
>  * <br>
>  * ds.resource.loader.public.name = DataSource <br>
>  * ds.resource.loader.description = Velocity DataSource Resource Loader <br>
>  * ds.resource.loader.class = 
> org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader <br>
>  * ds.resource.loader.resource.datasource = java:comp/env/jdbc/Velocity <br>
>  * ds.resource.loader.resource.table = tb_velocity_template <br>
>  * ds.resource.loader.resource.keycolumn = id_template <br>
>  * ds.resource.loader.resource.templatecolumn = template_definition <br>
>  * ds.resource.loader.resource.timestampcolumn = template_timestamp <br>
>  * ds.resource.loader.cache = false <br>
>  * ds.resource.loader.modificationCheckInterval = 60 <br>
>  * <br>
>  * Example WEB-INF/web.xml: <br>
>  * <br>
>  *	<resource-ref> <br>
>  *	 <description>Velocity template DataSource</description> <br>
>  *	 <res-ref-name>jdbc/Velocity</res-ref-name> <br>
>  *	 <res-type>javax.sql.DataSource</res-type> <br>
>  *	 <res-auth>Container</res-auth> <br>
>  *	</resource-ref> <br>
>  * <br>
>  *  <br>
>  * and Tomcat 4 server.xml file: <br>
>  *  [...] <br>
>  *  <Context path="/exampleVelocity" docBase="exampleVelocity" debug="0"> <br>
>  *  [...] <br>
>  *   <ResourceParams name="jdbc/Velocity"> <br>
>  *    <parameter> <br>
>  *      <name>driverClassName</name> <br>
>  *      <value>org.hsql.jdbcDriver</value> <br>
>  *    </parameter> <br>
>  *    <parameter> <br>
>  *     <name>driverName</name> <br>
>  *     <value>jdbc:HypersonicSQL:database</value> <br>
>  *    </parameter> <br>
>  *    <parameter> <br>
>  *     <name>user</name> <br>
>  *     <value>database_username</value> <br>
>  *    </parameter> <br>
>  *    <parameter> <br>
>  *     <name>password</name> <br>
>  *     <value>database_password</value> <br>
>  *    </parameter> <br>
>  *   </ResourceParams> <br>
>  *  [...] <br>
>  *  </Context> <br>
>  *  [...] <br>
>  * <br>
>  *  Example sql script:<br>
>  *  CREATE TABLE tb_velocity_template ( <br>
>  *	id_template varchar (40) NOT NULL , <br>
>  *	template_definition text (16) NOT NULL , <br>
>  *	template_timestamp datetime NOT NULL  <br>
>  *	) <br>
>  *
>  * @author <a href="mailto:david.kinnvall@alertir.com">David Kinnvall</a>
>  * @author <a href="mailto:paulo.gaspar@krankikom.de">Paulo Gaspar</a>
>  * @author <a href="mailto:lachiewicz@plusnet.pl">Sylwester Lachiewicz</a>
>  * @version $Id: DataSourceResourceLoader.java,v 1.8 2002/02/10 18:46:58 geirm 
> Exp $
>  */
> public class DataSourceResourceLoader extends ResourceLoader
> {
>      private String dataSourceName;
>      private String tableName;
>      private String keyColumn;
>      private String templateColumn;
>      private String timestampColumn;
>      private InitialContext ctx;
>      private DataSource dataSource;
>      public void init( ExtendedProperties configuration)
>      {
>          dataSourceName  = configuration.getString("resource.datasource");
>          tableName       = configuration.getString("resource.table");
>          keyColumn       = configuration.getString("resource.keycolumn");
>          templateColumn  = configuration.getString("resource.templatecolumn");
>          timestampColumn = configuration.getString("resource.timestampcolumn");
>          Runtime.info("Resources Loaded From: " + dataSourceName + "/" + 
> tableName);
>          Runtime.info( "Resource Loader using columns: " + keyColumn + ", "
>                        + templateColumn + " and " + timestampColumn);
>          Runtime.info("Resource Loader Initalized.");
>      }
>      public boolean isSourceModified(Resource resource)
>      {
>          return (resource.getLastModified() !=
>                  readLastModified(resource, "checking timestamp"));
>      }
>      public long getLastModified(Resource resource)
>      {
>          return readLastModified(resource, "getting timestamp");
>      }
>      /**
>       * Get an InputStream so that the Runtime can build a
>       * template with it.
>       *
>       *  @param name name of template
>       *  @return InputStream containing template
>       */
>      public synchronized InputStream getResourceStream( String name )
>          throws ResourceNotFoundException
>      {
>          if (name == null || name.length() == 0)
>          {
>              throw new ResourceNotFoundException ("Need to specify a template 
> name!");
>          }
>          try
>          {
>              Connection conn = openDbConnection();
>              try
>              {
>                  ResultSet rs = readData(conn, templateColumn, name);
>                 try {
>                     if (rs.next()) {
>                         String strField = rs.getString(templateColumn);
>                          return new
>                                 StringBufferInputStream(strField);
>                         //return new
>                         //    BufferedInputStream(rs.getAsciiStream
> (templateColumn));
>                      }
>                      else
>                      {
>                          String msg = "DataSourceResourceLoader Error: cannot 
> find resource "
>                              + name;
>                          Runtime.error(msg );
>                          throw new ResourceNotFoundException (msg);
>                      }
>                  }
>                  finally
>                  {
>                      rs.close();
>                  }
>              }
>              finally
>              {
>                  closeDbConnection(conn);
>              }
>          }
>          catch(Exception e)
>          {
>              String msg =  "DataSourceResourceLoader Error: database problem 
> trying to load resource "
>                  + name + ": " + e.toString();
>              Runtime.error( msg );
>              throw new ResourceNotFoundException (msg);
>          }
>      }
>     /**
>      *  Fetches the last modification time of the resource
>      *
>      *  @param resource Resource object we are finding timestamp of
>      *  @param i_operation string for logging, indicating caller's intention
>      *
>      *  @return timestamp as long
>      */
>      private long readLastModified(Resource resource, String i_operation)
>      {
>          /*
>           *  get the template name from the resource
>           */
>          String name = resource.getName();
>          try
>          {
>              Connection conn = openDbConnection();
>              try
>              {
>                  ResultSet rs = readData(conn, timestampColumn, name);
>                  try
>                  {
>                      if (rs.next())
>                      {
> 	                     return rs.getTimestamp(timestampColumn).getTime();
>                      }
>                      else
>                      {
>                          Runtime.error("DataSourceResourceLoader Error: while "
>                                        + i_operation
>                                        + " could not find resource " + name);
>                      }
>                  }
>                  finally
>                  {
>                      rs.close();
>                  }
>              }
>              finally
>              {
>                  closeDbConnection(conn);
>              }
>          }
>          catch(Exception e)
>          {
>              Runtime.error( "DataSourceResourceLoader Error: error while "
>                  + i_operation + " when trying to load resource "
>                  + name + ": " + e.toString() );
>          }
>          return 0;
>      }
>     /**
>      *   gets connection to the datasource specified through the configuration
>      *  parameters.
>      *
>      *  @return connection
>      */
>      private Connection openDbConnection()
>          throws Exception
>     {
>          if(ctx == null)
>          {
>              ctx = new InitialContext();
>          }
>          if(dataSource == null)
>          {
>              dataSource = (DataSource)ctx.lookup(dataSourceName);
>          }
>          return dataSource.getConnection();
>      }
>     /**
>      *  Closes connection to the datasource
>      */
>      private void closeDbConnection(Connection conn)
>      {
>          try
>          {
>              conn.close();
>          }
>          catch (Exception e)
>          {
>              Runtime.info(
>                  "DataSourceResourceLoader Quirk: problem when closing 
> connection: "
>                  + e.toString());
>          }
>      }
>     /**
>      *  Reads the data from the datasource.  It simply does the following 
> query :
>      *  <br>
>      *   SELECT <i>columnNames</i> FROM <i>tableName</i> WHERE <i>keyColumn</i>
>      *      = '<i>templateName</i>'
>      *  <br>
>      *  where <i>keyColumn</i> is a class member set in init()
>      *
>      *  @param conn connection to datasource
>      *  @param columnNames columns to fetch from datasource
>      *  @param templateName name of template to fetch
>      *  @return result set from query
>      */
>      private ResultSet readData(Connection conn, String columnNames, String 
> templateName)
>          throws SQLException
>      {
>          Statement stmt = conn.createStatement();
>          String sql = "SELECT " + columnNames
>                       + " FROM " + tableName
>                       + " WHERE " + keyColumn + " = '" + templateName + "'";
>          return stmt.executeQuery(sql);
>      }
> }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@velocity.apache.org
For additional commands, e-mail: dev-help@velocity.apache.org