Solving HttpMessageNotWritableException, Could not write JSON: Could not set field value in Spring Boot

By: (plus.google.com) +David Herron; Date: October 16, 2017

Tags: Spring Boot

My experience of programming on the Spring platform is that you'll be coding along, everything is going great, until an inscrutible complex error message emerges from the depths of who knows where. This message seemed to involve some module or another having created a round peg to fit into a square hole. That is, I'd sent a GET request to retrieve a large object tree, and it seemed that while filling data into a field of a subsidiary object Spring/Hibernate/etc chose the wrong data type, and it threw up an error. The specific type of error was receiving no discussion anywhere, so it was impossible to see how others had solved the problem. The documentation was of no use in explaining anything about this. But, after a couple days of trials and errors and more errors, a solution was found. And, indeed, Spring/Hibernate had chosen the wrong data type to fill into one of the fields, and the solution is fairly simple.

First, let's start with the error:

2017-10-14 15:19:11.869 DEBUG 77461 --- [nio-8080-exec-4] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Written [{timestamp=Sat Oct 14 15:19:11 PDT 2017, status=500, error=Internal Server Error, exception=org.springframework.http.converter.HttpMessageNotWritableException, message=Could not write JSON: Could not set field value [class PowerMeasurementMetaData {
class MeasurementMetadata {
    accumulationCharacteristic: null
    dataQualifier: null
    description: null
    itemDescription: null
    itemUnits: null
    measurementQuality: null
    resolution: null
    siScaleCode: null
}    measuringPeriod: null
    powerDataKind: null
}] value by reflection : [class com.amzur.orangebuttonapi.model.measurementsets.WeatherHistoricalProfile.measurementMetaData] setter of com.amzur.orangebuttonapi.model.measurementsets.WeatherHistoricalProfile.measurementMetaData; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Could not set field value [class PowerMeasurementMetaData {
class MeasurementMetadata {
    accumulationCharacteristic: null
    dataQualifier: null
    description: null
    itemDescription: null
    itemUnits: null
    measurementQuality: null
    resolution: null
    siScaleCode: null
}    measuringPeriod: null
    powerDataKind: null
}] value by reflection : [class com.amzur.orangebuttonapi.model.measurementsets.WeatherHistoricalProfile.measurementMetaData] setter of com.amzur.orangebuttonapi.model.measurementsets.WeatherHistoricalProfile.measurementMetaData (through reference chain: java.util.LinkedList[0]->com.amzur.orangebuttonapi.model.system.PVSystem["weatherProfiles"]), path=/systems}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@4e8b36af]

It first took quite awhile to puzzle through what I was being told by this error message. No stack trace was available, unfortunately. You see at the beginning Could not write JSON followed by Could not set field value, which is pretty clear. Some field, during the phase of serializing an object tree to JSON, could not be assigned. The rest of the error is unclear, but seems to indicate the setter for WeatherHistoricalProfile.measurementMetaData was being given a PowerMeasurementMetaData object. That field is supposed to receive a WeatherMeasurementMetaData object, so of course that would cause an error. But, is that actually what the error said? The error message is not clear, and could be read other ways around.

Even if that is what the error message said, it's not possible by the code for that to occur. A review of the code showed no instance of that combination. But, you need to see the relavent portion of the code.

The goal was to retrieve a PVSystem from the database. That class models a photovoltaic system that could be built from several photovoltaic arrays, subarrays, combiner boxes, inverters, weather stations, utility meters, and so on. The PVSystem object is the top of a sprawling tree of other objects corresponding to those real world thingymajigs.

@Entity
@ApiModel
@AttributeOverride(name = "identifier", column = @Column(name = "systemID"))
public class PVSystem extends LogicalBase {

    ...

    @JsonProperty("weatherProfiles")
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "systemID", nullable = true)
    private List<WeatherHistoricalProfile> weatherProfiles = null;

    ...

    @JsonProperty("energyProfiles")
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "systemID", nullable = true)
    private List<SolarEnergyProfile> energyProfiles = null;

    @JsonProperty("actualPerformance")
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "actualPerformanceID", nullable = true)
    private ActualPerformance actualPerformance = null;

    @JsonProperty("expectedPerformance")
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "expectedPerformanceID", nullable = true)
    private ExpectedPerformance expectedPerformance = null;

    @JsonProperty("predictedPerformance")
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "predictedPerformanceID", nullable = true)
    private ForecastPerformance predictedPerformance = null;


    @JsonProperty("powerProfiles")
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "systemID", nullable = true)
    private List<PowerProfile> powerProfiles = null;
