0

我正在尝试读取 Jar 文件中的数据库脚本,以便可以根据需要多次拆分 import.sql 文件。

例如,我有几个提供参考数据的项目或模块,所以我在每个项目中都有几个单独的脚本来声明它。我的方法不是拥有一个大的 import.sql,而是将其拆分以使其更具可读性并将数据保存在一个地方,因此如果我有多个 Web 应用程序项目,我不必重新声明和维护这些文件分别地。

我想我在使用 javassist 时遇到了问题 - 我创建了一个帮助程序类(在模块 FileIO 中),它只是查找给定名称,然后对于所有匹配项,它将尝试读取配置,定位数据库脚本,读取它们行按行,并返回一个我可以迭代执行查询的对象。

当我调用那个助手类(来自我的 Seam 项目)时,我得到了 NoSuchMethodError。如果我将所有这些功能移回调用所源自的 Seam 组件,它在大多数情况下都可以正常工作。最后一个问题是,如果我有多个配置文件,出于某种奇怪的原因,即使 URL 指向正确的配置文件,也只有第一个被使用过?

我正在使用 JBoss Seam 2.2.0.GA、Javassist 3.11.0.GA 和 Hibernate Entity Manager 3.4.0.GA。

接缝组件

@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();
                }
            }
        }

辅助方法:

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)));
    }

我正在正确使用 Java API,这是 javassist 的问题吗?任何想法和建议表示赞赏。

编辑:堆栈跟踪

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)

谢谢,沃尔特

4

2 回答 2

1

我发现了问题......我将课程标记为最终课程。使用 AOP,您必须小心标记为 final 的内容,否则可能会导致头痛。看起来像是另一种过早优化的情况。

沃尔特

于 2009-09-26T20:05:31.457 回答
0

如果您在运行时使用类的另一个版本(如在编译时),则会发生 NoSuchMethodError。更多交易显示您的例外。

于 2009-09-06T18:05:16.720 回答