Sunday, June 30, 2019

Policy Plus - Refresh on Home

Yesterday I found that the WM_SETTINGCHANGE message is sent after a policy refresh to tell applications to detect the new policy. On Home editions Policy Plus uses its own POL-to-Registry applier rather than calling RefreshPolicyEx, so it didn't cause the message to be broadcast. That required Home users to logout/login or reboot after changing policies, which was unfortunate. As suggested by a user I made Policy Plus broadcast that message after applying the policy changes.

The change is live on GitHub.

RefreshPolicy/RefreshPolicyEx send WM_SETTINGCHANGE even on Home editions

RefreshPolicy (or RefreshPolicyEx) causes Windows to examine the Group Policy POL files and apply changes to the Registry. System applications like Explorer are notified of the update. On Home editions, the system does not have the Group Policy infrastructure to apply POLs, but once the Registry is updated, the refresh-policy functions can trigger some applications to see the changes. The functions seem to broadcast WM_SETTINGCHANGE, even on Home editions.

Saturday, June 29, 2019

Exotherm - New best rating achieved

Mercuric, the current FICS deployment of Exotherm, reached a new best rating of 1683 yesterday. It lost a few games after that peak, including one by disconnection, and is now at 1665. Once I find a way to fix the disconnections in the middle of games its rating should increase more.

Friday, June 28, 2019

Java thread stoppage can be blocked by an error handler

Calling stop on a thread object in Java isn't the same as terminating the thread from the OS perspective. Rather, it causes Java to throw a ThreadDeath wherever the target thread currently is. This throwable goes up the call stack like a normal throwable. If it is caught (e.g. by catching all Errors or all Throwables) and not rethrown, the thread can continue.

Wednesday, June 26, 2019

JavaFileManager inferBinaryName isn't used for much

The inferBinaryName method of the JavaFileManager for an in-memory compilation task is called for each file needed for compilation. If custom JavaFileObjects are being used, inferBinaryName needs to be able to handle them. However, it appears that the resulting name isn't used for very much. The part after the last dot is interpreted as the class name and checked for validity as a Java identifier. If it's not valid, the class - at least in the Java version I was working with - is not "included". But after that check, the name doesn't seem to be used for anything.

Monday, June 24, 2019

Policy Plus - ADML language override

Normally Policy Plus detects the user's locale and tries to load ADML files for that language. A Policy Plus user requested the ability to change that behavior, which would be helpful when looking for a policy mentioned in a guide written in another language. So I added a simple dialog to change the preferred language:


If a preferred language code has been set, Policy Plus will use that instead of the locale name.

This change is live on GitHub.

Sunday, June 23, 2019

FMod - Side tileinfo customization

One Abiathar user told me today that their mod uses nonstandard side tileinfo values to trigger special behavior. Abiathar (and FleexCore2) turn all nonzero left and right tile property values into 1, which is a problem if those fields are to be used for something more than "blocking vs. not".

So today I changed FleexCore2 to have byte Left and Right fields rather than Boolean SolidLeft and SolidRight, then adjusted Abiathar's tileinfo translation functions to account for non-Boolean side values. In the interest of backward compatibility to extensions, I kept the functions that take Booleans; they now delegate to the byte-accepting versions, passing 0 or 1.

Virtually all users will only need binary side properties, so rather than entirely replacing the "Solid" checkboxes in the Tile Property Modifier UI I made dropdowns only appear if configured or if that tile has nonbinary side properties. Like with top, bottom, and special properties, custom side properties can be added to the ADEPS file and will appear in the dropdowns.

I also noticed that canceling the entry of a custom tile property value reset the dropdown to the first entry rather than leaving it where it was before. That's now fixed.

Saturday, June 22, 2019

Ktor's default response is 404 even if there's a route

I'm using the Ktor web server/framework to write a web service in Kotlin. I added a handler for a certain route, put some code in it, but found that clients got a 404 error when accessing that path. Apparently the problem was that, since I didn't need to send any data to the client when handling that request, I never used one of the response methods on call - the status code defaulted to 404. Setting the status code with call.response.status produced my expected behavior.

