What is Hackers' Pub?

Hackers' Pub is a place for software engineers to share their knowledge and experience with each other. It's also an ActivityPub-enabled social network, so you can follow your favorite hackers in the fediverse and get their latest posts in your feed.

パラノイアなのでランダムなSSHサーバに対して手元の鍵を全て試行するのが気持ち悪くて、これに加えて`Host *\nIdentityFile /dev/null`と書くことでフォールバックする前に速やかに失敗するようにしている(?)

0
0

まあ個人の秘密鍵を1個持っておいて、接続先のサーバには、アクセスする人の公開鍵を登録して回ると言うのが正しい使い方なのかもしれないけど。

.ssh/configで、鍵ファイルを指定する方法はあるけど、agentのどの鍵を使うか指定できないのかな。sshで特定のサーバに接続するときに「Too many authentication failures」で接続エラーが発生している。agentに登録されている鍵を順番に試すから、鍵を登録しすぎていたら発生するという書き込みを見かけた。

0
0
0
0
0
0
0
1
0
0
0

🎁これは広く読まれてほしいな〜と思ったので有料記事プレゼント使う🎁3月21日 9:50まで全文お読みいただけます

地下鉄サリン事件30年 教育者になった江川紹子さんが考えるカルト:朝日新聞 digital.asahi.com/articles/AST

 「自分たちが絶対的に正しいという『無謬(むびゅう)性』を信じ、思うようにいかないことがあると、自分たちは被害者だと主張する。敵がすぐに見えなければ、陰謀論に走る。カルト団体の特徴だと思っていたものが、社会全体に見られるようになりました」

0
0
0
0

「ところが、壮絶な体験を経て戻ったウクライナ社会の反応は、決して温かいものではなかった。「自分たちが従軍していないという負い目があるのか、帰還兵を『人を殺す訓練をした存在』として恐れているのか。怪物のような存在として見られることもある」

求人に応募して軍歴を告げると、採用が遠のいた経験があるという。「帰還兵は特殊な経験をしてはいるが、同じ市民なのに」。今ではあえて聞かれない限りは、軍務経験を明かさないようにしていると漏らす」

「ウクライナ侵攻3年:「怪物のような存在に見られて」 軍務経験明かせぬ社会の冷たさとは | 毎日新聞」
mainichi.jp/articles/20250320/

「社会にも注文をつけた。「多くの親たちは、脚がない人や義足を使っている人に子供が反応しないよう、しつけている。だが、社会は負傷した帰還兵たちを隠し続けられない。子供には『彼らは祖国を守るために脚を失ったんだ』と説明してほしい」と訴えた」

「ウクライナ侵攻3年:障害負った帰還兵を阻むソ連の「負の遺産」 米の経験共有の動きも | 毎日新聞」
mainichi.jp/articles/20250320/

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

voicettank.org/20250319-2/
【美國總統的行政命令所向無敵?】

『雖然《華盛頓郵報》證實已經有超過八十起訴訟挑戰川普的行政命令,然而當中已有六項被擋下。』

『當行政命令牴觸法律或憲法時,有三種解決方案:

第一、由國會再立新法推翻總統已經發布的行政命令,但這需要總統簽署,或是在總統否決後由國會以三分之二多數票推翻否決。

第二、若行政命令違反憲法或聯邦法律,聯邦法院可以宣告無效。

第三、任何未經國會通過的行政命令,都可以由以後的總統透過新的行政命令加以廢除或修改。』

0
0
0
0

Park Hyunwoo shared the below article:

Revisiting Java's Checked Exceptions: An Underappreciated Type Safety Feature

洪 民憙 (Hong Minhee) @hongminhee@hackers.pub

Despite their bad reputation in the Java community, checked exceptions provide superior type safety comparable to Rust's Result<T, E> or Haskell's Either a b—we've been dismissing one of Java's best features all along.

Introduction

Few features in Java have been as consistently criticized as checked exceptions. Modern Java libraries and frameworks often go to great lengths to avoid them. Newer JVM languages like Kotlin have abandoned them entirely. Many experienced Java developers consider them a design mistake.

