小编Rom*_*kiy的帖子

Java 9 + maven + junit:测试代码是否需要自己的module-info.java以及放置它的位置?

假设我有一个使用Maven 3和junit的Java项目.有src/main/javasrc/test/java目录分别包含主要来源和测试来源(一切都是标准的).

现在我想将项目迁移到Java 9. src/main/java内容代表Java 9模块; 有com/acme/project/module-info.java看大约是这样的:

module com.acme.project {
    require module1;
    require module2;
    ...
}
Run Code Online (Sandbox Code Playgroud)

如果测试代码需要module-info.java自己怎么办?例如,添加对某些模块的依赖性,该模块仅用于测试,而不是生产代码.在这种情况下,我必须把module-info.javasrc/test/java/com/acme/project/给模块不同的名称.这样Maven似乎将主要源和测试源视为不同的模块,因此我必须将包从主模块导出到测试模块,并且需要测试模块中的包,如下所示:

主模块(in src/main/java/com/acme/project):

module prod.module {
    exports com.acme.project to test.module;
}
Run Code Online (Sandbox Code Playgroud)

测试模块(in src/test/java/com/acme/project):

module test.module {
    requires junit;
    requires prod.module;
}
Run Code Online (Sandbox Code Playgroud)

这产生了

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:testCompile (default-testCompile) on project test-java9-modules-junit: Compilation failure: Compilation failure:
[ERROR] /home/rpuch/git/my/test-java9-modules-junit/src/test/java/com/acme/project/GreeterTest.java:[1,1] package exists in another module: prod.module
Run Code Online (Sandbox Code Playgroud)

因为一个包在两个模块中定义.所以现在我必须在主模块和测试模块中有不同的项目,这是不方便的.