Thursday, June 20, 2019

Some Java permission checks need to be requested by the classloader

Today I was working with a custom SecurityManager implementation, trying to make it restrict one thread group's access to a package. It appeared that checkPermission was not called with a relevant permission during the loading or execution of restricted code, nor was checkPackageAccess called. However, after the custom classloader responsible for loading the untrusted code was adjusted to make a call to the system security manager regarding the class requested by loadClass, class access could be controlled.

Tuesday, June 18, 2019

Trying to use Android UI components from the wrong thread may do something strange

Today I was making an Android app react to websocket events. When I tried to update UI based on the events, I found strange behavior like the layout not updating when a view was set to gone even though the view was no longer visible. Then I realized that the websocket library delivers the events on a different thread. Using a Handler to enqueue the UI-related work for the main thread fixed the problem.

Monday, June 17, 2019

JitPack requires the Maven plugin

A couple days ago I was trying to help make a Java library available through JitPack, an adapter that acts as a Maven repository and builds artifacts from a Git code repository. The JitPack Gradle log seemed to say the build failed with an exception about not being able to find one of the plugins the project used. However, we eventually found that the further-up warning about the lack of maven plugin was much more important. Applying that fixed the problem and allowed the project to build.

Saturday, June 15, 2019

Kotlin won't create SAM literals of interfaces defined in Kotlin

In a recent Kotlin project I wrote an interface definition meant to be consumable from Java and possibly other Kotlin code. It contains only one method, so I expected it to be usable in Kotlin code as a Single Abstract Method implementation literal, e.g. SomeInterface { arg -> ... }. This didn't compile, noting that the interface type has no constructors. Apparently interfaces defined in Kotlin cannot be used in this fashion, possibly as an encouragement to just pass functions instead.

Friday, June 14, 2019

BCEL Repository.lookupClass can't find dynamically generated classes

Recently I used Apache BCEL (Bytecode Engineering Library) to modify classes and load the altered versions. That process starts with Repository.lookupClass call to get a BCEL JavaClass instance representing a class. However, when I tried to do that to a dynamically generated class (actually one that had already been through an editing process) rather than one loaded normally by the system classloader, it couldn't find the class. If I understand correctly, lookupClass searches the application classpath and loads a .class file from disk? That will clearly not work for anything dynamically generated, so the alternate route of passing a byte stream to ClassParser is needed. This works if you can keep track of the bytecode of the edited classes you create, but isn't possible for classes created by others.

Thursday, June 13, 2019

Inner class modifiers are in two places

Today I used Apache BCEL to remove the final modifier from some Java classes, including some inner classes. I successfully altered the modifiers on the ClassGens, but when I loaded the classes I found that the inner ones were still final. Then I remembered that the InnerClass records (in the InnerClasses attribute) have an "inner access flags" property. Once I checked for and removed the final modifier from those, the loaded inner classes were non-final.

Wednesday, June 12, 2019

Conditional breakpoints are extremely slow

Today I was investigating an issue in a JVM application (written in Kotlin but JVM-based nonetheless) and added a conditional breakpoint in IntelliJ to stop at a loop iteration I was interested in. That worked as intended, but I noticed that the program then took dramatically longer to run and that the icon of the Debugger tab in the lower left blinked several times. If I understand correctly, a conditional breakpoint needs to break into the debugger every time, evaluate the condition, and resume execution if appropriate. If I needed the conditional-stop to work faster, I would have added an if statement to the code and set a normal breakpoint on a statement inside that to avoid unnecessary debugger entrances.

Tuesday, June 11, 2019

Intel communication drivers affect Windows audio stuttering, somehow