...
}

The classes related to the error message:

@Entity
public class WeatherHistoricalProfile extends WeatherProfile {
    @JsonProperty("measurementSource")
    @Embedded
    private MeasurementSource measurementSource = null;
}

@Entity
public class WeatherProfile extends MeasurementSet {
    @JsonProperty("measurementMetaData")
    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name = "weatherMeasurementMetaID", nullable = true)
    private WeatherMeasurementMetaData measurementMetaData = null;
}

@Entity
public class PowerProfile extends MeasurementSet {
    @JsonProperty("measurementMetaData")
    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name = "powerMeasurementMetaID", nullable = true)
    private PowerMeasurementMetaData measurementMetaData = null;

    @JsonProperty("measurementSource")
    @Embedded
    private MeasurementSource measurementSource = null;
}

@Entity
public class EnergyProfile extends MeasurementSet {
    @JsonProperty("measurementMetaData")
    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name = "energyMeasurementMetaID", nullable = true)
    private EnergyMeasurementMetaData measurementMetaData = null;
}

@Entity
public class MeasurementSet extends Measurement {
}

@Entity
public class Measurement {
    @JsonProperty("measurementID")
    @Id
    @GeneratedValue
    private Integer measurementID;

    @JsonProperty("timeReference")
    @Embedded
    private UTCDateTimeInterval timeReference = null;

    @JsonProperty("measurementMetaData")
    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name = "measurementMetaID", nullable = true)
    private MeasurementMetadata measurementMetaData = null;
}

And the MeasurementMetadata subclass tree

@Entity(name="WeatherMeasurementMetaData")
@AttributeOverride(name="measurementMetaID", 
       column=@Column(name="weatherMeasurementMetaID"))
public class WeatherMeasurementMetaData extends MeasurementMetadata {
    @JsonProperty("weatherDataKind")
    @Enumerated
    private WeatherDataKind weatherDataKind = null;
}

@Entity(name="PowerMeasurementMetaData")
@AttributeOverride(name="measurementMetaID", 
        column=@Column(name="powerMeasurementMetaID"))
public class PowerMeasurementMetaData extends MeasurementMetadata {
    @JsonProperty("measuringPeriod")
    @Enumerated
    private MeasuringPeriodKind measuringPeriod = null;

    @JsonProperty("powerDataKind")
    @Enumerated
    private PowerDataKind powerDataKind = null;
}

@Entity(name="EnergyMeasurementMetaData")
@AttributeOverride(name="measurementMetaID", 
         column=@Column(name="energyMeasurementMetaID"))
public class EnergyMeasurementMetaData extends MeasurementMetadata {
    @JsonProperty("energyDataKind")
    @Enumerated
    private EnergyDataKind energyDataKind = null;

    @JsonProperty("measuringPeriod")
    @Enumerated
    private MeasuringPeriodKind measuringPeriod = null;
}

@Entity
public class MeasurementMetadata {
    @JsonProperty("measurementMetaID")
    @Id
    @GeneratedValue
    private Integer measurementMetaID;

    @JsonProperty("accumulationCharacteristic")
    @Enumerated
    @AttributeOverrides(@AttributeOverride(name = "value", column = 
                @Column(name = "accumulationCharacteristic")))
    private AccumulationKind accumulationCharacteristic = null;

    @JsonProperty("dataQualifier")
    @Enumerated
    @AttributeOverrides(@AttributeOverride(name = "value", column = 
                @Column(name = "dataQualifier")))
    private DataQualifierKind dataQualifier = null;

    @JsonProperty("description")
    private String description = null;

    @JsonProperty("itemDescription")
    private String itemDescription = null;

    @Embedded
    @JsonProperty("itemUnits")
    private XBRLItemType itemUnits = null;

    @JsonProperty("measurementQuality")
    @Enumerated
    @AttributeOverrides(@AttributeOverride(name = "value", column = 
             @Column(name = "measurementQuality")))
    private QualityOfReading measurementQuality = null;

    @JsonProperty("resolution")
    private Float resolution = null;

    @JsonProperty("siScaleCode")
    @Enumerated
    @AttributeOverrides(@AttributeOverride(name = "value", column = 
                @Column(name = "siScaleCode")))
    private SiScaleCodeType siScaleCode = null;
}