But what if this conventional wisdom is wrong? What if checked exceptions represent one of Java's most forward-thinking features?

In this post, I'll argue that Java's checked exceptions were ahead of their time, offering many of the same type safety benefits that are now celebrated in languages like Rust and Haskell. Rather than abandoning this feature, we should consider how to improve it to work better with modern Java's features.

Understanding Java's Exception Handling Model

To set the stage, let's review how Java's exception system works:

  • Unchecked exceptions (subclasses of RuntimeException or Error): These don't need to be declared or caught. They typically represent programming errors (NullPointerException, IndexOutOfBoundsException) or unrecoverable conditions (OutOfMemoryError).

  • Checked exceptions (subclasses of Exception but not RuntimeException): These must either be caught with try/catch blocks or declared in the method signature with throws. They represent recoverable conditions that are outside the normal flow of execution (IOException, SQLException).

Here's how this works in practice:

// Checked exception - compiler forces you to handle or declare it
public void readFile(String path) throws IOException {
    Files.readAllLines(Path.of(path));
}

// Unchecked exception - no compiler enforcement
public void processArray(int[] array) {
    int value = array[array.length + 1]; // May throw ArrayIndexOutOfBoundsException
}

The Type Safety Argument for Checked Exceptions

At their core, checked exceptions are a way of encoding potential failure modes into the type system via method signatures. This makes certain failure cases part of the API contract, forcing client code to explicitly handle these cases.

Consider this method signature:

public byte[] readFileContents(String filePath) throws IOException

The throws IOException clause tells us something critical: this method might fail in ways related to IO operations. The compiler ensures you can't simply ignore this fact. You must either:

  1. Handle the exception with a try-catch block
  2. Propagate it by declaring it in your own method signature

This type-level representation of potential failures aligns perfectly with principles of modern type-safe programming.

Automatic Propagation: A Hidden Advantage

One often overlooked advantage of Java's checked exceptions is their automatic propagation. Once you declare a method as throws IOException, any exception that occurs is automatically propagated to the caller without additional syntax.

Compare this with Rust, where you must use the ? operator every time you call a function that returns a Result:

// Rust requires explicit propagation with ? for each call
fn read_and_process(path: &str) -> Result<(), std::io::Error> {
    let content = std::fs::read_to_string(path)?;
    process_content(&content)?;
    Ok(())
}

// Java automatically propagates exceptions once declared
void readAndProcess(String path) throws IOException {
    String content = Files.readString(Path.of(path));
    processContent(content); // If this throws IOException, it's automatically propagated
}

In complex methods with many potential failure points, Java's approach leads to cleaner code by eliminating the need for repetitive error propagation markers.

Modern Parallels: Result Types in Rust and Haskell

The approach of encoding failure possibilities in the type system has been adopted by many modern languages, most notably Rust with its Result<T, E> type and Haskell with its Either a b type.

In Rust:

fn read_file_contents(file_path: &str) -> Result<Vec<u8>, std::io::Error> {
    std::fs::read(file_path)
}

When calling this function, you can't just ignore the potential for errors—you need to handle both the success case and the error case, often using the ? operator or pattern matching.

In Haskell:

readFileContents :: FilePath -> IO (Either IOException ByteString)
readFileContents path = try $ BS.readFile path

Again, the caller must explicitly deal with both possible outcomes.

This is fundamentally the same insight that motivated Java's checked exceptions: make failure handling explicit in the type system.

Valid Criticisms of Checked Exceptions

If checked exceptions are conceptually similar to these widely-praised error handling mechanisms, why have they fallen out of favor? There are several legitimate criticisms:

1. Excessive Boilerplate in the Call Chain

The most common complaint is the boilerplate required when propagating exceptions up the call stack:

void methodA() throws IOException {
    methodB();
}

void methodB() throws IOException {
    methodC();
}

void methodC() throws IOException {
    // Actual code that might throw IOException
}

Every method in the chain must declare the same exception, creating repetitive code. While automatic propagation works well within a method, the explicit declaration in method signatures creates overhead.