Recently, seemingly out of nowhere, my Windows 10 laptop's audio started stuttering/glitching every few seconds, regardless of the application producing the sound. A lot of people have encountered similar problems and there doesn't seem to be a consistent fix. After some reading and unsuccessful experimenting I came across a Microsoft Answers thread with a post (by "D Eddy") mentioning the Intel Driver Update Utility. Like that author, I had an outdated Intel Wireless Bluetooth driver. Even though neither audio device I tried (or any of my devices I'm aware of) used Bluetooth, installing that driver somehow fixed the audio problem.

The updater also suggested updates for my WiFi driver and Intel Rapid Storage Technology, but after I tried installing those the Rapid Storage Technology installer failed with an unspecified error and my computer couldn't boot after the restart. (Good thing I had a recent previous Windows version to roll back to.)

Monday, June 10, 2019

Comcast Xfinity routers might not select the best channel automatically

It looks like most people in my apartment complex have a WiFi router in their apartment - there's at least 30 networks in range right now. When I arrived, it was virtually impossible to connect to, much less remain connected with, my network because of all the congestion. The router in my apartment is an Xfinity, which claims to be able to select an appropriate channel automatically. However, using a WiFi inspector app on my phone, I determined that there are many strong signals in the range my network broadcast in. I picked a different channel for the 5 GHz network, which still had several other networks but with weaker signals. I disabled the 2.4 GHz network entirely since connecting to any of the available channels was hopeless. This dramatically improved connectivity: I can now use WiFi normally from anywhere within the apartment.

Sunday, June 9, 2019

Exotherm - Mercuric's rating rising

Today Mercuric once again improved its highest-achieved rating. It peaked at 1673 this afternoon, but is now at 1660. I suspect its disconnections may be from using too much memory and getting terminated, so I just tried launching it with the PYPY_GC_MAX environment variable set at 0.7 GB in order to keep away from my virtual server's capacity of 1 GB. I'll see if it's still up in the morning.

Saturday, June 8, 2019

Java's Proxy can't proxy a class, but Javassist can

One Java project I'm working on needs to be able to create instances of one class (specified dynamically) that act exactly like instances of a class with a very similar set of members. Java's built-in Proxy class can create an object that implements specified interfaces and delegates all method calls to a single handler, but since the resulting objects inherit from Proxy this works for interfaces only. However, the Javassist library provides ProxyFactory, which does something very similar but also allows setting the superclass.

Thursday, June 6, 2019

Exotherm - Established rating

Mercuric has played enough games that the FICS no longer considers its rating provisional/estimated. It's currently at 1640, moderately higher than my atomic rating! That figure is probably lower than it should be because the PyPy process has an unfortunate tendency to stop in the middle of a game (probably due to running out of memory), so it forfeits by disconnection.

Wednesday, June 5, 2019

Android library packages should be unique

I recently set up a project consisting of an Android app module and some Android libraries. I wanted the libraries to provide interchangeable versions of functionality in the app (swapped out via some other tricks), so I tried to give the libraries the same package name in their manifest as the app. However, library code appeared to then use the wrong R class at runtime - the app's, not the library's own - which was somewhat expected. Classes from the library can be dumped into the same Java package as the app classes, but the package declared in the manifest should be different. Library code can still use R (with an import).

Monday, June 3, 2019

The maven-publish plugin is incompatible with Gradle 5.1

Today I published a Java/Kotlin project to Maven Central. I did it from Gradle using the maven-publish and signing plugins using this writeup. After dealing with GPG using Bash on Ubuntu on Windows, I found that the signArchives task failed with "duplicate key" when signing the main JAR. (I previously hit the same error when trying to use the older maven plugin.) After some research I discovered that this workflow doesn't work on Gradle 5.1. Downgrading the project Gradle wrapper to 5.0 fixed the problem.

Saturday, June 1, 2019

Exotherm - Mercuric getting some games

I haven't yet set up a watchdog for the mercuric Python process on my server, so I've just been periodically checking whether it's online and restarting it if it disconnected. Despite the poor uptime, a few people have seen its seeks and played it. Its rating is currently 1568, higher than I expected!