【问题标题】:Determining whether library class is used from GWT app or regular Java确定是从 GWT 应用程序还是常规 Java 使用库类
【发布时间】:2012-10-04 20:53:02
【问题描述】:

我正在编写几个在多个项目之间共享的库类。其中一些项目是普通的 Java,而其他项目是 GWT 应用程序。对于其中一些类,无论它们需要在 GWT 中还是在 Java 中运行,确切的实现都是不同的(我们不详细说明原因,但正如许多示例之一,Java 中不推荐使用 Date.getMonth,但 Calendar 替换不是' t 在 GWT 中可用)。

有没有办法将代码的某些部分标记为与一个或另一个场景有关?

我研究过在 GWT 中使用延迟绑定和类替换,但这需要使用 GWT.create() 实例化类,这对于普通的 Java 应用程序不可用,因此会导致编译错误。

【问题讨论】:

  • 您或许可以阅读类路径系统属性来找到此信息。
  • @Vulcan:嗯……Java 编译器是否足够聪明,可以根据围绕该检查的复杂 if 语句删除不需要的代码,还是我会失去这个功能?
  • 代码生成可能是一种解决方案
  • @Jean-MichelGarcia:听起来很复杂;)你有一个如何实现的例子吗?

标签: java gwt compilation environment


【解决方案1】:

如果您的代码在 GWT 环境(开发或生产)或 false 其他地方运行,听起来您可以使用返回 true 的静态 GWT.isClient()。您必须在服务器类路径中包含gwt-user.jar。例如,在 JVM 中运行以下代码:

import com.google.gwt.core.shared.GWT;

public class Main {
    public static void main(String[] args) {
        System.out.println(GWT.isClient() ? "Running client-side." 
                : "Running server-side.");
    }
}

将在您的控制台中生成Running server-side.

【讨论】:

  • 这在非 GWT 环境中不可用
  • @Jean-MichelGarcia 反射是必要的。
  • @Jean-MichelGarcia 查看编辑后的答案,亲自尝试并收回反对票。出于某种原因,GWT 类位于 shared 包中。
  • @Boris-Brudnoy,好的,如果你提到 GWT 部门。我在想他是想避免在他的非 GWT 代码中使用 GWT
  • 我试图避免依赖,是的。但这仍然是一个可行的解决方案。我会有一个问题:Java 编译器可以根据 isClient() 函数调用的结果删除代码吗? (不确定编译时评估能走多远)
【解决方案2】:

找到了一个效果很好的解决方案:我的库的 .gwt.xml 文件中的 <super-source> 标记!

基本上,我的库中有以下 EnvironmentFlags 类的两个版本。 Java使用的实际库中的一个位于文件夹“lib”中:

my.library.EnvironmentFlags 如下所示:

package my.library;

public class EnvironmentFlags {
  public static final boolean IS_GWT      = false;
  public static final boolean IS_DEV_MODE = false;
}

然后文件夹“super/my/library”中的文件如下所示:

package my.library;

import com.google.gwt.core.client.GWT;

public class EnvironmentFlags {
  public static final boolean IS_GWT      = true;
  public static final boolean IS_DEV_MODE = !GWT.isProdMode();
}

现在神奇的是:我的库的 .gwt.xml 文件如下所示:

<module>
  <source       path='lib'   />
  <super-source path='super' />
</module>

这导致使用 EnvironmentFlags 类的第一个版本的普通 Java,它只是将两个标志都设置为 false,而 GWT 编译器用从超级源目录加载的第二个版本替换该类的源,这将 GWT 标志设置为 true,并将 DEV_MODE 标志设置为从 GWT 获得的任何值。

现在,在我的代码中,我可以简单地使用以下内容:

if (EnvironmentFlags.IS_GWT) {
  // Do GWT stuff
} else {
  // Do plain-old Java stuff
}

Java 和 GWT 编译器都应该从编译结果中删除相应的无法访问/不需要的代码,即不需要运行时开销。

PS:IS_DEV_MODE 标志实际上与我原来的问题没有任何关系。我只是将它作为免费赠品包含在内,它允许我根据我是在测试还是部署我的 GWT 应用程序让我的代码行为不同(例如,更冗长)。

【讨论】:

  • 如上所述,我会将GWT.isProdMode 替换为GWT.isClient
  • @Jean-MichelGarcia:isClient() 将用于 IS_GWT 标志,我已经处理了真/假常量和类替换。第二个 IS_DEV_MODE 标志实际上与我的原始问题没有任何关系,我只是将其包含在内,因此我也可以让我的代码行为不同(例如,更详细的错误),具体取决于我是处于 GWT 开发模式还是 GWT 生产模式。
猜你喜欢
  • 2011-05-06
  • 2014-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-06
  • 1970-01-01
相关资源
最近更新 更多