The Profile objects are subclassed from Measurement. Each Profile object has a MeasurementMetadata object, and in some cases a subclass of MeasurementMetadata is used. For example WeatherProfile.measurementMetaData takes a WeatherMeasurementMetaData object, EnergyProfile.measurementMetaData takes a EnergyMeasurementMetaData object, and PowerProfile.measurementMetaData takes a PowerMeasurementMetaData object.

We still haven't determined whether the interpretation of the above error message was correct. After some reading and pondering I first tried implementing JsonSerializer objects using the procedure outlined in the Spring Boot documentation. (docs.spring.io) https://docs.spring.io/spring-boot/docs/1.5.7.RELEASE/reference/htmlsingle/#boot-features-json-components Since it seemed to be related to the Serialization process, perhaps a custom Serializer would do the trick.

With Spring Boot this task is simpler than with straight Spring. You create a class:

import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.boot.jackson.*;

@JsonComponent
public class Example {

    public static class Serializer extends JsonSerializer<SomeObject> {
        // ...
    }

    public static class Deserializer extends JsonDeserializer<SomeObject> {
        // ...
    }

}

It contains a pair of inner classes for each class you wish to implement a custom Serializer and Deserializer. Unfortunately the documentation doesn't include a clear example of what to do next. Fortunately there's a bit of a clue in the Spring Boot source code, at (github.com) https://github.com/spring-projects/spring-boot/blob/v1.5.7.RELEASE/spring-boot/src/main/java/org/springframework/boot/jackson/JsonObjectSerializer.java

For a different way to implement @JsonSerialize see (stackoverflow.com) https://stackoverflow.com/questions/7161638/how-do-i-use-a-custom-serializer-with-jackson


@JsonComponent
public class MeasurementsSerializers {

	private static final Logger logger = LoggerFactory.getLogger(MeasurementsSerializers.class);
	
	public static class EnergyProfileSerializer extends JsonSerializer<EnergyProfile> {

		@Override
		public void serialize(EnergyProfile value, JsonGenerator jgen, SerializerProvider serializers)
				throws IOException, JsonProcessingException {
			try {
				logger.info("MeasurementsSerializers serialize EnergyProfile "+ value.toString());
				jgen.writeStartObject();
				jgen.writeNumberField("measurementID", value.getMeasurementID());
				jgen.writeObjectField("timeReference", value.getTimeReference());
				jgen.writeObjectField("measurementMetaData", value.getMeasurementMetaData());
				if (value instanceof SolarEnergyProfile) {
					jgen.writeObjectField("measurementSource", ((SolarEnergyProfile) value).getMeasurementSource());
				}
				if (value instanceof SolarEnergyForecastProfile) {
					jgen.writeObjectField("measurementSource", ((SolarEnergyForecastProfile) value).getMeasurementSource());
				}
				jgen.writeEndObject();
			}
			catch (Exception ex) {
				if (ex instanceof IOException) {
					throw (IOException) ex;
				}
				throw new JsonMappingException(jgen, "Object serialize error", ex);
			}
		}
		
	}
    ...
}

Unfortunately this didn't make any difference in the behavior of the error. But it did give a solid indication that code was being executed and the objects looked correct.

I later decided to implement empty EntityListener classes to again see if I could gain some more insight. I discussed these classes in Persisting complex Embeddable/Embedded objects in Spring/Hibernate

For example:

@Entity
@EntityListeners(EnergyProfileEntityListener.class)
public class EnergyProfile extends MeasurementSet {
    ...
}

The @EntityListeners references an EntityListener class. It looks like so:

public class EnergyProfileEntityListener {

	private static final Logger logger = LoggerFactory.getLogger(EnergyProfileEntityListener.class);
	
	@PrePersist
	public void energyPrePersist(EnergyProfile profile) {
		logger.info("EnergyProfileEntityListener prePersist "+ profile.toString());
	}

	@PostUpdate
	@PostLoad
	public void energyPostLoad(EnergyProfile profile) {
		logger.info("EnergyProfileEntityListener @PostUpdate @PostLoad "+ profile.toString());
	}
}

In case it's not obvious, EntityListener methods are triggered at certain points in the lifecycle of an Entity instance. In this case we're triggering just before the Entity is to be persisted to a database, and then just after the Entity is constructed. One can do quite powerful things with EntityListener methods, but we just want to print something to show what the status of the object is at each moment in time.

THIS step made for a useful change in the behavior of the application in that we could see more data about the error message. The error still occurred but we knew more about what happened.

