views:

522

answers:

2

Hi,

I am trying to read database scripts in a Jar file so that I can split up my import.sql files as many times as I see fit.

For instance, I have several projects or modules that provide reference data, so I have a few separate scripts in each project that declares that. Instead of having one large import.sql, my approach was to split it up to make it more readable as well as keep the data in one place so if I have multiple web application projects, I don't have to redeclare and maintain those files separately.

I think I am having an issue with javassist - I created a helper class (in module, FileIO) that simply looks for a given name, then for all matches, it will attempt to read the configuration, locate the database scripts, read them line by line, and return an object which I can iterative over to execute the queries.

When I call that helper class (from my Seam project), I am getting NoSuchMethodError. If I move all of that functionality back into the Seam Component that the call originates from, it works most of the way. The last issue being, if I have more than 1 configuration file, for some odd reason, even though the URL points to the correct configuration file, only the first one is ever used?

I am using JBoss Seam 2.2.0.GA, Javassist 3.11.0.GA, and Hibernate Entity Manager 3.4.0.GA.

Seam Component

@Observer("org.jboss.seam.postInitialization")
        @Transactional
        public void prepareDatabase() throws IOException
        {
         log.debug(getVersions());
         log.debug("initializing database");

         List<DatabaseImport> databaseImports = DatabaseImporter.getImports();

         for(DatabaseImport databaseImport : databaseImports)
         {
          for(String query : databaseImport.getQueries())
          {
           // ensure we don't create blank queries or ones that are comments only
           if(StringUtils.isNotBlank(query) && !query.startsWith("--"))
            entityManager.createNativeQuery(query).executeUpdate();
          }
         }
        }

Helper Methods:

public static List<String> readFromStream(final InputStream inputStream)
                      throws IOException
    {
     List<String> lines = new ArrayList<String>();
     BufferedReader reader = null;

     try
     {
      reader = new BufferedReader(new InputStreamReader(inputStream));

      String line = null;

      while((line = reader.readLine()) != null)
       lines.add(line);
     }
     finally
     {
      if(reader != null)
       reader.close();
     }

     return (lines);
    }

    public static List<String> readFromClassLoader(final String name)
                        throws IOException
    {
     return (readFromStream(Thread.currentThread().getContextClassLoader().getResourceAsStream(name)));
    }

    public static String toString(List<String> lines) throws IOException
    {
     StringBuilder buffer = new StringBuilder();

     for(String line : lines)
      buffer.append(line);

     return (buffer.toString());
    }

    public static List<String> readLinesFromURL(URL url, ClassLoader classLoader, List<String> names)
                       throws IOException
    {
     URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url}, classLoader);

     List<String> lines = new ArrayList<String>();

     for(String name : names)
      lines.addAll(readLinesFromURL(urlClassLoader, name));

     return (lines);
    }

    public static List<String> readLinesFromURL(URL url, ClassLoader classLoader, final String name)
                       throws IOException
    {
     return (readLinesFromURL(new URLClassLoader(new URL[]{url}, classLoader), name));
    }

    public static List<String> readLinesFromURL(URLClassLoader urlClassLoader, final String name)
                       throws IOException
    {
     return (readFromStream(urlClassLoader.getResourceAsStream(name)));
    }

    public static String readAsString(final File file) throws IOException
    {
     return (new String(read(file)));
    }

I am using the Java API properly, is this an issue with javassist? Any thoughts and suggestions are appreciated.

EDIT: StackTrace

java.lang.RuntimeException: exception invoking: prepareDatabase
    at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:154)
    at org.jboss.seam.Component.callComponentMethod(Component.java:2249)
    at org.jboss.seam.core.Events.raiseEvent(Events.java:85)
    at org.jboss.seam.contexts.ServletLifecycle.endInitialization(ServletLifecycle.java:118)
    at org.jboss.seam.init.Initialization.init(Initialization.java:740)
    at org.jboss.seam.servlet.SeamListener.contextInitialized(SeamListener.java:36)
    at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
    at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
    at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1239)
    at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
    at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:466)
    at org.mortbay.jetty.plugin.Jetty6PluginWebAppContext.doStart(Jetty6PluginWebAppContext.java:124)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
    at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:156)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.jetty.Server.doStart(Server.java:222)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.plugin.Jetty6PluginServer.start(Jetty6PluginServer.java:132)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:441)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:383)
    at org.mortbay.jetty.plugin.Jetty6RunWar.execute(Jetty6RunWar.java:67)
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:483)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:678)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:553)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:523)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:371)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:332)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:181)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:356)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:137)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
    at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
    at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
    at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
    at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:32)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
    at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:28)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:77)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.transaction.TransactionInterceptor$1.work(TransactionInterceptor.java:97)
    at org.jboss.seam.util.Work.workInTransaction(Work.java:47)
    at org.jboss.seam.transaction.TransactionInterceptor.aroundInvoke(TransactionInterceptor.java:91)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
    at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:185)
    at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:103)
    at com.walterjwhite.seamCore.deployment.ApplicationStartupListener_$$_javassist_seam_1.prepareDatabase(ApplicationStartupListener_$$_javassist_seam_1.java)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
    at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:144)
    ... 43 more
Caused by: java.lang.NoSuchMethodError: com.walterjwhite.io.file.FileReader.readLinesFromURL(Ljava/net/URL;Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/util/List;
    at com.walterjwhite.seamCore.persistence.DatabaseImporter.getImports(DatabaseImporter.java:34)
    at com.walterjwhite.seamCore.deployment.ApplicationStartupListener.prepareDatabase(ApplicationStartupListener.java:80)

Thanks, Walter

A: 

A NoSuchMethodError occur if you use at runtime another version of the class as at compile time. More deails show your the exception.

Horcrux7
That makes sense - javassist must be modifying the class as it is a Seam component. I'll see if I can re-obtain the stack trace, I made some significant changes in the API and don't have that block of code currently working.Walter
+1  A: 

I found the problem ... I marked the class as final. With AOP you have to be careful what you mark as final, otherwise it can lead to headaches. Looks like another case of premature optimization.

Walter