我们有一个可执行的JAR文件,有时包含其他JAR文件.(整个事情依赖于其他四个下载的JAR,位于太空中巨型部署乌龟的背面.)在运行时,我们动态加载嵌套的JAR文件,执行以下操作:
// wearyingly verbose error handling elided
URL nestedURL = the_main_system_classloader.getResource("path/to/nested.jar");
File temp = File.createTempFile (....);
// copy out nestedURL contents into temp, byte for byte
URL tempURL = temp.toURI().toURL();
URLClassLoader loader = URLClassLoader.newInstance(new URL[]{ tempURL });
Class<?> clazz = loader.loadClass("com.example.foo.bar.baz.Thing");
Thing thing = (Thing) clazz.newInstance();
// do stuff with thing
Run Code Online (Sandbox Code Playgroud)
这种技术之前已在这里提出过; 链接包括这一个和这个.我们目前的代码有效...
...大多.我真的想找到一些方法来避免临时文件的创建和复制(以及最终的清理,因为众所周知,deleteOnExit是邪恶的).毕竟,在开始时获得的URL指向JAR:
URL nestedURL = the_main_system_classloader.getResource("path/to/nested.jar");
// nestedURL.toString() at this point is
// "jar:file:/C:/full/path/to/the/executable.jar!/path/to/nested.jar"
URLClassLoader loader = URLClassLoader.newInstance(new URL[]{ nestedURL …Run Code Online (Sandbox Code Playgroud) 这似乎是一个新的问题,但上次我使用Java时,语言没有泛型.我有一个类层次结构(名称更改为尽可能通用):
public abstract class AbstractBase { .... }
public class ConcreateSubA extends AbstractBase { .... }
public class ConcreateSubB extends AbstractBase { .... }
...
public class ConcreateSubZZ9PluralZAlpha extends AbstractBase { .... }
...
Run Code Online (Sandbox Code Playgroud)
我正在尝试清理一些遗留代码,并且有一个地方可以通过泛型将大量重复重复都考虑在一个例程中.(我正在考虑泛型,因为在调用此例程时,它只需要对其中一个具体类进行操作.)
例程看起来像
public <Thing extends AbstractBase> void someFunc()
{
another_function_call (Thing.concreteSpecialToken);
// could also be
// another_function_call (Thing.concreteSpecialToken());
// if methods are more feasible than fields
// Cannot use
// another_function_call (Thing().concreteSpecialToken());
// because creating instances of these types is a Major Operation[tm]
}
Run Code Online (Sandbox Code Playgroud)
我遗漏了大量的线条,但这是重要的部分: someFunc() …
我一直在努力解决SwingWorker的可用性问题,吃掉后台任务中抛出的任何异常,例如,在这个SO线程中描述的.该线程给出了一个很好的问题描述,但没有讨论恢复原始异常.
我已被传递的applet需要向上传播异常.但我甚至无法抓住它.我正在使用此博客条目中的SimpleSwingWorker包装类来尝试解决此问题.这是一个相当小的课程,但我会在这里重新发布它仅供参考.
调用代码看起来很像
try {
// lots of code here to prepare data, finishing with
SpecialDataHelper helper = new SpecialDataHelper(...stuff...);
helper.execute(); // this will call get+done on the actual worker
} catch (Throwable e) {
// used "Throwable" here in desperation to try and get
// anything at all to match, including unchecked exceptions
//
// no luck, this code is never ever used :-(
}
Run Code Online (Sandbox Code Playgroud)
包装纸:
class SpecialDataHelper extends SimpleSwingWorker {
public SpecialDataHelper (SpecialData sd) …Run Code Online (Sandbox Code Playgroud) 所以我们有一个带有自定义命名空间的XML文档.(XML是由我们无法控制的软件生成的.它由名称空间 - 不知道的 DOM解析器解析;标准的Java7SE/Xerces东西,但也在我们的有效控制之外.)输入数据如下所示:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<MainTag xmlns="http://BlahBlahBlah" xmlns:CustomAttr="http://BlitherBlither">
.... 18 blarzillion lines of XML ....
<Thing CustomAttr:gibberish="borkborkbork" ... />
.... another 27 blarzillion lines ....
</MainTag>
Run Code Online (Sandbox Code Playgroud)
我们得到的文档是可用的,xpath可查询和可遍历等等.
将此文档转换为用于写入数据接收器的文本格式使用标准的变换器方法,如"我如何将XML文档更改为Java字符串?"中所述.问题:
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter stringwriter = new StringWriter();
transformer.transform (new DOMSource(theXMLDocument), new StreamResult(stringwriter));
return stringwriter.toString();
Run Code Online (Sandbox Code Playgroud)
它完美无缺.
但现在我想将单个任意节点从该Document转换为字符串.一个DOMSource构造函数接收节点的指针一样的,因为它接受一个Document(实际上文件只是节点的子类,所以它是相同的API,据我可以告诉).因此,在上面的代码片段中的"theXMLDocument"中传递一个单独的节点非常有用......直到我们到达Thing.
那时,transform()抛出一个异常:
java.lang.RuntimeException: Namespace for prefix 'CustomAttr' has not been declared.
at com.sun.org.apache.xml.internal.serializer.SerializerBase.getNamespaceURI(Unknown Source)
at com.sun.org.apache.xml.internal.serializer.SerializerBase.addAttribute(Unknown Source)
at com.sun.org.apache.xml.internal.serializer.ToUnknownStream.addAttribute(Unknown Source) …Run Code Online (Sandbox Code Playgroud) 这有点奇怪,但我对日志记录包及其属性的使用很陌生。我通过谷歌搜索可以找到的所有问题都是“如何使日志记录打开多个文件?” 但我今天的问题是如何让它停止同时处理多个文件。开始了...
首先,这个项目仅限于使用 java.util.logging,不,我不能切换到 log4j 或任何其他第三方包,是的,我知道它们应该更棒。:-)
所以当这个小程序启动时,它会运行这段代码:
import java.util.logging.Logger;
import java.util.logging.LogManager;
// in startup routine:
LogManager.getLogManager().readConfiguration(
this.getClass().getResourceAsStream("/logging.properties"));
Run Code Online (Sandbox Code Playgroud)
从 JAR 中提取属性文件并应用它们,这是有效的。应该readConfiguration()从虚拟机启动时重置所有现有设置。该项目的其余部分有类似的行
private final static Logger LOGGER = Logger.getLogger(NameOfClass.class.getName());
Run Code Online (Sandbox Code Playgroud)
我认为这是相当标准的。我们所有的类都在同一个包中(例如,将其称为 TheProject),并且时髦的日志记录名称/属性层次结构遵循相同的约定,因为这正是 java.util.logging 喜欢的方式。
logging.properties 文件一开始是 Java 6 SE JRE 附带的文件的副本,然后进行了修改。现在看起来像这样:
handlers=java.util.logging.FileHandler,java.util.logging.ConsoleHandler
# Default global logging level.
.level=INFO
# Loggers
# ------------------------------------------
# Loggers are usually attached to packages.
# Here, the level for each package is specified.
# The global level is used by default, so levels
# …Run Code Online (Sandbox Code Playgroud) TL; DR:Eclipse Juno是否存在"让静态导入单独留下地狱"的偏好设置?
几乎所有使用Eclipse的开发人员都在其保存操作列表中组织了Imports.这很好,非常有用.
问题在于静态导入.我们的项目需要仔细管理其静态导入,因此我们强烈希望明确列出它们:
import static thing.foo;
import static thing.bar;
import static thing.baz;
Run Code Online (Sandbox Code Playgroud)
不幸的是,根据Organize Imports中的阈值数量"Number of static imports needed for .*",此块偶尔会崩溃
import static thing.*;
Run Code Online (Sandbox Code Playgroud)
只要Eclipse编辑器认为存在对静态存在的引用,那么将阈值设置为大数就会使静态列表单独存在.然后我们得到这样的场景,选择最简单的例子:
经过几个月的循环足够多次,最终我们到达第8步,高级开发人员放弃了Eclipse的代码和SO上的帖子.
有这样一个问题,提出问题,但没有别的.
是否有一些神奇的首选项或构建设置组合,告诉Eclipse继续为正常的导入做其事情,但只是停止在管理静态导入时徘徊?
我花了一些时间编写 HTML 和 CSS,并使用 Firefox 53 中的开发人员工具。特别是“HTML/DOM/CSS Inspector”。
当您将鼠标移到 Inspector 窗口中的 HTML 块上时,页面上相应呈现的 HTML 元素会突出显示。此外,还有一些有用的网格线和颜色叠加以及页面上绘制的其他内容,所有这些都是 Mozilla 开发人员的一个很好的决定。它显示随机divs 和其他元素可能如何重叠,非常适合显示边距折叠的位置等。
但是,当我将鼠标从 HTML 树上移开时,所有有用的突出显示和覆盖都消失了。有没有办法让突出显示/覆盖“粘住”?例如,直到我单击另一个 HTML 元素,或重新加载页面,或者...主动采取一些行动而不是简单地移动我的鼠标?
请注意,右键单击 Inspector 并选择 ":hover" 菜单条目显然不是我想要的。我想更改Inspector的鼠标悬停行为,而不是页面的鼠标悬停行为。
(现在我要再倒一杯威士忌,然后继续使用规则/计算与“浏览器样式”控件进行战斗。那些......设计得不太好。)
背景:什么有效
有时我们必须使用一个读取 PKCS#12 密钥库的 Java 软件。对于这个特定的项目,我们必须根据需要创建公共/私有对,并将密钥存储在 PKCS12 文件中,因为它很稳定,而且几乎所有东西都可以读取该格式。
因为我们内部做了很多 Java 工作,keytool所以我们想,嘿,只需使用 keytool 来创建私钥和证书即可。一个典型的例子如下所示:
keytool -keystore MyLuggage.p12 -storepass 123456 -storetype pkcs12
-alias "......"
-genkeypair -keyalg RSA -keysize typically_2048_or_3072 -sigalg SHA256withRSA
-ext "KeyUsage=dataEncipherment,digitalSignature,keyEncipherment"
-startdate ....
-dname "......."
Run Code Online (Sandbox Code Playgroud)
实践中实际-keysize值在 2048 到 8192 之间变化;出于这个问题的目的,使用什么似乎没有什么区别,但显然,如果我们要选择它们,我们会使用适合任务的密钥长度(通常由其他软件的约束决定,或者由交给我们的一些规定)。
这一直有效,因为其他软件(包括开头提到的 Java 软件)可以读取密钥库并使用其中的私钥。(并且公钥可以导出使用等)
这就是破坏的地方
该软件最近升级到使用 RSA 的 FIPS 140 认证 Java 库的版本。(“BSAFE”或“JSAFE”取决于您询问的人。)现在,尝试打开以前创建的 PKCS#12 文件失败,并显示
java.lang.SecurityException: Algorithm not allowable in FIPS140 mode: PBE/PKCS12/SHA1/RC2/CBC/40
at ......
at java.security.KeyStore.load(Unknown Source)
Run Code Online (Sandbox Code Playgroud)
省略的 ...... 帧位于我们没有的 RSA 源代码中,并且希望使用在任何情况下都已被混淆的函数名称。因此,查看他们的来源并尝试找出到底是什么导致了这种情况的测试,并不是一种选择。
那么,是什么原因造成这种情况呢?我们选择的唯一算法是“RSA”密钥生成和“SHA256withRSA”签名,这两种算法都是 FIPS …
所以我有一些使用Java 8流的代码,它可以工作.它完全符合我的需要,而且它清晰可读(函数式编程很少见).在子例程的末尾,代码在自定义对类型的List上运行:
// All names Hungarian-Notation-ized for SO reading
class AFooAndABarWalkIntoABar
{
public int foo_int;
public BarClass bar_object;
....
}
List<AFooAndABarWalkIntoABar> results = ....;
Run Code Online (Sandbox Code Playgroud)
这里的数据必须作为数组传递给程序的其他部分,因此它们会被复制出来:
// extract either a foo or a bar from each "foo-and-bar" (fab)
int[] foo_array = results.stream()
.mapToInt (fab -> fab.foo_int)
.toArray();
BarClass[] bar_array = results.stream()
.map (fab -> fab.bar_object)
.toArray(BarClass[]::new);
Run Code Online (Sandbox Code Playgroud)
并做了.现在每个阵列都可以做到.
除了......在列表上的循环两次困扰我的灵魂.如果我们需要跟踪更多信息,他们可能会添加第三个字段,然后必须进行第三次传递以将3元组转换为三个数组,等等.所以我在努力尝试一次性完成.
分配数据结构是微不足道的,但维护消费者使用的索引似乎很可怕:
int[] foo_array = new int[results.size()];
BarClass[] bar_array = new BarClass[results.size()];
// the trick is providing a stateful iterator across the …Run Code Online (Sandbox Code Playgroud)