商业模式有点复杂,如果解释不是100%清楚,还请见谅:
uploader 接口(interface) ( String upload(String path, byte[] fileContents)
) 定义了上传文件的不同方式(包含在字节数组中),例如 AmazonUploader
其中包含内容和 path
字符串,并根据给定的 key 将其上传到 Amazon S3。
我有一个类叫做 LocalUploader
在 QA 中使用,将给定的文件数组按原样写入本地磁盘。
uploader 用于两种不同的情况:
- Web 界面,由用户
web
运行 - 命令行界面,由登录
ssh
的用户运行, 通过用户root
.
命令行界面与 Web 界面是不同的 jar,但它们都捆绑了 uploader 。此外,命令行可执行文件是一个运行 java -jar ....
的 bash 脚本。在最后。
想法是将文件保存到已知位置,然后通过简单的静态 http 服务器提供它们。
问题简而言之:由于两个进程写入相同的位置,当一个文件由命令行界面写入时,它不再可由 web 界面写入(web
不能' t 访问由 root
制作的文件,显然,反过来没有问题)。
现在,我的 uploader 坚持使用 Java 6,所以没有 nio
文件包。
工作流程简述:
这是我尝试过的:
- 使用
java.io.File
的.setWritable()
.如果我在写入文件之前这样做,它会失败(返回false
),如果我在之后这样做,它会返回 true 但不会设置writable
旗帜。 - 使用
su
以另一个用户身份运行 jar。但这与参数插入混淆 - 使用
umask
, 立即被 Java 忽略。可能是因为这是一个不同的过程。 - 为 linux 权限使用组标识标志 - 被 Java 迅速忽略。可能是因为这是一个不同的过程。
我没有尝试的:
- 使用 ACL - 我们无法承受破坏底层分区的后果。
- 返回文件作为输出并让 bash 写入文件 - 并非所有命令都需要写入文件,而且,可能需要也可能不需要写入多个文件。这不是我想放入 bash 脚本的逻辑,这是上传者的工作。
注意事项:
- 我在 uploader 上使用 Java 6。没有花哨的东西。
- 我正在为 uploader 使用 Spring 3.2。没有开机。
- 我可能可以使用 uploader 中的实用程序库。
- 我正在使用 Java 8 作为命令行可执行文件。
一些相关代码:
uploader .java
@Override
public String upload(String path, byte[] fileContents) {
final File file = new File(path);
try {
FileUtils.writeByteArrayToFile(file, fileContents);
} catch (IOException e) {
throw new RuntimeException("Error writing file to path " + path, e);
}
return "";
}
初始化.sh
#!/bin/bash
CONFIGDIR=${spring.config.location}
CONFIGFILE=$CONFIGDIR/${app.name}.conf
# Loading a settings from CONFIGFILE
[ -f $CONFIGFILE ] && source $CONFIGFILE
# Setting JAVA_BIN
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
# Starting the application
$JAVACMD $JAVA_OPTS -jar ${app.home}/bin/${build.finalName}.jar "$@" --spring.config.location=$CONFIGDIR/
这整件事闻起来像是一些根本不应该存在的微不足道的问题,但我很难过。将不胜感激。
最佳答案
您尝试过使用 sudo 吗?
sudo -u web $JAVACMD $JAVA_OPTS -jar ${app.home}/bin/${build.finalName}.jar "$@" --spring.config.location=$CONFIGDIR/
这应该可行,因为命令行界面是由以 root 身份登录的用户调用的(这是不推荐的,但我认为这是给定的)。
关于java - 如何确保使用正确的用户或权限创建文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32183968/