我觉得我走错了道路,一切都开始看起来非常难看.如何module-info.java在测试代​​码中拥有自己的代码,或者如何在没有测试代码的情况下实现相同的效果(require …

java junit maven java-9 java-module

32
推荐指数
2
解决办法
7404
查看次数

如何在Java 9中运行时访问javax.annotation.Resource

我有一个测试:

public class ResourceTest {
    @Test
    public void test() throws ClassNotFoundException {
        Class.forName("javax.annotation.Resource");
    }
}
Run Code Online (Sandbox Code Playgroud)

它试图访问javax.annotation.Resource.在java 8中它可以工作,但是在java 9中(我使用的是Oracle JDK 9)它失败了ClassNotFoundException.正如本文所解释的那样:@Resource注入在JDK9下停止工作,javax.annotation.ResourceJDK在Java 9中默认不可用.

我正在尝试使用模块描述符访问它:

module test {
    requires java.xml.ws.annotation;
    requires junit;
}
Run Code Online (Sandbox Code Playgroud)

在这里,我特意请求访问java.xml.ws.annotation模块(包含javax.annotation.Resource).但测试仍然失败.

当我删除该requires子句并添加包含的依赖项(作为库)时javax.annotations.Resource,它可以工作:

    <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>javax.annotation-api</artifactId>
        <version>1.3.1</version>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

当我同时添加它们(Maven依赖于pom.xmlrequires java.xml.ws.annotation)时,IDEA中的编译失败,并显示以下消息:

the unnamed module reads package javax.annotation from both java.xml.ws.annotation and java.annotation
Run Code Online (Sandbox Code Playgroud)

但Maven构建仍然成功!

如果我java.xml.ws.annotation通过命令行添加模块,它可以工作(没有Maven依赖和with requires子句):

mvn clean test …
Run Code Online (Sandbox Code Playgroud)

java java-9 java-module

20
推荐指数
1
解决办法
2万
查看次数

Spring:@Resource注入在JDK9下停止工作

在我的@Configuration课堂上,我有如下的家属:

@Configuration
public class MyConfig {
    @Resource(name = "firstDataSource")
    private DataSource firstDataSource;

    // more code
}
Run Code Online (Sandbox Code Playgroud)

在Oracle JDK 8:firstDataSource字段中工作的依赖项注入已成功注入非null值.

现在我尝试在JDK 9中运行应用程序(没有修改).结果是@Resource不再触发依赖注入:使用此注释注释的所有内容仍然存在null.

什么可能是@Resource停止工作的原因?

在项目中使用Spring 4.0.9.

这是一个测试项目,展示了这个问题:https://github.com/rpuch/test-spring-injection-jdk9

它包含一个测试:MainTest我从IDE运行.当我使用JDK 8时,它会输出

??? 29, 2017 10:45:13 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5f8ed237: startup date [Fri Sep 29 22:45:13 SAMT 2017]; root of context hierarchy
OK
Run Code Online (Sandbox Code Playgroud)

但是在JDK 9下,它会在启动期间抛出异常,这是由以下原因造成的:

Caused by: java.lang.IllegalStateException: bean1 is not injected
    at Bean2.<init>(Bean2.java:7)
    at Config2.bean2(Config2.java:16)
Run Code Online (Sandbox Code Playgroud)

当没有注入依赖时会发生这种情况.

java spring dependency-injection java-9

9
推荐指数
2
解决办法
2124
查看次数

Serializable.class 如何不能从 Class.class 分配?

org.springframework.core.SerializableTypeWrapper(5.2.3版)中,第112行有如下代码:

    if (GraalDetector.inImageCode() || !Serializable.class.isAssignableFrom(Class.class)) {
        // Let's skip any wrapping attempts if types are generally not serializable in
        // the current runtime environment (even java.lang.Class itself, e.g. on Graal)
        return providedType;
    }
Run Code Online (Sandbox Code Playgroud)

我对第二个检查 ( !Serializable.class.isAssignableFrom(Class.class))很好奇:它是否可以评估为true(即,Serialazable.class不可从 分配Class.class)?

这是Class#isAssignableFrom()javadoc 所说的:

确定此 Class 对象表示的类或接口是否与指定的 Class 参数表示的类或接口相同,或者是其超类或超接口。

查看 的代码Class,我看到以下内容:

public final class Class<T> implements java.io.Serializable
Run Code Online (Sandbox Code Playgroud)

Serializable的超级接口也是如此,Class并且应该始终可以从Class. 但是 Spring 代码中的检查表明有时并非如此。

怎么来的?在什么情况下会发生这种情况,为什么它们不违反 Java 语言规范?

java spring graalvm graalvm-native-image

9
推荐指数
1
解决办法
131
查看次数

构建本机映像时,如何调试“映像堆中不允许...的实例”?

我有一个使用 Micronaut 2.0.0 实现 RESTful API 的小 Java 应用程序。在幕后,它使用 Redisson 3.13.1 转到 Redis。Redisson 反过来使用 Netty (4.1.49)。

该应用程序在“经典”java(在 HotSpot 上,Java 8 和 11)中运行良好。

我正在尝试使用 GraalVM 从此应用程序构建本机映像。

命令大概是这样的:

native-image --no-server --no-fallback -H:+TraceClassInitialization -H:+PrintClassInitialization --report-unsupported-elements-at-runtime --initialize-at-build-time=reactor.core.publisher.Flux,reactor.core.publisher.Mono -H:ConfigurationFileDirectories=target/config -cp target/app-1.0.0-SNAPSHOT.jar com.app.AppApplication target/app
Run Code Online (Sandbox Code Playgroud)

这是我得到的:

Error: Unsupported features in 4 methods
Detailed message:
Error: No instances of java.net.Inet4Address are allowed in the image heap as this class should be initialized at image runtime. Object has been initialized without the native-image initialization instrumentation and the …
Run Code Online (Sandbox Code Playgroud)

java netty graalvm-native-image

8
推荐指数
1
解决办法
797
查看次数

如何在不转换为密钥库的情况下从PEM证书和密钥构建SSLSocketFactory?

我得到了一个自签名的客户端证书工具包,该工具包将用于通过HTTPS访问服务器。该套件包含以下PEM文件:

  1. client.crt(客户端证书)
  2. client.key(客户端私钥)
  3. ca.crt(CA证书)

解决任务的一种方法是生成Java密钥库:

  1. 使用openssl将客户端证书和密钥转换为PKCS12密钥库
  2. 使用keytool将CA证书导入商店

...然后使用类似以下的代码来构建SSLSocketFactory实例:

InputStream stream = new ByteArrayInputStream(pksData);         
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(stream, password);

KeyManagerFactory kmf = KeyManagerFactory.getInstance(
    KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, password.toCharArray());
KeyManager[] keyManagers = kmf.getKeyManagers();

TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
    TrustManagerFactory.getDefaultAlgorithm());
tmfactory.init(keyStore);
TrustManager[] trustManagers = tmfactory.getTrustManagers();

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null);
sslSocketFactory = sslContext.getSocketFactory();
Run Code Online (Sandbox Code Playgroud)

...以后用于初始化http库。

因此,我们获得了一个KeyStore,然后在其帮助下初始化KeyManagers和TrustManagers,最后我们用它们构建SSLSocketFactory实例。

问题是:是否有一种方法可以避免创建密钥库文件,并以某种方式从PublicKey和Certificate实例开始构建SSLSocketFactory(例如,可以使用bouncycastle的PemReader从PEM文件中获取)?

java ssl keystore pem sslsocketfactory

6
推荐指数
2
解决办法
5241
查看次数

是否可以避免使用xalan TransformerFactory?

我有以下代码:

final TransformerFactory factory = TransformerFactory.newInstance();

factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
Run Code Online (Sandbox Code Playgroud)

