gpt4 book ai didi

grails - maven下用grails指定 "provided"依赖

转载 作者:行者123 更新时间:2023-12-02 14:04:07 27 4
gpt4 key购买 nike

我有一个 grails 1.3.7 应用程序。我正在使用 Spring 的 JMS 类将我的一个 grails 服务设置为消息监听器,在 grails-app/conf/resources.groovy 中设置这些类。我使用 maven 2.0.9 进行构建,使用 grails-maven-plugin 1.3.7 和“maven-war”目标来创建一个 war 文件。

我有两种情况:

  • 我希望能够使用“mvn grails:run-app”从命令行本地运行我的 grails 应用程序。我在开发过程中使用它。
  • 我希望能够通过部署 maven 创建的 war 文件在 JBoss 5.1.0 GA 中运行应用程序。这就是我们在集成、测试和生产环境中所做的。

  • 在 JBoss 中运行时,所有与 JMS 提供程序相关的依赖项都可用并由应用程序服务器提供。使用 maven 处理此问题的正常方法是在 pom 文件中声明这些依赖项,范围为“provided”。这将使这些依赖项可用于编译和单元测试,但将它们从 war 文件中排除。

    但是,当我使用“mvn grails:run-app”从命令行本地运行时,这些依赖项似乎在运行时对 grails 不可用,许多 ClassNotFound 等异常证明了这一点。将范围更改为“编译”允许我在本地运行。但是,现在这些依赖项被打包到我的 war 文件中,这是我不希望的,并且在 JBoss 中运行时往往会破坏事情。

    我现在找到的解决方案(或解决方法)是在我的 pom 中包含这些具有默认(编译)范围的 JMS 依赖项,并通过 BuildConfig.groovy 中的一些代码从 war 文件中删除这些 jars(及其所有传递依赖项)(见下文)。这可行,但它很困惑且容易出错,因为我必须列出每一个传递依赖项(其中有很多!)。

    我尝试过的其他一些事情:

    起初,我想也许我可以将所需的 JMS 依赖项添加到 BuildConfig.groovy 的“grails.project.dependency.resolution/dependencies”部分,并将它们完全排除在 pom 之外。但是,这不起作用,因为根据 this link ,在 maven 下运行 grails 时忽略 BuildConfig 依赖项部分。

    我还注意到“pom true”选项(在上面的链接中提到)并尝试使用它。但是,当尝试运行 grails:run-app 时,grails 会抛出有关未解决依赖项的警告并给出一个 tomcat 错误:
    :::: WARNINGS
    ::::::::::::::::::::::::::::::::::::::::::::::
    :: UNRESOLVED DEPENDENCIES ::
    ::::::::::::::::::::::::::::::::::::::::::::::
    :: commons-collections#commons-collections;3.2.1: configuration not found in commons-collections#commons-collections;3.2.1: 'master'. It was required from org.grails.internal#load-manager-grails;1.2-SNAPSHOT compile
    :: org.slf4j#slf4j-api;1.5.8: configuration not found in org.slf4j#slf4j-api;1.5.8: 'master'. It was required from org.grails.internal#load-manager-grails;1.2-SNAPSHOT runtime

    ...

    java.lang.LinkageError: loader constraint violation: when resolving overridden method "org.apache.tomcat.util.digester.Digester.setDocumentLocator(Lorg/xml/sax/Locator;)V" the class loader (instance of org/codehaus/groovy/grails/cli/support/GrailsRootLoader) of the current class, org/apache/tomcat/util/digester/Digester, and its superclass loader (instance of <bootloader>), have different Class objects for the type org/xml/sax/Locator used in the signature
    at org.grails.tomcat.TomcatServer.start(TomcatServer.groovy:212)

    我的问题:
    有没有更好的方法 - 通过 grails 和/或 maven 配置选项 - 来完成我想要的 - 即能够在本地和 JBoss 内成功运行 grails,而不必手动从 war 文件中排除所有传递依赖项?


    注意:我无法更改我正在使用的 grails、JBoss 或 maven 的版本。

    相关文件的一些摘录:

    BuildConfig.groovy:
    grails.project.class.dir = "target/classes"
    grails.project.test.class.dir = "target/test-classes"
    grails.project.test.reports.dir = "target/test-reports"
    grails.project.war.file = "target/${appName}-${appVersion}.war"

    grails.project.dependency.resolution = {
    // inherit Grails' default dependencies
    inherits("global") {
    // uncomment to disable ehcache
    // excludes 'ehcache'
    }
    log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
    repositories {
    // only use our internal Archiva instance
    mavenRepo "http://my-company.com/archiva/repository/mirror"
    mavenLocal()
    }
    dependencies {
    // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
    }

    //Remove own log4j and use the one supplied by JBoss instead
    grails.war.resources = {stagingDir ->
    delete file:"$stagingDir/WEB-INF/classes/log4j.properties" // logging conf done in JBoss only

    def files = fileScanner {
    fileset(dir:"$stagingDir/WEB-INF/lib"){
    [
    // all of the following are jms-related dependencies supplied by JBoss
    /* org.jboss.javaee */ "jboss-jms-api-*.jar",
    /* org.jboss.naming */ "jnp-client-*.jar",
    /* org.jboss */ "jboss-common-core-*.jar",
    /* org.jboss.logging */ "jboss-logging-spi-*.jar",
    /* jboss.messaging */ "jboss-messaging-*.jar",
    /* org.jboss.aop */ "jboss-aop-*.jar",
    /* org.apache.ant */ "ant-*.jar",
    /* org.apache.ant */ "ant-launcher-*.jar",
    /* org.jboss */ "jboss-reflect-*.jar",
    /* org.jboss */ "jboss-mdr-*.jar",
    /* qdox */ "qdox-*.jar",
    /* trove */ "trove-*.jar",
    /* org.jboss.logging */ "jboss-logging-log4j-*.jar",
    /* org.jboss.remoting */ "jboss-remoting-*.jar",
    /* jboss */ "jboss-serialization-*.jar",
    /* oswego-concurrent */ "concurrent-*.jar",
    /* org.jboss.jbossas */ "jboss-as-cluster-*-jboss-ha-legacy-client.jar",
    /* commons-logging */ "commons-logging-*.jar",
    /* org.jboss.jbossas */ "jboss-as-server-*.jar",
    /* sun-jaxb */ "jaxb-api-*.jar",
    /* org.jboss.jbossas */ "jboss-as-deployment-*.jar",
    /* org.jboss.javaee */ "jboss-jad-api-*.jar",
    /* org.jboss.security */ "jboss-security-spi-*.jar",
    . . . // and the other 74 transitive dependencies...
    ].each{
    include(name:it)
    }
    }
    }
    files.each
    {
    delete(file: it)
    }

    }
    }

    pom.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    . . .

    <dependencies>

    . . .

    <dependency>
    <!-- already a dep of grails-crud; make it scope:compile for resources.groovy -->
    <groupId>org.springframework</groupId>
    <artifactId>spring-jms</artifactId>
    <version>3.0.5.RELEASE</version>
    </dependency>
    <!-- Note: all the remaining jms dependencies below should be 'provided' scope, but
    grails doesn't correctly pull them in when running locally, so we must leave
    them as compile scope and remove them (and their transitive dependencies) from
    the war file through BuildConfig.groovy
    -->
    <dependency>
    <groupId>org.jboss.javaee</groupId>
    <artifactId>jboss-jms-api</artifactId>
    <version>1.1.0.GA</version>
    </dependency>
    <dependency>
    <groupId>org.jboss.naming</groupId>
    <artifactId>jnp-client</artifactId>
    <version>5.0.3.GA</version>
    </dependency>
    <dependency>
    <groupId>jboss.messaging</groupId>
    <artifactId>jboss-messaging</artifactId>
    <version>1.4.3.GA</version>
    </dependency>
    <dependency>
    <groupId>org.jboss.aop</groupId>
    <artifactId>jboss-aop</artifactId>
    <version>2.1.1.GA</version>
    <classifier>client</classifier>
    <exclusions>
    <exclusion>
    <!-- see http://jira.codehaus.org/browse/GROOVY-3356 -->
    <groupId>apache-xerces</groupId>
    <artifactId>xml-apis</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>org.jboss.remoting</groupId>
    <artifactId>jboss-remoting</artifactId>
    <version>2.5.3.SP1</version>
    </dependency>
    <dependency>
    <groupId>jboss</groupId>
    <artifactId>jboss-serialization</artifactId>
    <version>1.0.3.GA</version>
    </dependency>
    <dependency>
    <groupId>oswego-concurrent</groupId>
    <artifactId>concurrent</artifactId>
    <version>1.3.4-jboss-update1</version>
    </dependency>
    <!-- the following two are required in order to connect to HA-JNDI -->
    <dependency>
    <groupId>org.jboss.jbossas</groupId>
    <artifactId>jboss-as-cluster</artifactId>
    <classifier>jboss-ha-legacy-client</classifier>
    <version>5.1.0.GA</version>
    </dependency>
    <dependency>
    <groupId>org.jboss.cluster</groupId>
    <artifactId>jboss-ha-client</artifactId>
    <version>1.1.1.GA</version>
    </dependency>

    <!-- End dependencies for connecting to JMS -->

    </dependencies>

    <build>
    <plugins>
    <plugin>
    <groupId>org.grails</groupId>
    <artifactId>grails-maven-plugin</artifactId>
    <version>1.3.7</version>
    <extensions>true</extensions>
    <executions>
    <execution>
    <goals>
    <goal>init</goal>
    <goal>maven-clean</goal>
    <goal>validate</goal>
    <goal>config-directories</goal>
    <goal>maven-compile</goal>
    <goal>maven-test</goal>
    <goal>maven-war</goal>
    <goal>maven-functional-test</goal>
    </goals>
    </execution>
    </executions>
    </plugin>
    </plugins>
    </build>
    </project>

    资源.groovy:
    import org.codehaus.groovy.grails.commons.ConfigurationHolder
    import org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter
    import org.springframework.jms.listener.DefaultMessageListenerContainer
    import org.springframework.jms.listener.adapter.MessageListenerAdapter
    import org.springframework.jms.support.destination.JndiDestinationResolver
    import org.springframework.jndi.JndiObjectFactoryBean
    import org.springframework.jndi.JndiTemplate

    beans = {

    def config = ConfigurationHolder.config

    jndiTemplate(JndiTemplate) {
    environment = config.myQueue.ctx.toProperties() // flattens a{b{c}} to 'a.b.c'
    }

    jmsFactory(JndiObjectFactoryBean) {
    jndiTemplate = jndiTemplate
    jndiName = config.myQueue.connectionFactory as String
    lookupOnStartup = false // need this?
    proxyInterface = "javax.jms.ConnectionFactory"
    }

    authJmsFactory(UserCredentialsConnectionFactoryAdapter) {
    targetConnectionFactory = jmsFactory
    username = config.app.auth.username as String
    password = config.app.auth.password as String
    }

    destinationResolver(JndiDestinationResolver) {
    jndiTemplate = jndiTemplate
    }

    jmsMessageListener(MessageListenerAdapter, ref("myMessageDrivenService")) {
    defaultListenerMethod = "onEventMessage"
    }

    jmsContainer(DefaultMessageListenerContainer) {
    connectionFactory = authJmsFactory
    destinationResolver = destinationResolver
    destinationName = config.eventQueue.queueName as String
    messageListener = jmsMessageListener
    transactionManager = ref("transactionManager") // grails' txn mgr
    cacheLevel = DefaultMessageListenerContainer.CACHE_CONNECTION
    autoStartup = false // started up in Bootstrap.groovy
    }
    }

    最佳答案

    解决方案是通过配置文件为您的依赖项创建动态范围。

    例子:

    <?xml version="1.0" encoding="utf-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    . . .
    <properties>
    <jms.deps.scope>compile</jms.deps.scope>
    </properties>

    <profile>
    <id>build</id>
    <properties>
    <jms.deps.scope>provided</jms.deps.scope>
    </properties>
    </profile>

    <dependencies>
    <dependency>
    <groupId>whatever</groupId>
    <artifactId>whatever</artifactId>
    <scope>${jms.deps.scope}</scope>
    </dependency>
    </dependencies>

    . . .

    然后,当您的命令行将指定配置文件时:
    mvn clean install war -P build

    希望这可以帮助。

    关于grails - maven下用grails指定 "provided"依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9383138/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com