2017-10-16 16:25:52.595 ERROR 19710 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: Could not set field value [class PowerMeasurementMetaData {
class MeasurementMetadata {
    accumulationCharacteristic: null
    dataQualifier: null
    description: null
    itemDescription: null
    itemUnits: null
    measurementQuality: null
    resolution: null
    siScaleCode: null
}    measuringPeriod: null
    powerDataKind: null
}] value by reflection : [class com.amzur.orangebuttonapi.model.measurementsets.SolarEnergyProfile.measurementMetaData] setter of com.amzur.orangebuttonapi.model.measurementsets.SolarEnergyProfile.measurementMetaData; nested exception is org.hibernate.PropertyAccessException: Could not set field value [class PowerMeasurementMetaData {
class MeasurementMetadata {
    accumulationCharacteristic: null
    dataQualifier: null
    description: null
    itemDescription: null
    itemUnits: null
    measurementQuality: null
    resolution: null
    siScaleCode: null
}    measuringPeriod: null
    powerDataKind: null
}] value by reflection : [class com.amzur.orangebuttonapi.model.measurementsets.SolarEnergyProfile.measurementMetaData] setter of com.amzur.orangebuttonapi.model.measurementsets.SolarEnergyProfile.measurementMetaData] with root cause

java.lang.IllegalArgumentException: Can not set com.amzur.orangebuttonapi.model.measurementsets.EnergyMeasurementMetaData field com.amzur.orangebuttonapi.model.measurementsets.EnergyProfile.measurementMetaData to com.amzur.orangebuttonapi.model.measurementsets.PowerMeasurementMetaData
	at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) ~[na:1.8.0_101]
	at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) ~[na:1.8.0_101]
	at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) ~[na:1.8.0_101]
	at java.lang.reflect.Field.set(Field.java:764) ~[na:1.8.0_101]
	at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:38) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:612) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:220) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4647) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:172) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:128) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.performTwoPhaseLoad(AbstractRowReader.java:238) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:209) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:133) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:88) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:688) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1991) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:570) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:252) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:566) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:135) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:509) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
	at com.amzur.orangebuttonapi.model.systemperformance.ActualPerformance.toIndentedString(ActualPerformance.java:155) ~[classes!/:0.0.1-SNAPSHOT]
	at com.amzur.orangebuttonapi.model.systemperformance.ActualPerformance.toString(ActualPerformance.java:140) ~[classes!/:0.0.1-SNAPSHOT]
	at com.amzur.orangebuttonapi.model.systemperformance.ActualPerformanceEntityListener.metaDataPostLoad(ActualPerformanceEntityListener.java:22) ~[classes!/:0.0.1-SNAPSHOT]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
	at org.hibernate.jpa.event.internal.jpa.ListenerCallback.performCallback(ListenerCallback.java:35) ~[hibernate-entitymanager-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.jpa.event.internal.jpa.CallbackRegistryImpl.callback(CallbackRegistryImpl.java:94) ~[hibernate-entitymanager-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.jpa.event.internal.jpa.CallbackRegistryImpl.postLoad(CallbackRegistryImpl.java:88) ~[hibernate-entitymanager-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.jpa.event.internal.core.JpaPostLoadEventListener.onPostLoad(JpaPostLoadEventListener.java:36) ~[hibernate-entitymanager-5.0.12.Final.jar!/:5.0.12.Final]
	at org.hibernate.engine.internal.TwoPhaseLoad.postLoad(TwoPhaseLoad.java:314) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]

We have essentially the same error message, but it's morphed a bit. We have a stack trace, not that it's entirely useful, and we have verification that something -- Hibernate to be precise -- was trying to fit a square peg into a round hole. That is, assigning a PowerMeasurementMetaData to a EnergyMeasurementMetaData field.

After quite a bit of reviewing the code I had an intuitive hunch and made this change.

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Measurement {
    ....
}

What we had was the case of an Entity class with several subclasses. By default, Hibernate uses a single table to represent all the variants of this class and its subclasses. Clearly Hibernate got confused about which class to assign to the object it was instantiating.

Making this change means Hibernate sets up a separate table for each subclass. In that circumstance, Hibernate does not get confused as to which class to instantiate when retrieving some data.

As a test - I've stripped out the EntityListener and Serializer classes which I'd implemented along the way. The problem is fixed.

« Cryptomining for altcoins (Magi Coin) on linux single board computers Plex says - This server is not powerful enough to convert video »
2016 Election Acer C720 Ad block AkashaCMS Amazon Amazon Kindle Amiga Android Anti-Fascism AntiVirus Software Apple Apple Hardware History Apple iPhone Apple iPhone Hardware April 1st Arduino ARM Compilation Astronomy Asynchronous Programming Authoritarianism Automated Social Posting Ayo.JS Bells Law Big Brother Big Finish Bitcoin Mining Black Holes Blade Runner Blockchain Blogger Blogging Books Botnet Botnets Cassette Tapes Cellphones Christopher Eccleston Chrome Chrome Apps Chromebook Chromebooks Chromebox ChromeOS CIA CitiCards Citizen Journalism Civil Liberties Clinton Cluster Computing Command Line Tools Comment Systems Computer Hardware Computer Repair Computers Cross Compilation Crouton Cryptocurrency Curiosity Rover Cyber Security Cybermen Daleks Darth Vader Data backup Data Storage Database Database Backup Databases David Tenant DDoS Botnet Detect Adblocker Developers Editors Digital Photography Diskless Booting Disqus DIY DIY Repair DNP3 Do it yourself Docker Docker MAMP Docker Swarm Doctor Who Doctor Who Paradox Drobo Drupal Drupal Themes DVD E-Books E-Readers Early Computers Election Hacks Electric Bicycles Electric Vehicles Electron Emdebian Encabulators Energy Efficiency Enterprise Node EPUB ESP8266 Ethical Curation Eurovision Event Driven Asynchronous Express Facebook Fake News Fedora VirtualBox File transfer without iTunes FireFly Fraud Freedom of Speech Gallifrey git Gitlab GMAIL Google Google Chrome Google Gnome Google+ Government Spying Great Britain Heat Loss Hibernate Hoax Science Home Automation HTTPS Human ID I2C Protocol Image Analysis Image Conversion Image Processing ImageMagick In-memory Computing InfluxDB Infrared Thermometers Insulation Internet Internet Advertising Internet Law Internet of Things Internet Policy Internet Privacy iOS Devices iPad iPhone iPhone hacking Iron Man Iternet of Things iTunes Java JavaScript JavaScript Injection JDBC John Simms Journalism Joyent Kaspersky Labs Kindle Kindle Marketplace Lets Encrypt LibreOffice Linux Linux Hints Linux Single Board Computers Logging Mac OS Mac OS X Machine Readable ID macOS MacOS X setup Make Money Online MariaDB Mars Matt Lucas MEADS Anti-Missile Mercurial Michele Gomez Micro Apartments Military Hardware Minification Minimized CSS Minimized HTML Minimized JavaScript Missy Mobile Applications MODBUS Mondas MongoDB Mongoose Monty Python MQTT Music Player Music Streaming MySQL NanoPi Nardole NASA Net Neutrality Node Web Development Node.js Node.js Database Node.js Testing Node.JS Web Development Node.x North Korea npm NY Times Online advertising Online Community Online Fraud Online Journalism Online Video Open Media Vault Open Source Governance Open Source Licenses Open Source Software OpenAPI OpenVPN Paywalls Personal Flight Peter Capaldi Photography PHP Plex Plex Media Server Political Protest Postal Service Power Control Privacy Production use Public Violence Raspberry Pi Raspberry Pi 3 Raspberry Pi Zero Recycling Refurbished Computers Remote Desktop Republicans Retro-Technology Reviews Right to Repair River Song Robotics Rocket Ships RSS News Readers rsync Russia Russia Troll Factory Russian Hacking SCADA Scheme Science Fiction Search Engine Ranking Season 1 Season 10 Season 11 Security Security Cameras Server-side JavaScript Shell Scripts Silence Simsimi Skype Social Media Social Media Warfare Social Networks Software Development Space Flight Space Ship Reuse Space Ships SpaceX Spear Phishing Spring Spring Boot SQLite3 SSD Drives SSD upgrade SSH SSH Key SSL Swagger Synchronizing Files Telescopes Terrorism The Cybermen The Daleks The Master Time-Series Database Torchwood Total Information Awareness Trump Trump Administration Trump Campaign Ubuntu UDOO Virtual Private Networks VirtualBox VLC VNC VOIP Web Applications Web Developer Resources Web Development Web Development Tools Web Marketing Website Advertising Weeping Angels WhatsApp Window Insulation Wordpress YouTube YouTube Monetization