2. Poor Integration with Functional Programming

Java 8 introduced lambdas and streams, but checked exceptions don't play well with them:

// Won't compile because map doesn't expect functions that throw checked exceptions
List<String> fileContents = filePaths.stream()
    .map(path -> Files.readString(Path.of(path))) // Throws IOException
    .collect(Collectors.toList());

This forces developers to use awkward workarounds:

List<String> fileContents = filePaths.stream()
    .map(path -> {
        try {
            return Files.readString(Path.of(path));
        } catch (IOException e) {
            throw new UncheckedIOException(e); // Wrap in an unchecked exception
        }
    })
    .collect(Collectors.toList());

3. Interface Evolution Problems

Adding a checked exception to an existing method breaks all implementing classes and calling code. This makes evolving interfaces over time difficult, especially for widely-used libraries and frameworks.

4. Catch-and-Ignore Anti-Pattern

The strictness of checked exceptions can lead to the worst possible outcome—developers simply catching and ignoring exceptions to make the compiler happy:

try {
    // Code that might throw
} catch (Exception e) {
    // Do nothing or just log
}

This is worse than having no exception checking at all because it provides a false sense of security.

Improving Checked Exceptions Without Abandoning Them

Rather than abandoning checked exceptions entirely, Java could enhance the existing system to address these legitimate concerns. Here are some potential improvements that preserve the type safety benefits while addressing the practical problems:

1. Allow lambdas to declare checked exceptions

One of the biggest pain points with checked exceptions today is their incompatibility with functional interfaces. Consider how much cleaner this would be:

