如何在使用javax.faces.bean.ViewScoped注解的bean时失败

huangapple go评论55阅读模式
英文:

How to fail when bean annotated with javax.faces.bean.ViewScoped

问题

有没有一种方法可以检测到使用javax.faces.bean.ViewScoped创建的@Named CDI-Bean?我多次遇到过,IDE更喜欢这个注解而不是javax.faces.view.ViewScoped

当发现有一个使用javax.faces.bean.ViewScoped注解的CDI-Bean时,有没有一种好的方法来中止应用程序的启动?

英文:

Is there a way of detecting @Named CDI-Beans which are created with javax.faces.bean.ViewScoped? It happened multiple times to me, that the IDE preferred this annotation to javax.faces.view.ViewScoped.

Is there a good way to just abort the application startup when a javax.faces.bean.ViewScoped annotated CDI-Bean is found?

答案1

得分: 4

是的!只要你有一个bean-discovery-mode="all",你可以使用CDI扩展来实现这一点。

这里是一个为你特定情况量身定制的启动示例:

package com.stackoverflow.q76653269;

import java.util.HashSet;
import java.util.Set;

import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.DeploymentException;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;

public class BadBeansDetector implements Extension {

    <T> void processAnnotatedType(@Observes ProcessAnnotatedType<T> type) {
        Set<Class<?>> badBeans = new HashSet<>();

        if (type.getAnnotatedType().getAnnotation(javax.faces.bean.ViewScoped.class) != null) {
            badBeans.add(type.getAnnotatedType().getJavaClass());
        }
        
        if (!badBeans.isEmpty()) {
            throw new DeploymentException("发现了错误的Bean!" + badBeans);
        }
    }
}

要使其运行,创建一个META-INF/services/javax.enterprise.inject.spi.Extension文本文件,其唯一内容为:

com.stackoverflow.q76653269.BadBeansDetector

对于Maven WAR项目,此META-INF文件夹必须位于src/main/resources中(而不是src/main/webapp)。

如果你的bean-discovery-mode="annotated",那么这将无法工作,但是错误的bean在首次注入时将无法使用,并且在任何你对其进行@Inject时都会阻止部署并引发未满足依赖关系的异常,你也不需要提出这个问题。

当然,另一种选择是升级到JSF 2.3,其中此注解标记为@Deprecated,并重新配置你的构建/编译器以在遇到已弃用的内容时失败。另一种选择是进一步迁移到Faces 4.0,其中已经移除了这个弃用的注解 如何在使用javax.faces.bean.ViewScoped注解的bean时失败

英文:

> Is there a good way to just abort the application startup when a javax.faces.bean.ViewScoped annotated CDI-Bean is found?

Yes! You can use a CDI extension for this as long as you've a bean-discovery-mode=&quot;all&quot;.

Here's a kickoff example tailored for your specific use case:

package com.stackoverflow.q76653269;

import java.util.HashSet;
import java.util.Set;

import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.DeploymentException;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;

public class BadBeansDetector implements Extension {

    &lt;T&gt; void processAnnotatedType(@Observes ProcessAnnotatedType&lt;T&gt; type) {
        Set&lt;Class&lt;?&gt;&gt; badBeans = new HashSet&lt;&gt;();

        if (type.getAnnotatedType().getAnnotation(javax.faces.bean.ViewScoped.class) != null) {
            badBeans.add(type.getAnnotatedType().getJavaClass());
        }
        
        if (!badBeans.isEmpty()) {
            throw new DeploymentException(&quot;Bad beans found! &quot; + badBeans);
        }
    }
}

To get it to run, create a META-INF/services/javax.enterprise.inject.spi.Extension text file with the sole content:

com.stackoverflow.q76653269.BadBeansDetector

In case of a Maven WAR project, this META-INF folder must reside in src/main/resources (and thus not src/main/webapp).

