自 Java 9 以来 Java 日期和时间 API 发生了变化。 LocalDateTime 现在具有微秒精度。
Java 9 具有 java.time.Clock 的全新实现,能够以比毫秒(十进制小数的三位数字)更精细的分辨率捕获当前时刻。
我们从后端服务中获得以微秒为单位的时间。
System.currentTimeMillis > 1565245051795 > 2019-08-08T06:17:31.795
Service.getTime > 1565245051795306 > 2019-08-08T06:17:31.795306
Run Code Online (Sandbox Code Playgroud)
为了构造在我们的应用程序中使用的 LocalDateTime,我们执行
long timeMicros = service.getTime();
long timeMillis = timeMicros / 1000;
LocalDateTime ldt = Instant.ofEpochMilli(timeMillis).atZone(ZoneId.systemDefault()).toLocalDateTime();
Run Code Online (Sandbox Code Playgroud)
为了查询服务,我们再次需要时间微秒,然后我们做
long timeMillis = dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
long timeMicros = timeMillis * 1000;
Run Code Online (Sandbox Code Playgroud)
问题是我们没有取回时间微秒的精度。
是否可以创建具有微秒精度的 Instant ?
我们现在使用的是 Java 11。当我们的一个 JUnit 测试由于增加的微秒精度而失败时,我注意到了这一变化。
对于 JUnit 测试,我找到了一个解决方法:
private static final LocalDateTime START = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
Run Code Online (Sandbox Code Playgroud)
我不确定这是一种解决方法还是实际的解决方案,但添加时间戳的最后三微秒数字似乎有效。
System.currentTimeMillis > 1565245051795 > 2019-08-08T06:17:31.795
Service.getTime > …Run Code Online (Sandbox Code Playgroud) 我正在学习java.net.http api,尝试下载已下载的字节范围的文件。为此,range可以使用标头(假设服务器支持此类功能)。
使用org.apache.http.client.methods.HttpGet我可以做到这一点:
HttpGet httpGet= new HttpGet("http://exampleURL.com/aFile");
if (myFile.length() > 0) {
httpGet.addHeader("Range", "bytes=" + myFile.length() + "-"+totalBytes));
}
httpGet.addHeader("xxxx", "yyyy");//ok
Run Code Online (Sandbox Code Playgroud)
现在使用 HttpRequest 我无法动态添加新标头,我必须创建一个新的整个 HttpRequest:
HttpRequest request = null;
if (myFile.length() > 0) {
request = HttpRequest.newBuilder()
.uri(URI.create("http://exampleURL.com/aFile"))
.header("Range","bytes="+myFile.length() +"-"+ totalBytes)
.build();
}else{
request = HttpRequest.newBuilder()
.uri(URI.create("http://exampleURL.com/aFile"))
.build();
}
request.header("xxxx","yyyyy")//Can't do this anymore
Run Code Online (Sandbox Code Playgroud)
我有办法动态添加它们吗?
我看到文档说:
HttpRequest 构建后是不可变的,并且可以多次发送。
但是不可变有什么意义呢?如果我出于任何原因需要修改标题怎么办?
参考:
每当打开新连接时,Netty 都会实例化一组请求处理程序类。这对于像 websocket 这样的连接将在 websocket 的生命周期内保持打开状态似乎很好。
当使用 Netty 作为每秒可以接收数千个请求的 HTTP 服务器时,这似乎是垃圾收集的负担。每个请求都会实例化几个类(在我的例子中是 10 个处理程序类),然后在几毫秒后垃圾收集它们。
在具有中等负荷〜1000请求/秒的HTTP服务器,这将是10000类实例化和垃圾收集每一秒。
似乎我们可以简单地 看到下面的答案创建可共享的处理程序,使用ChannelHandler.Sharable. 他们只需要是线程安全的。
但是,我看到打包在库中的所有非常基本的 HTTP 处理程序都不可共享,例如HttpServerCodec和HttpObjectAggregator。此外,没有一个HTTP 处理程序示例是可共享的。99% 的示例代码和教程似乎都不会打扰它。Norman Maurer 的书(Netty 的作者)中只有一句话说明了使用共享处理程序的原因:
为什么要共享一个通道处理程序?
在多个 ChannelPipelines 中安装单个 ChannelHandler 的一个常见原因是收集多个 Channel 的统计信息。
没有提到任何地方的 GC 负载问题。
换句话说,它的设计目的远不止我每秒 1000 个中等的请求。
是否有什么我错过了使 GC 负载不成问题的东西?
或者,我应该尝试实现自己的Sharable处理程序,其具有类似的功能来解码、编码和写入 HTTP 请求和响应吗?
我正在使用 Java 11 和 Maven 3.6.1 构建我的第一个模块化应用程序。我的 IDE 是 IntellijIDEA 2019.1.3。我添加了一个模块“app”并添加了module-info.java,但我很困惑,因为即使我将 spring 依赖项添加到应用程序模块中,我的应用程序仍在工作,并且我没有打开我的模块或模块中的某些包进行反射。
我添加module-info.java了我的 IDE 功能,它迫使我添加requires语句。到现在为止还挺好。但是为什么它可以在不打开模块进行反射的情况下工作?这是 Java 11 或我的 IDE 版本中的一些新功能吗?难道我做错了什么?
我的module-info.java:
module app {
requires spring.web;
requires spring.webmvc;
requires javax.servlet.api;
requires spring.context;
}
Run Code Online (Sandbox Code Playgroud)
我试图在 SO 和 JetBrains 上找到答案,但我失败了。
我正在看这个人 ( https://youtu.be/hxsCYxZ1gXU?t=2238 ) 使用 spring 模块,他的 IDE 要求他打开模块进行反射。我下载了他的项目并删除了opens语句,它仍然在我的 IDE 中编译。
还有一个问题:如何使用 IDE 检查模块路径?我怎样才能看到有哪些模块以及我的类路径上有什么(现在应该什么都没有)?
编辑:我刚刚意识到我的 IDE 打印Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED日志。我想这就是原因,但我找不到这个 arg 的来源。我在正确的道路上吗?
编辑号 2:在控制台日志中,命令行参数是:
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.io=ALL-UNNAMED
-Djava.util.logging.config.file=C:\Users\Nedim\.IntelliJIdea2019.2\system\tomcat\Unnamed_ems\conf\logging.properties
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djdk.module.showModuleResolution=true …Run Code Online (Sandbox Code Playgroud) 我们正在使用 jaxb 的项目从 Java 8 迁移到 11。由于它已从 JDK 中删除,因此必须单独包含,这是我通过 gradle 配置完成的:
compile("javax.xml.bind:jaxb-api:2.2.11")
compile("com.sun.xml.bind:jaxb-core:2.2.11")
compile("com.sun.xml.bind:jaxb-impl:2.2.11")
Run Code Online (Sandbox Code Playgroud)
我能够运行该项目,但是 compileJava gradle 作业会引发错误:
Errors occurred while build effective model from C:\Users\.\.gradle\caches\modules-2\files-2.1\com.sun.xml.bind\jaxb-core\2.2.11\db0f76866c6b1e50084e03ee8cf9ce6b19becdb3\jaxb-core-2.2.11.pom:
'dependencyManagement.dependencies.dependency.systemPath' for com.sun:tools:jar must specify an absolute path but is ${tools.jar} in com.sun.xml.bind:jaxb-core:2.2.11
Errors occurred while build effective model from C:\Users\.\.gradle\caches\modules-2\files-2.1\com.sun.xml.bind\jaxb-impl\2.2.11\2d4b554997fd01d1a2233b1529b22fc9ecc0cf5c\jaxb-impl-2.2.11.pom:
'dependencyManagement.dependencies.dependency.systemPath' for com.sun:tools:jar must specify an absolute path but is ${tools.jar} in com.sun.xml.bind:jaxb-impl:2.2.11
Run Code Online (Sandbox Code Playgroud)
作业完成并创建了一个 jar,但是在生产服务器上运行时,它会因以下错误而停止:
java.lang.NoClassDefFoundError: javax/xml/bind/Unmarshaller$Listener
Run Code Online (Sandbox Code Playgroud)
我正在使用 Spring Boot v1.5.6 和 gradle 4.8.1
我们有一个代码可以生成运行 Java 8 的自签名证书(该 api 已在 Java 9 中删除)。从 JDK 9 开始,似乎会有一个用于生成自签名证书的新 API:https : //bugs.java.com/bugdatabase/view_bug.do?bug_id= JDK- 8165481
有没有做同样的例子:
class Foo{
public Foo(){
CertAndKeyGen keyGen = new CertAndKeyGen("RSA", "SHA256withRSA", null);
keyGen.generate(2048);
rootPrivateKey = keyGen.getPrivateKey();
rootCertificate = keyGen.getSelfCertificate(new X500Name("CN=FooBar"), (long) 24 * 60 * 60);
CertAndKeyGen subKeyGen =new CertAndKeyGen("RSA","SHA256withRSA",null);
subKeyGen.generate(2048);
subPrivateKey = subKeyGen.getPrivateKey();
subCertificate = subKeyGen.getSelfCertificate(new X500Name("CN=FizzBuzz"), (long) 24 * 60 * 60);
rootCertificate = signCertificate(rootCertificate, rootCertificate, rootPrivateKey);
subCertificate = signCertificate(subCertificate, rootCertificate, rootPrivateKey);
X509Certificate[] certChain = new X509Certificate[]{subCertificate,rootCertificate};
KeyStore store = …Run Code Online (Sandbox Code Playgroud) 我正在将我的项目从 java 8 升级到 java 11。我能够使用 java11、spring 5 依赖项构建和部署它,但是当我将 module-info.java 添加到我的项目中时,我在构建时遇到以下错误:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project infrastructure: Execution default-compile of goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile failed.: NullPointerException -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project infrastructure: Execution default-compile of goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile failed.
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956) …Run Code Online (Sandbox Code Playgroud) 我的多 jar 应用程序在 Java 11 中运行并显示与 Log4j2 相关的警告:
警告:不支持 sun.reflect.Reflection.getCallerClass。这会影响性能。
它没有崩溃,但很困扰我,因为运营团队(AppDynamics 监视器)向我询问了它。我读到我需要在清单中使用“Multi-Release:true”条目,但我不知道如何告诉 Maven Assembly Plugin 添加它。
我没有在 pom.xml 中使用任何其他插件。我应该使用Maven Shade Plugin吗?
无论如何,这是我的 pom.xml 的 Maven Assembly Plugin 部分。
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
我包含的库(我也写过)使用 Log4j 2 作为依赖项,如下所示:
<!-- Log4j 2 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.12.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
我怎样才能摆脱这个警告?
我使用 Java 11 (Beta) 运行时创建了一个新的 Cloud Functions 函数来处理我的静态站点的 HTML 表单提交。这是一个简单的 3 字段表单(姓名、电子邮件、消息)。不涉及文件上传。该函数主要做两件事:
注意:它还会验证 recaptcha,但我已将其禁用以进行测试。
在我的本地机器(基本型号 2019 Macbook Pro 13")上运行该功能大约需要 3 秒。我在东南亚。部署到 Google Cloud us-central1 的相同功能大约需要 25 秒(慢 8 倍) . 我有几乎相同的代码在生产中作为 Servlet on GAE Java 8 运行时的一部分也在美国中部地区运行了几年。大约需要 2-3 秒,包括 recaptcha 验证和发送电子邮件。我正在尝试将其移植到 Cloud Function,但即使没有 recaptcha 验证,Cloud Function 的性能也会降低约 10 倍。
相比之下,Cloud Function 在 256MB / 400GHz 实例上运行,而我的 GAE Java 8 运行时在 F1 (128MB / 600GHz) 实例上运行。该函数仅使用大约 75MB 的内存。该函数被配置为接受未经身份验证的请求。
我注意到,即使是基本的字符串连接,如:String c = a + b; …
我安装了 Java 11。当我运行命令时java <filename.java>,为了编译和运行代码,它编译并运行程序,在 CMD 中显示输出,但它不生成任何.class文件。
你能向我解释为什么它不生成.class文件吗?
java-11 ×10
java ×8
maven ×2
build.gradle ×1
gradle ×1
http-headers ×1
httprequest ×1
java-9 ×1
java-time ×1
javac ×1
jaxb ×1
log4j2 ×1
module-info ×1
netty ×1
reflection ×1
spring ×1