正如我们所知,Java 16 带来了新特性,如记录、密封接口和类,以及模式匹配。
今天我想在我的培训项目中使用它们。但是,我遇到了一个问题,也许我不明白什么。
因此,在代表我的 Intellij Idea 项目的给定代码中,情况看起来像:我有包:客户端和订单客户端类是一个密封接口,具有三个实现:Regular、Vip 和 SuperVip:
package com.example.records.domain.client;
public sealed interface Client permits Client.Regular, Client.SuperVip, Client.Vip {
Limit currentLimit();
record Regular() implements Client {
@Override
public Client.Limit currentLimit() {
return Client.Limit.of((short) 10);
}
}
record Vip() implements Client {
@Override
public Client.Limit currentLimit() {
return Client.Limit.of((short) 20);
}
}
record SuperVip() implements Client {
@Override
public Client.Limit currentLimit() {
return Client.Limit.of((short) 100);
}
}
record Limit(short value) {
public Limit {
if (value < 0) throw …Run Code Online (Sandbox Code Playgroud) 有没有办法获得像ConstructorProperties这样的注释,它@Target(CONSTRUCTOR)必须注释 java 16 记录的生成构造函数?例如:
@ConstructorProperties({"id", "filename"})
public record Person(long id, String filename) {}
Run Code Online (Sandbox Code Playgroud)
此 ^ 导致以下错误:
java: annotation type not applicable to this kind of declaration
Run Code Online (Sandbox Code Playgroud) 当我们在 Java 中使用类时,为每个类字段/方法添加 JavaDoc/注释非常简单:
class Product {
//Product unique identifier
private int id;
}
Run Code Online (Sandbox Code Playgroud)
如果我们将这些类迁移到 Java 记录,则不清楚在这种情况下编写注释/JavaDocs 的最佳实践是什么:
record Product(int id, String name, double price) {
}
Run Code Online (Sandbox Code Playgroud)
因为现在所有字段都在一行中声明。
keytool从 OpenJDK16 创建的 PKCS12 密钥库文件无法从 Java 8、9、10 和 11 中读取。这是错误吗?如何创建适用于 Java 8 的 PKCS12 密钥库?
我构建了一个 Maven 项目,该项目生成一个可执行 JAR 文件,该文件必须在从版本 8 到版本 16 的任何 JRE 上运行。该 JAR 文件生成一个 HTTPS 服务器(使用com.sun.net.httpserver.HttpsServer)。
在构建期间,我使用keytool生成密钥对并将其存储在捆绑在 JAR 中的 PKCS12 密钥库中(实际上,我使用的是keytool-maven-plugin):
$ /path/to/jdk16/bin/keytool -genkeypair -keystore /tmp/keystore.p12 -storepass password -storetype PKCS12 -alias https -dname "CN=localhost, OU=My HTTP Server, O=Sentry Software, C=FR" -keypass password -validity 3650 -keyalg RSA -sigalg SHA256withRSA
Run Code Online (Sandbox Code Playgroud)
Java 代码使用这个自动生成的密钥库来启动 HTTPS 服务器:
// initialize the HTTPS …Run Code Online (Sandbox Code Playgroud) 首次启动 Talend Open Studio 时出现错误
java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
at java.base/java.lang.Class.getDeclaredMethod(Class.java:2613)
at org.apache.webbeans.proxy.Unsafe.lambda$unsafeDefineClass$2(Unsafe.java:163)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:312)
at org.apache.webbeans.proxy.Unsafe.unsafeDefineClass(Unsafe.java:160)
at org.apache.webbeans.proxy.Unsafe.defineAndLoadClass(Unsafe.java:126)
at org.apache.webbeans.proxy.AbstractProxyFactory.createProxyClass(AbstractProxyFactory.java:280)
at org.apache.webbeans.proxy.AbstractProxyFactory.createProxyClass(AbstractProxyFactory.java:250)
at org.apache.webbeans.proxy.InterceptorDecoratorProxyFactory.createProxyClass(InterceptorDecoratorProxyFactory.java:216)
at org.apache.webbeans.proxy.InterceptorDecoratorProxyFactory.createProxyClass(InterceptorDecoratorProxyFactory.java:188)
at org.apache.webbeans.portable.AbstractProducer.defineInterceptorStack(AbstractProducer.java:105)
at org.apache.webbeans.config.BeansDeployer.validate(BeansDeployer.java:1183)
at org.apache.webbeans.config.BeansDeployer.validateInjectionPoints(BeansDeployer.java:1104)
at org.apache.webbeans.config.BeansDeployer.deploy(BeansDeployer.java:330)
at org.apache.webbeans.lifecycle.AbstractLifeCycle.bootstrapApplication(AbstractLifeCycle.java:137)
at org.apache.webbeans.lifecycle.AbstractLifeCycle.startApplication(AbstractLifeCycle.java:103)
at org.apache.webbeans.web.lifecycle.WebContainerLifecycle.startApplication(WebContainerLifecycle.java:98)
at org.apache.webbeans.servlet.WebBeansConfigurationListener.doStart(WebBeansConfigurationListener.java:207)
at org.apache.webbeans.servlet.WebBeansConfigurationListener.contextInitialized(WebBeansConfigurationListener.java:85)
at org.apache.meecrowave.openwebbeans.OWBAutoSetup$EagerBootListener.doContextInitialized(OWBAutoSetup.java:84)
at org.apache.meecrowave.openwebbeans.OWBAutoSetup$EagerBootListener.access$100(OWBAutoSetup.java:65)
at org.apache.meecrowave.openwebbeans.OWBAutoSetup.onStartup(OWBAutoSetup.java:61)
at org.apache.meecrowave.Meecrowave.lambda$deployWebapp$9(Meecrowave.java:280)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5135)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
at org.apache.meecrowave.Meecrowave.deployWebapp(Meecrowave.java:420)
at org.apache.meecrowave.Meecrowave.deployClasspath(Meecrowave.java:190)
at org.talend.sdk.component.server.cli.EnhancedCli.run(EnhancedCli.java:52)
at org.talend.sdk.component.studio.ProcessManager$2.run(ProcessManager.java:288)
Run Code Online (Sandbox Code Playgroud)
以管理员和用户身份启动。
尝试使用 Java 16、Java 11 和“OpenJDK(推荐发行版:Zulu)”
我该如何解决这个问题?
我已经尝试使用以下方法从这里发布多个版本:
sudo -i
cd /usr/lib/jvm
wget [release link here]
tar xzf [file name here]
export PATH=$PWD/[dir here]/bin:$PATH
java -version
Run Code Online (Sandbox Code Playgroud)
但在java -version我总是得到:
/usr/lib/jvm/[dir here]/bin/java: cannot execute binary file: Exec format error
Run Code Online (Sandbox Code Playgroud)
这意味着我选择了错误的版本/架构。是否有适用于 Raspberry Pi 的版本,或者是否有其他安装 Java 16 的方法?
Java反射正变得越来越受限:
当使用严重依赖反射的库时,这是一个严重的问题,例如在测试中使用它来模拟对象的PowerMock 。
我创建了这个简单的例子来说明这个问题。这里是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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Powermock</name>
<properties>
<java.version>16</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<parameters>true</parameters>
</configuration>
</plugin>
</plugins>
</build>
</project>
Run Code Online (Sandbox Code Playgroud)
通过这个简单的测试SomeTest.java:
package …Run Code Online (Sandbox Code Playgroud) 目前正致力于从 Java 13 升级到 Java 16,并使用以下更新的依赖项来执行加密/解密的密码库:
===================================
加密库类:
package com.decryption.test;
@NoArgsConstructor
@Service
public class CryptoLib {
protected static final String PROTOCOL_VERSION = "ECv2";
protected final String DEV_ROOT_PUB_KEY = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESXy7kqanQwAM/HBTcV0MVtgQkKLY6UVqP3Z/vdlxiRgFqnc9dZUSD8muUpgeZDD05lM68qoI31mbeX9c8P/9Uw==";
protected static final String MERCHANT_ID_PREFIX = "merchant:";
protected static final String HMAC_SHA256_ALGO = "HmacSha256";
protected static final int HMAC_SHA256_ALGO_SIZE = 256 / 8; // 256 bit key size -> 32 bytes
protected static final String AES_CTR_ALGO = "AES/CTR/NoPadding";
protected static final int AES_CTR_ALGO_SIZE = 256 / 8; …Run Code Online (Sandbox Code Playgroud) 我有一个用于定义方法或字段的注释,如下所示:
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.FIELD})
public @interface NotColumn {
}
Run Code Online (Sandbox Code Playgroud)
我想阻止用户在记录上使用此注释,因为在该上下文中使用此注释没有意义。看来这样做不应该编译,因为我没有指定ElementType.PARAMETER为有效的@Target.
不过,以下编译良好:
public record MyRecord(String customerId,
String companyName,
@NotColumn String description
}
Run Code Online (Sandbox Code Playgroud)
但是这种带有紧凑构造函数的形式无法使用“ java:注释类型不适用于这种声明”进行编译 - 这实际上是我所期望的。
public record MyRecord(String customerId,
String companyName,
@NotColumn String description
public MyRecord {
}
}
Run Code Online (Sandbox Code Playgroud) 在 Java 11 下运行 Eclipse 时,使用google-java-format eclipse 插件效果很好,但在 Java 16+ 上运行时,它会失败并出现以下错误:
完整错误:A save participant caused problems. The save participant 'Code Clean Up' caused an exception: java.lang.IllegalAccessError: class com.google.googlejavaformat.java.JavaInput (in unnamed module @0x99c5646) cannot access class com.sun.tools.javac.parser.Tokens$TokenKind (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.parser to unnamed module @0x99c5646. See the error log for details.
google-java-formatter确实注意到--add-exports,在 JDK 16+ 上运行时,由于 JEP-396(JDK 内部的强封装),您需要在运行格式化程序时设置标志。不清楚的是如何判断--add-exportsEclipse 插件的设置。
添加以下内容eclipse.ini(或在我的情况下SpringToolSuite4.ini)似乎没有帮助(更不用说它感觉不对,因为它不针对该特定插件)。有没有不同的方法来处理/解决这个问题?
-vmargs
-Dosgi.requiredJavaVersion=11
-Dosgi.dataAreaRequiresExplicitInit=true
-Xms256m
-Xmx2048m …Run Code Online (Sandbox Code Playgroud) eclipse eclipse-plugin spring-tool-suite google-java-format java-16
java-16 ×10
java ×8
java-record ×3
annotations ×2
bouncycastle ×1
constructor ×1
cryptography ×1
eclipse ×1
etl ×1
google-pay ×1
java-11 ×1
java-14 ×1
keytool ×1
linux ×1
maven ×1
powermock ×1
powermockito ×1
raspberry-pi ×1
ssl ×1
talend ×1