小编jqn*_*qno的帖子

Scala演员:接受vs反应

首先我要说的是,我有很多Java经验,但最近才对函数式语言感兴趣.最近我开始关注Scala,这似乎是一种非常好的语言.

但是,我一直在阅读Scala 编程中的 Scala的Actor框架,有一点我不明白.在第30.4章中,它表示使用react而不是receive可以重用线程,这对性能有好处,因为线程在JVM中很昂贵.

这是否意味着,只要我记得打电话react而不是receive,我可以开始尽可能多的演员?在发现Scala之前,我一直在和Erlang一起玩,编程Erlang的作者自豪地生成了超过20万个进程,而且不会出汗.我讨厌用Java线程做到这一点.与Erlang(和Java)相比,我在Scala中看到了什么样的限制?

此外,此线程如何在Scala中重用?为简单起见,我们假设我只有一个线程.我开始的所有演员都会在这个帖子中按顺序运行,还是会进行某种任务切换?例如,如果我启动两个互相ping消息的actor,如果它们在同一个线程中启动,我是否会冒死锁?

根据Scala编程,编写演员使用react比使用更困难receive.这听起来似乎有道理,因为react不会回来.然而,本书接着展示了如何react使用循环内部Actor.loop.结果,你得到了

loop {
    react {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

对我来说,这看起来非常相似

while (true) {
    receive {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在本书前面使用过.尽管如此,这本书还是说"在实践中,程序至少需要少数几个receive".那我在这里错过了什么?除了回归之外,receive做什么不能做到react?为什么我关心?

最后,进入我不理解的核心:本书不断提及如何使用react可以丢弃调用堆栈来重用线程.这是如何运作的?为什么有必要丢弃调用堆栈?当函数通过抛出异常(react)而终止时,为什么可以放弃调用堆栈,而不是当它通过返回(receive)终止时?

我的印象是Scala中的Programming一直在掩盖这里的一些关键问题,这是一种耻辱,因为否则它是一本真正优秀的书.

multithreading scala actor

110
推荐指数
4
解决办法
2万
查看次数

Google Code项目的Maven存储库

我正在Google Code上托管一个小型开源项目,并且我被要求将jar提交到可公开访问的Maven存储库.我几乎没有Maven的实际知识.最好的方法是什么?

我可以提交一些中央存储库,还是可以自己托管?当我想发布一个新版本的jar时,我需要做什么?

我一直在谷歌搜索,发现看起来很简单,但似乎有点......与Maven的精神相反,将jar文件提交给SVN :).

此外,还有一种方法可以像Google Code一样跟踪下载次数吗?

编辑

我一直在得到一些答案,其中一些包含有关添加到我的内容的提示pom.xml.多谢你们!但显然我忘记提到一件重要的事情:我的构建脚本是在ANT中,说白了,我打算保持这种方式:).我只是想让Maven用户更容易将我的jar包含在他们的项目中.


我最终采用的解决方案

最后,我确实使用了之前引用的解决方案,我只是将一个Maven repo提交给SVN.我有ANT脚本调用Maven来设置本地仓库,然后调用SVN将其提交给Google Code.对于那些有兴趣:看我的构建脚本在这里,在publish-maven目标.

maven-2 google-code

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

如何在默认情况下指示成员字段是@Nonnull?

我的问题是后续这一块.

在过去的FindBugs版本中,可以使用@DefaultAnnotation(Nonnull.class)@DefaultAnnotationForFields(Nonnull.class)表示应将包中的所有字段视为@Nonnull.在FindBugs的(2.0)的当前版本@DefaultAnnotation@DefaultAnnotationForFields已被弃用,并且我们都应该使用JSR-305来代替.但JSR-305似乎并未涵盖(现已弃用)FindBugs注释所涵盖的所有内容.

javadoc的确实表明了一些替代品:

  • @ParametersAreNonnullByDefault.这(显然)仅适用于参数,而不适用于成员字段.
  • @CheckReturnValue,当应用于类型或包时.同样,这不适用于成员字段.
  • @TypeQualifierDefault.也许这可以做我想要的,但我不明白它是如何工作的,除了一些神秘的javadoc之外,我无法找到任何有关其用法或意图的文档或示例.我认为这将有助于我创建自己的注释,但我能确定所有工具(FindBugs,Eclipse等)都能正确地解释这个新注释(甚至根本不能)吗?

javadoc中没有提供关于如何处理其弃用任何提示.

因此,使用当前版本的FindBugs和/或JSR-305,我应该如何表明特定包中(甚至某个类)中的所有成员字段都应该被视为@Nonnull?它甚至可能吗?

java findbugs jsr305

21
推荐指数
1
解决办法
4284
查看次数

设置多版本 JAR 单元测试

我有一个项目使用了大量反射,还涉及“新”Java 功能,例如记录和密封类。我正在写这样的课程:

public class RecordHelper {
    public static boolean isRecord(Class<?> type) {
        return type.isRecord();
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,这仅适用于 Java 16 及更高版本,因此我尝试设置一个多版本 JAR 文件,其默认实现如下:

public class RecordHelper {
    public static boolean isRecord(Class<?> type) {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经能够使用Baeldung 上的这篇文章使用 Maven 进行设置,并且效果很好。这很好,因为它不依赖于不同版本的单独配置文件,这使我的 pom 文件保持干净。

但现在我需要编写测试。

我希望能够在我想要支持的所有平台上运行测试套件,这意味着 JDK 8 及更高版本的所有平台。(我不介意在运行测试之前在不同的 JDK 上进行编译。)当然,在 JDK 16 及更高版本上,我也想测试与记录相关的东西(以及在 17 及更高版本上,密封类),所以这意味着我必须编译一些记录,这意味着我将不可避免地拥有一些无法在较旧的 JDK 上运行的类文件。

在我看来,拥有一个用于测试的多版本 JAR 文件也是有意义的,其中记录测试被放置在 中的适当位置META-INF/versions,但当然测试通常不会打包在 JAR 中,因此不起作用。

有没有办法让它在单模块 Maven 项目中工作而不需要太多重复?

当然,随着 JDK 版本的上升,它必须“积累”测试类,例如,在 JDK 8 上,我只有“常规”测试类,在 JDK 16 上,我有常规测试类和那些测试类,在java16JDK 17 …

java maven

15
推荐指数
1
解决办法
841
查看次数

更新 Spring Boot Parent 后 PortUnreachableExceptions 垃圾邮件日志

spring-boot-parent版本 2.5.5 升级到 2.6.0 后,我开始看到这些错误消息充斥着日志:

[INFO] [stdout] 2022-01-11 13:40:01.157 WARN 76859 --- [ udp-epoll-2] i.m.s.reactor.netty.channel.FluxReceive : [6d1243de, L:/127.0.0.1:58160 - R:localhost/127.0.0.1:8125] An exception has been observed post termination, use DEBUG level to see the full stack: java.net.PortUnreachableException: readAddress(..) failed: Connection refused

使用DEBUG级别:

[INFO] [stdout] 2022-01-11 13:38:29.733  WARN 76479 --- [    udp-epoll-2] i.m.s.reactor.netty.channel.FluxReceive  : [43aad7ce, L:/127.0.0.1:38108 - R:localhost/127.0.0.1:8125] An exception has been observed post termination
[INFO] [stdout] 
[INFO] [stdout] java.net.PortUnreachableException: readAddress(..) failed: Connection refused
[INFO] [stdout]     at io.micrometer.shaded.io.netty.channel.epoll.EpollDatagramChannel.translateForConnected(EpollDatagramChannel.java:575)
[INFO] [stdout] …
Run Code Online (Sandbox Code Playgroud)

java spring-boot micrometer

10
推荐指数
2
解决办法
9983
查看次数

Log4net输出到我的文档

在我们的C#应用​​程序中,我们将文件写入Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).我们的log4net日志文件也应该去那里,所以我们定义application.conf如下:

<appender name="LogFile" type="log4net.Appender.RollingFileAppender">
  <appendToFile value="true"/>
  <file value="%USERPROFILE%\My Documents\MyApp\log.txt"/>
  ...snip...
</appender>
Run Code Online (Sandbox Code Playgroud)

这是有效的,直到我们在具有非英语Windows的PC上运行.因为那时,SpecialFolder.MyDocuments指向文件夹Mijn Documenten,而日志仍然转到My Documents.随之而来的是混乱,因为现在我们的文件分布在两个地方.

我想将我的日志写入"真正的"我的文档文件夹.我该怎么做呢?

  • 我试图找到一个类似的环境变量%USERPROFILE%,但似乎没有My Documents的存在.
  • 有一个注册表项,用于定义"我的文档"的真实位置,但无法访问application.conf.
  • 我试图以File编程方式覆盖我的appender参数,如下所示:

    public static void ConfigureLogger()
    {
        XmlConfigurator.Configure();
    
        Hierarchy hierarchy = (Hierarchy)log4net.LogManager.GetRepository();
        foreach (var appender in hierarchy.Root.Appenders)
        {
            if (appender is FileAppender)
            {
                var fileAppender = appender as FileAppender;
                var logDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyApp");
                var pathElements = fileAppender.File.Split(Path.DirectorySeparatorChar);
                var logFileName = pathElements.Last();
                var fullLogFilePath = Path.Combine(logDirectory, logFileName); …
    Run Code Online (Sandbox Code Playgroud)

c# log4net

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

使用ScalaTest的Selenium DSL发生奇怪的超时

我正在用ScalaTest的Selenium DSL编写Selenium测试,我遇到了无法解释的超时问题.为了使问题更复杂,它们似乎只是在某些时候发生.

每当我在页面加载或一些Javascript渲染后访问元素时,就会出现问题.它看起来像这样:

click on "editEmployee"
eventually {
  textField(name("firstName")).value = "Steve"
}
Run Code Online (Sandbox Code Playgroud)

我的PatienceConfig配置如下:

override implicit val patienceConfig: PatienceConfig =
    PatienceConfig(timeout = Span(5, Seconds), interval = Span(50, Millis))
Run Code Online (Sandbox Code Playgroud)

测试失败,出现以下错误:

- should not display the old data after an employee was edited *** FAILED ***
  The code passed to eventually never returned normally. Attempted 1 times over 10.023253653000001 seconds.
  Last failure message: WebElement 'firstName' not found.. (EditOwnerTest.scala:24)
Run Code Online (Sandbox Code Playgroud)

有意义的是它没有立即成功,因为click导致某些渲染,并且文本字段可能不会立即可用.但是,尝试找到它不应该花费10秒钟,对吗?

此外,我发现非常有趣的是,最终块只尝试了一次,而且几乎只需要10秒钟.这闻起来像某个地方发生了超时,而且不是我的PatienceConfig,因为它被设置为在5秒后超时.

通过此解决方法,它确实有效:

click on "editEmployee"
eventually {
  find(name("firstName")).value // from ScalaTest's `OptionValues` …
Run Code Online (Sandbox Code Playgroud)

selenium scala scalatest

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

int与long的迭代速度

我有以下两个程序:

long startTime = System.currentTimeMillis();
for (int i = 0; i < N; i++);
long endTime = System.currentTimeMillis();
System.out.println("Elapsed time: " + (endTime - startTime) + " msecs");
Run Code Online (Sandbox Code Playgroud)

long startTime = System.currentTimeMillis();
for (long i = 0; i < N; i++);
long endTime = System.currentTimeMillis();
System.out.println("Elapsed time: " + (endTime - startTime) + " msecs");
Run Code Online (Sandbox Code Playgroud)

注意:唯一的区别是循环变量(intlong)的类型.

当我运行它时,第一个程序始终打印0到16毫秒,无论值是什么N.第二个需要更长的时间.因为N == Integer.MAX_VALUE,它在我的机器上运行大约1800毫秒.运行时间似乎或多或少是线性的N.

那么为什么呢?

我想JIT编译器会优化int循环到死.并且有充分的理由,因为显然它什么都不做.但是为什么它也不是这样做的long呢?

一位同事认为我们可能正在测量JIT编译器在long循环中的工作,但由于运行时似乎是线性的N …

java optimization performance jit

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

使用 Spring Framework 和 Chrome 设置视频流

我们正在编写一个 Spring 服务,它使 HTTP 端点可用,通过它可以流式传输来自 Amazon S3 存储的视频(或音频)文件。基本思想是,您可以在 Google Chrome 地址栏中输入一个 url,该服务将从 S3 中获取文件并进行流式传输,这样用户就可以立即开始观看,而无需等待下载完成,并且用户可以单击视频进度条中的随机位置并立即从该位置开始观看视频。

我理解这在理论上应该有效的方式是 Chrome 开始下载文件。该服务以 HTTP 200 响应并包含一个Accept-Ranges: bytes和一个Content-Length: filesize标头。这filesize是已知的,因为我们可以将其作为元数据从 S3 中查询,而无需获取整个文件。包含这些标头会导致浏览器取消下载,并再次请求带有Range: bytes=0-whatever标头的文件(whateverChrome 决定的块大小)。然后服务以 HTTP 206(部分内容)和请求的字节范围进行响应,我们可以轻松确定,因为 S3 支持相同的范围协议。Chrome 然后从服务请求连续的块,直到流结束。

在 Spring 方面,我们将数据发送到 a ResponseEntity<InputStreamResource>(根据这个 SO answer)。

然而,我们在实践中观察到,虽然 Chrome 在几百个字节后取消了它的第一个请求。但是,它会发送带有Range: bytes=0-标头的第二个请求,从而有效地请求整个文件。服务器以 HTTP 206 响应。结果,它只下载了几百字节的视频,并且视频显然没有开始播放。

有趣的是,在 Firefox 中一切正常。不幸的是,我们的应用程序需要支持 Chrome。我们是否遗漏了协议的某些部分?

spring http video-streaming spring-boot

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

CDI具有非托管对象

假设我有两个类,首先是一个没有任何属性,字段或注释的类:

public class B {}
Run Code Online (Sandbox Code Playgroud)

和一个注入B的类,如下所示:

public class A {
    @Inject
    private B b;

    public B getB() {
        return b;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在A级在我们使用之前是没用的,所以有两种选择:

  • @Inject它
  • 使用可靠的"新A()"手动构造它

如果A被注入,CDI管理它并且足够注入B,其具有隐含的@Dependent范围.很酷,就是我想要的.

但是,如果我手动构造A(假设在工厂或构建器中),CDI完全忽略我的对象并且不会注入类型B的对象.

示例我在谈论它什么时候不起作用,这里对象a将始终保持为null:

public class Builder {
    @Inject
    private A a;

    public static Builder ofTypeSomething() {
        // do some magic here
        return new Builder();
    }

    private Builder() {
        // and some more here
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用?

A类是一个有效的托管bean,并且有一个有效的范围,就像B类一样.即使我将@Producer添加到静态方法,它也不会改变任何东西(这很好,因为静态方法的想法是调用它,不要在任何地方注入Builder).

java java-ee cdi

7
推荐指数
1
解决办法
5355
查看次数