In case you've bean-discovery-mode=&quot;annotated&quot;, then this won't work, but the bad bean would in first place not be injectable and already block deployment with an unsatisfied dependency exception anywhere you @Inject it and you wouldn't need to ask this question.

The alternative is of course to upgrade to JSF 2.3 where this annotation is marked @Deprecated and reconfigure your build/compiler to fail when a deprecated thing is encountered. Yet another alternative is to migrate further to Faces 4.0 where this deprecated annotation is long removed 如何在使用javax.faces.bean.ViewScoped注解的bean时失败

答案2

得分: 4

我认为之前的答案已经不错了,但另一种在编译时捕获此问题的方法是使用Maven Enforcer插件:https://maven.apache.org/enforcer/maven-enforcer-plugin/usage.html

然后使用这个规则扩展来搜索被禁止的类使用:https://github.com/skuzzle/restrict-imports-enforcer-rule

在您的pom.xml中的总体更改将类似于:

...
<build>
 <plugins>
...

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>3.3.0</version>
    <dependencies>
        <dependency>
            <groupId>de.skuzzle.enforcer</groupId>
            <artifactId>restrict-imports-enforcer-rule</artifactId>
            <version>2.3.1</version>
        </dependency>
    </dependencies>
    <executions>
        <execution>
            <id>check-viewscopedjsf-imports</id>
            <phase>process-sources</phase>
            <goals>
                <goal>enforce</goal>
            </goals>
            <configuration>
                <rules>
                    <RestrictImports>
                        <reason>Use CDI managed beans, not deprecated JSF APIs</reason>
                        <bannedImport>javax.faces.bean.**</bannedImport>
                    </RestrictImports>
                </rules>
            </configuration>
        </execution>
    </executions>
  </plugin>
 </plugins>
</build>

这种方法的优点是您可以在编译时捕获错误,而不是在运行时,因此根据您的用例,它可能会节省一些时间。不过,我认为这不会检查第三方库,而BalusC的解决方案会检查。所以,如果这在您的堆栈中是一个大问题,您可能可以同时运行这两个解决方案以获得全面的覆盖。

英文:

I think the previous answer is just fine, but another way to catch this at compile time would be to use the Maven Enforcer plugin: https://maven.apache.org/enforcer/maven-enforcer-plugin/usage.html

Then use this rule extensions that can search for banned class usages: https://github.com/skuzzle/restrict-imports-enforcer-rule

The total change in your pom.xml would be something like:

...
&lt;build&gt;
 &lt;plugins&gt;
...

  &lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-enforcer-plugin&lt;/artifactId&gt;
    &lt;version&gt;3.3.0&lt;/version&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;de.skuzzle.enforcer&lt;/groupId&gt;
            &lt;artifactId&gt;restrict-imports-enforcer-rule&lt;/artifactId&gt;
            &lt;version&gt;2.3.1&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
    &lt;executions&gt;
        &lt;execution&gt;
            &lt;id&gt;check-viewscopedjsf-imports&lt;/id&gt;
            &lt;phase&gt;process-sources&lt;/phase&gt;
            &lt;goals&gt;
                &lt;goal&gt;enforce&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
                &lt;rules&gt;
                    &lt;RestrictImports&gt;
                        &lt;reason&gt;Use CDI managed beans, not deprecated JSF APIs&lt;/reason&gt;
                        &lt;bannedImport&gt;javax.faces.bean.**&lt;/bannedImport&gt;
                    &lt;/RestrictImports&gt;
                &lt;/rules&gt;
            &lt;/configuration&gt;
        &lt;/execution&gt;
    &lt;/executions&gt;
  &lt;/plugin&gt;
 &lt;/plugins&gt;
&lt;/build&gt;

The advantage of this approach is you'll catch the error while compiling, instead of while running, so it may save you a bit of time depending on your use case. I don't think this will check third party libraries however, which BalusC's solution would do. So if this is a big problem in your stack, you could probably run both solutions for full coverage.

huangapple
  • 本文由 发表于 2023年7月10日 19:26:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76653269.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定