// Current approach - forced to handle or wrap exceptions inline
List<String> contents = filePaths.stream()
    .map(path -> {
        try {
            return Files.readString(Path.of(path));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    })
    .collect(Collectors.toList());

// Potential future approach - lambdas can declare exceptions
List<String> contents = filePaths.stream()
    .map((String path) throws IOException -> Files.readString(Path.of(path)))
    .collect(Collectors.toList());

This would require updating functional interfaces to support exception declarations:

@FunctionalInterface
public interface Function<T, R, E extends Exception> {
    R apply(T t) throws E;
}

2. Generic exception types in throws clauses

Another powerful enhancement would be allowing generic type parameters in throws clauses:

public <E extends Exception> void processWithException(Supplier<Void, E> supplier) throws E {
    supplier.get();
}

This would enable much more flexible composition of methods that work with different exception types, bringing some of the flexibility of Rust's Result<T, E> to Java's existing exception system.

3. Better support for exception handling in functional contexts

Unlike Rust which requires the ? operator for error propagation, Java already automatically propagates checked exceptions when declared in the method signature. What Java needs instead is better support for checked exceptions in functional contexts:

// Current approach for handling exceptions in streams
List<String> contents = filePaths.stream()
    .map(path -> {
        try {
            return Files.readString(Path.of(path));
        } catch (IOException e) {
            throw new RuntimeException(e); // Lose type information
        }
    })
    .collect(Collectors.toList());

// Hypothetical improved API
List<String> contents = filePaths.stream()
    .mapThrowing(path -> Files.readString(Path.of(path))) // Preserves checked exception
    .onException(IOException.class, e -> logError(e))
    .collect(Collectors.toList());

4. Integration with Optional<T> and Stream<T> APIs

The standard library could be enhanced to better support operations that might throw checked exceptions:

// Hypothetical API
Optional<String> content = Optional.ofThrowable(() -> Files.readString(Path.of("file.txt")));
content.ifPresentOrElse(
    this::processContent,
    exception -> log.error("Failed to read file", exception)
);

Comparison with Other Languages' Approaches

It's worth examining how other languages have addressed the error handling problem:

Rust's Result<T, E> and ? operator

Rust's approach using Result<T, E> and the ? operator shows how propagation can be made concise while keeping the type safety benefits. The ? operator automatically unwraps a successful result or returns the error to the caller, making propagation more elegant.

However, Rust's approach requires explicit propagation at each step, which can be more verbose than Java's automatic propagation in certain scenarios.

Kotlin's Approach

Kotlin made all exceptions unchecked but provides functional constructs like runCatching that bring back some type safety in a more modern way:

val result = runCatching {
    Files.readString(Path.of("file.txt"))
}

result.fold(
    onSuccess = { content -> processContent(content) },
    onFailure = { exception -> log.error("Failed to read file", exception) }
)

This approach works well with Kotlin's functional programming paradigm but lacks compile-time enforcement.

Scala's Try[T], Either[A, B], and Effect Systems

Scala offers Try[T], Either[A, B], and various effect systems that encode errors in the type system while integrating well with functional programming:

import scala.util.Try

val fileContent: Try[String] = Try {
  Source.fromFile("file.txt").mkString
}

fileContent match {
  case Success(content) => processContent(content)
  case Failure(exception) => log.error("Failed to read file", exception)
}

This approach preserves type safety while fitting well with Scala's functional paradigm.

Conclusion

Java's checked exceptions were a pioneering attempt to bring type safety to error handling. While the implementation has shortcomings, the core concept aligns with modern type-safe approaches to error handling in languages like Rust and Haskell.

Copying Rust's Result<T, E> might seem like the obvious solution, but it would represent a radical departure from Java's established paradigms. Instead, targeted enhancements to the existing checked exceptions system—like allowing lambdas to declare exceptions and supporting generic exception types—could preserve Java's unique approach while addressing its practical limitations.

The beauty of such improvements is that they'd maintain backward compatibility while making checked exceptions work seamlessly with modern Java features like lambdas and streams. They would acknowledge that the core concept of checked exceptions was sound—the problem was in the implementation details and their interaction with newer language features.

So rather than abandoning checked exceptions entirely, perhaps we should recognize them as a forward-thinking feature that was implemented before its time. As Java continues to evolve, we have an opportunity to refine this system rather than replace it.

In the meantime, next time you're tempted to disparage checked exceptions, remember: they're not just an annoying Java quirk—they're an early attempt at the same type safety paradigm that newer languages now implement with much celebration.

What do you think? Could these improvements make checked exceptions viable for modern Java development? Or is it too late to salvage this controversial feature? I'm interested in hearing your thoughts in the comments.

Read more →
0
0
3

マストドン迷言集

・みくは彼氏いるからメタンフェタミンはだめにゃ

・わぁいうすしおに塩かける クーパー(ぺもりんか)うすしおに塩かけるの大好き

・ねこさんおちんぽにゃ

・ぴゅっぴゅです

・ぺもりんか、男じゃん!

・ヨーグルト400g食べきり女

・気分がいいです!金がないので

・うかごかわいいけどちんちんないから可愛くない

・刑期付き自衛官だったのか

・許してください、何でもしますから!

・ほら見て可愛いマンコたち

0
0
0
0
0
0
0
0
0
0
0

コストコの『塩バターキャラメルスプレッド』で作る焼きりんごがおいしい! パンに塗ってもいいけど背徳的スイーツづくりにも……

背徳的なスプレッドが、またひとつ登場してしまった…。コストコで販売されているフランス産『塩バターキャラメルスプレッド』はたっぷり750g入り! ねっとりとした口当たりで、こってり甘く、パンに塗ればお腹にたまる食べごたえで […]
Read more →
0
0
0
0
0
0
0
0

Termine zum Kampagnen-Start 📆

Sei dabei beim Treffen im Café Katelbach, Große Brunnenstraße 60, !

, 21.3.2025, 18:00.

Und beim Kampagnen-Auftakt in der Jupi Bar, Caffamacherreihe 37,

, 22.3.2025 ab 19 Uhr

für eine bessere

0

One of the most exhausting things about being a (perceived) woman working in computational physics is dealing with men who don't think women can do physics and men who don't think women can code (there is a lot of overlap here). Things men have tried to 'explain' to me recently:
- Basic coding practices
- A topic I have published papers on
- How to debug a code ("have you tried adding print statements")
- How code releases work
- My own ideas 😫

0