第二行在带有默认值的现代JDK(我尝试过1.8)中运行良好TransformerFactory。但是,当我xalan向类路径添加(最新的版本2.7.2)时,在第二行得到以下内容:

Exception in thread "main" java.lang.IllegalArgumentException: Not supported: http://javax.xml.XMLConstants/property/accessExternalDTD
    at org.apache.xalan.processor.TransformerFactoryImpl.setAttribute(TransformerFactoryImpl.java:571)
    at Main.main(Main.java:11)
Run Code Online (Sandbox Code Playgroud)

我猜这是因为xalan's TransformerFactory不支持此属性。Xalan的实现通过以下ServiceLoader机制获得:services/javax.xml.transform.TransfomerFactory在xalan jar中指定。

可以TransformerFactory使用javax.xml.transform.TransformerFactory系统属性或$JRE/lib/jaxp.properties文件覆盖实现,也可以直接在代码中传递类名称。但是要做到这一点,我必须提供一个具体的类名。现在是com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl,但是在系统属性中对其进行硬编码有点吓人,因为在JDK升级中,它们可以轻松更改类名,而我们只会遇到运行时错误。

有什么方法可以指示TransformerFactory.newInstance()忽略Xalan提供的实现吗?或告诉它“仅使用系统默认值”。

PS我不能仅仅xalan从类路径中删除,因为我们使用的许多其他库都依赖于它。

java xml xalan

6
推荐指数
1
解决办法
1945
查看次数

KeyFactory是线程安全的吗?

有一个服务类需要PublicKey从X.509编码的公钥表示形式生成实例。此类的一个实例将服务多个线程。这样做是正确的吗?

public class MyService {
    private final KeyFactory rsaKeyFactory;

    public MyService() throws NoSuchAlgorithmException {
        rsaKeyFactory = KeyFactory.getInstance("RSA");
    }

    public PublicKey generatePublicKey(byte[] publicKeyBytes) throws GeneralSecurityException {
        return rsaKeyFactory.generatePublic(new X509EncodedKeySpec(publicKeyBytes));
    }
}
Run Code Online (Sandbox Code Playgroud)

KeyFactory这里使用的实例是线程安全的吗?generatePublicKey()方法可以由不同的线程同时调用。

Javadocs似乎没有提到线程安全性。

java multithreading public-key-encryption

5
推荐指数
1
解决办法
839
查看次数

Spring Security 默认使用 AuthenticationProvider 和 UserDetailsS​​ervice

如果我没有理解错的话,AuthenticationProvider用于UserDetailsService检索用户的属性以验证Authentication对象。

问题是在下一个代码中没有配置 aAuthenticationProvider和 a UserDetailsService

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().withUser("user").password("pass").roles("ADMIN").and().withUser("user1")
            .password("pass").roles("USER");
}
Run Code Online (Sandbox Code Playgroud)

但认证服务已经设置。

我的问题是,是否有一个实现AuthenticationProvider和另一个实现UserDetailsService被添加到内部的 spring 上下文中?在这种情况下,使用的实现是什么(在内存身份验证的情况下)。

*.withUser("user").password("pass").roles("ADMIN")*配置部分是否代表UserDetailsService实现?

java spring-security

5
推荐指数
1
解决办法
3753
查看次数

POST 响应缓存在 nginx 中不起作用

我的任务是使用nginx实现微缓存策略,即缓存一些POST端点的响应几秒钟。

http部分nginx.conf我有以下内容:

proxy_cache_path /tmp/cache keys_zone=cache:10m levels=1:2 inactive=600s max_size=100m;
Run Code Online (Sandbox Code Playgroud)

然后我locationserver

    location /my-url/ {
      root dir;
      client_max_body_size 50k;
      proxy_cache cache;
      proxy_cache_valid 10s;
      proxy_cache_methods POST;
      proxy_cache_key "$request_uri|$request_body";
      proxy_ignore_headers Vary;

      add_header X-Cached $upstream_cache_status;

      proxy_pass http://my-upstream;
    }
Run Code Online (Sandbox Code Playgroud)

该应用程序位于输出处,如果我理解正确的my-upstreamCache-Control: max-age=10,应该使响应可缓存。

但是当我在短时间内(不到10秒)使用curl发出重复请求时

curl -v --data "a=b&c=d" https://my-host/my-url/1573
Run Code Online (Sandbox Code Playgroud)

它们全部到达后端(根据后端日志)。还有,X-Cached总是MISS

请求和响应如下:

> POST /my-url/1573 HTTP/1.1
> Host: my-host
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Length: 113
> Content-Type: application/x-www-form-urlencoded
> 
* upload …
Run Code Online (Sandbox Code Playgroud)

caching nginx http-post nginx-location nginx-cache

5
推荐指数
1
解决办法
2561
查看次数