2024 Clojure状态调查!分享您的想法。

欢迎!请参阅关于页面以了解更多此工作的信息。

+1 投票
tools.deps

我遇到了这个错误,花了很长时间才弄清楚。

由于某种原因,下载eclipse工件失败了。
非常令人沮丧。
我发现问题在于$HOME/.m2/repository下的目录权限错误。

下载依赖关系时,未能将任何文件写入到本地Maven仓库,这触发了项目依赖解析失败。
错误与FileNotFound相关 - 而不是“我不能写入此目录”。
这更令人困惑,因为我在那个目录中有些依赖项(可能是以前下载的)。

我怀疑目录权限是由挂载到Docker容器中的本地Maven仓库改变的。

我在Slack上报告了这个问题,并按照Alex Miller的建议提出这个问题。
他提到这可能是由于Maven库,并非tools.deps控制范围内的问题。

在我看来,当Maven库在尝试创建本地文件时并没有错误退出,而当我们尝试通过tools.deps读取文件时则抛出异常,这是很奇怪的。

复制步骤

rm -rf ~/.m2/repository/org/eclipse 
mkdir -p ~/.m2/repository/org/eclipse/
chown root:root ~/.m2/repository/org/eclipse
clojure -Sdeps '{:deps {info.sunng/ring-jetty9-adapter {:mvn/version "0.22.0"}}}'

异常

clojure -Sdeps '{:deps {info.sunng/ring-jetty9-adapter {:mvn/version "0.22.0"}}}'
警告:失败加载S3TransporterFactory类
警告:失败加载S3TransporterFactory类
警告:失败加载S3TransporterFactory类
警告:失败加载S3TransporterFactory类
SLF4J:失败加载类"org.slf4j.impl.StaticLoggerBinder"。
SLF4J:使用无操作(NOP)日志记录器实现默认。
SLF4J:有关详细信息,请参阅http://www.slf4j.org/codes.html#StaticLoggerBinder
警告:失败加载S3TransporterFactory类
警告:失败加载S3TransporterFactory类
警告:失败加载S3TransporterFactory类
警告:失败加载S3TransporterFactory类
构建类路径错误。无法读取org.eclipse.jetty.websocket:websocket-servlet:jar:11.0.15的工件描述符
org.eclipse.aether.resolution.ArtifactDescriptorException:无法读取org.eclipse.jetty.websocket:websocket-servlet:jar:11.0.15的工件描述符

    at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(Unknown Source)
    at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.readArtifactDescriptor(Unknown Source)
    at org.eclipse.aether.internal.impl.DefaultRepositorySystem.readArtifactDescriptor(Unknown Source)
    at clojure.tools.deps.extensions.maven$read_descriptor.invokeStatic(maven.clj:115)
    at clojure.tools.deps.extensions.maven$read_descriptor.invoke(maven.clj:106)
    at clojure.tools.deps.extensions.maven$fn__825.invokeStatic(maven.clj:146)
    at clojure.tools.deps.extensions.maven$fn__825.invoke(maven.clj:143)
    at clojure.lang.MultiFn.invoke(MultiFn.java:244)
    at clojure.tools.deps$expand_deps$children_task__463$fn__465$fn__466.invoke(deps.clj:407)
    at clojure.lang.AFn.applyToHelper(AFn.java:152)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at clojure.core$apply.invokeStatic(core.clj:667)
    at clojure.core$with_bindings_STAR_.invokeStatic(core.clj:1990)
    at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1990)
    at clojure.lang.RestFn.invoke(RestFn.java:425)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.RestFn.applyTo(RestFn.java:132)
    at clojure.core$apply.invokeStatic(core.clj:671)
    at clojure.core$bound_fn_STAR_$fn__7194.doInvoke(core.clj:2020)
    at clojure.lang.RestFn.invoke(RestFn.java:397)
    at clojure.lang.AFn.call(AFn.java:18)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    at java.base/java.lang.Thread.run(Thread.java:1583)

原因:org.eclipse.aether.resolution.ArtifactResolutionException:无法从中央仓库传至 org.eclipse.jetty.websocket:websocket-servlet:pom:11.0.15:/home/ieugen/.m2/repository/org/eclipse/jetty/websocket/websocket-servlet/11.0.15/websocket-servlet-11.0.15.pom.part.lock (不存在文件或目录)

    at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(Unknown Source)
    at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(Unknown Source)
    at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(Unknown Source)
    ... 25 more

原因:org.eclipse.aether.transfer.ArtifactTransferException:无法从中央仓库传至 org.eclipse.jetty.websocket:websocket-servlet:pom:11.0.15:/home/ieugen/.m2/repository/org/eclipse/jetty/websocket/websocket-servlet/11.0.15/websocket-servlet-11.0.15.pom.part.lock (不存在文件或目录)

    at org.eclipse.aether.connector.basic.ArtifactTransportListener.transferFailed(Unknown Source)
    at org.eclipse.aether.connector.basic.BasicRepositoryConnector$TaskRunner.run(Unknown Source)
    at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(Unknown Source)
    at org.eclipse.aether.connector.basic.BasicRepositoryConnector$DirectExecutor.execute(Unknown Source)
    at org.eclipse.aether.connector.basic.BasicRepositoryConnector.get(Unknown Source)
    at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(Unknown Source)
    ... 28 more

原因:java.io.FileNotFoundException:/home/ieugen/.m2/repository/org/eclipse/jetty/websocket/websocket-servlet/11.0.15/websocket-servlet-11.0.15.pom.part.lock (不存在文件或目录)

1 个答案

0

这是在用卷将 ~/.m2 等挂载到 Docker 时遇到的一个常见问题。为了避免再次下载工件,你可能会在 Docker 中下载某些东西。该文件可能会被写成 root 写入到用户家目录中。我在过去几年里也遇到过好几次这种情况。上一次是上周。:slightly_smiling_face: 我也不是 Docker 高手,我可能在使用时犯了错误。当这种情况发生时,不太明显发生了什么,当你想起你曾经遇到过时,你就很幸运。

我们过去也遇到过这个问题。多年来我们一直在使用一个名为 "run-as-user.sh" 的脚本,其内容如下

```
#!/usr/bin/env bash

set -eu

NEW_UID=$(stat -c '%u' /app)
NEW_GID=$(stat -c '%g' /app)

groupmod -g "$NEW_GID" -o hop >/dev/null 2>&1
usermod -u "$NEW_UID" -o hop >/dev/null 2>&1

exec chpst -u hop:hop -U hop:hop env HOME="/home/hop" "$@"
```

我们将其用作容器的入口点。然后在于您所用的 Docker 镜像中使用的 Dockerfile 中也添加以下行(除其他所需的行外),以及安装 `runit` 包的命令(这是提供 `chpst` 命令的包)的命令

```
RUN useradd --home-dir /home/hop --create-home --shell /bin/bash --user-group hop
COPY run-as-user.sh /usr/local/bin
WORKDIR /app
ENTRYPOINT ["run-as-user.sh"]
```

运行容器时,我们通过在容器内部使用卷挂载所需的所有目录(~/.m2、Clojure 应用程序目录等)。我们在容器内部将 Clojure 应用程序目录挂载到 `/app` 之下(这是 `run-as-user.sh` 脚本将查找的地方)。然后,`run-as-user.sh` 脚本会负责更改容器内使用的帐户的 UID 和 GID,以匹配 `/app` 目录所有者(即外部用户)的 UID 和 GID。

希望这能帮助。
...