.NET: Easily Install Log4Net in .NET Web Application

Logging is an integral tool for debugging applications. For newer developers, or developers who don’t typically work in the .NET ecosystem, setting up Log4Net can be confusing and complicated.

First, we need to add Log4Net to our application with NuGet. Navigate to the top of Visual Studio and click:

 "Tools > NuGet Package Manager > Manage NuGet Packages for Solution" 

Next, in the search bar, type “Log4Net” and install the package to your project.

Open up your AssemblyInfo.cs file and add:

 [assembly: log4net.Config.XmlConfigurator(ConfigFile = "config.log4net", Watch = true)] 

Under your project’s directory, create a “config.log4net” file. This file is customizable but for today, we’re going to stick with a simple configuration that outputs to Visual Studio’s “Output” window and writes to a log file located in your project’s directory. Here’s the file content:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <log4net>
    <!-- Need trace for web applications. -->
    <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%d [%t] %-5p %c %m%n"/>
      &lt;/layout>
    </appender>

    <appender name="FileAppender" type="log4net.Appender.FileAppender">
      <file value="your-app-logs.txt" />
      <appendToFile value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
      </layout>
    </appender>

    <root>
      <level value="ALL"/>
      <appender-ref ref="TraceAppender"/>
      <appender-ref ref="FileAppender"/>
    </root>
  </log4net>
</configuration>

Now, add your logging code like so:

class ClassNeedsLogging {
        private static readonly ILog Logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public void MethodThatNeedsLogging() {
            Logger.Info("Hit MethodThatNeedsLogging");
        }
}

That’s it. Now, you should see logging in the Visual Studio “Output” window. You’ll also be able to see logging in “{Your Project Directory}/your-app-logs.txt”.

.NET Error: Could Not Load File or Assembly “System.Runtime, Version=X.X.X.X, Culture = neutral …” or One of Its Dependencies.

This will be a rather short post today guys. This caused a big headache for me so I just want to get it out there.

I ran into this error: ‘Could Not Load File or Assembly “System.Runtime, Version=X.X.X.X, Culture = neutral …” or One of Its Dependencies’

I googled the heck out of it. Tried multiple different things including repairing visual studio, messing with config files, and much more.

None of the suggested solutions worked. I ended up having to delete the ‘bin’ and ‘obj’ folders.

An old DLL may have been causing some issues. Either way, this fixed it.

Have fun coders. Let me know if this fixed your issue.

-Steve

Log4J Error: “log4j:WARN No appenders could be found for logger”

I recently got these errors when working on a Java web app:

[ERROR] log4j:WARN No appenders could be found for logger (org.apache.cxf.common.logging.LogUtils).
[ERROR] log4j:WARN Please initialize the log4j system properly.

My issue was that my project utilized Log4J2 and a dependency in my pom.xml utilized Log4J. To find which dependency is to blame, comb through the output of the mvn dependency:tree command.

There are a few solutions that could be utilized including changing the dependency to Log4J2, adding a log4j.properties file to the project outputting error messages, or adding a log4j.properties file to the dependency. Adding a log4j.properties file to the dependency made most sense in my case; I didn’t want every project that refers to the dependency to have to define and populate a log4j.properties file. We will go over adding a log4j.properties file to the dependency itself.

Navigate to the resources directory of the offending dependency and create an empty file named log4j.properties. Populating this file with any valid configuration should get rid of the appender error. Remember, this artifact must be published and then referred to the original project.

That’s it! Your error should be fixed!

tl;dr
Navigate to dependency that utilizes log4j and define and populate a log4j.properties file in the resources directory.

Google GWT: Editing Server Side GWT Code with Partial Recompilation

This article is meant to teach developers how to edit GWT server side code with partial recompilation. That is to say, to teach developers how to avoid having to completely restart the GWT app. I’ve decided to author this article because I’ve recently worked with a team that did not know this ability existed or rather, could not find a way to setup partial recompilation.

Use Case: Reduce GWT application compile time and increase developer productivity.

Prerequisites: The gwt-maven-plugin org.codehaus.mojo is placed in your pom.xml.

  1. Run project with mvn gwt:debug in the command line. Wait until “[INFO] Listening for transport dt_socket at address: 8000”
  2. Listen on port 8000 with your preferred IDE utilzing a remote configuration. If this is confusing, you can follow the debugging tutorial located at Google GWT: Debugging Server Side GWT Code.
  3. Edit any code in the server package.
  4. Reload the changes in the IDE (Control + Shift + F9 in Intelilj).
  5. Optional: Navigate to “GWT Development Mode” window -> click “Jetty” tab -> click “Restart Server”. I’ve noticed that with larger code changes this is required but not for small code changes. The disadvantage is that it takes time to restart the server. If possible, try to avoid this.
  6. Set breakpoints to verifying that the code that you changed actually updated.

That’s it! You can partially recompile GWT apps!

Google GWT: Debugging Server Side GWT Code

I recently was working on a project utilizing Google GWT. Many of the developers did not know how to setup and use the debugger with Google GWT projects. Instead, they were relying on logging. Logging is a great tool but a good debugger is invaluable.

This article seeks to allow a developer to debug GWT server side Java code. For this tutorial, we will be utilizing Intellij IDEA but fear not, Eclipse can do the same thing.

We will first assume that the gwt-maven-plugin org.codehaus.mojo is placed in your pom.xml. If you have not set this up, feel free to learn more here.

After verifying this, navigate to the root directory of your project and run the application utilizing “mvn gwt:run”. Now, open up your application and play around with it just to make sure everything is working correctly. This is important to minimize any variables that could cause failure when trying to setup the debugger.

Following this, rerun the project in debug configuration utilizing “mvn gwt:debug”. This will allow a debugger to attach on to localhost with port 8000. Now, navigate to your preferred IDE and create a “Remote” debug configuration that listens on localhost with port 8000. Name this remote debug configuration “gwt debug”.

For Intellij, your settings should look like this:

intellij_remote_debug_configuration_for_gwt

In Intellij, go to “Run -> Debug” and click the remote configuration that you created called “gwt debug”. Now, set a breakpoint in your application, open the application in your browser, and then watch the IDE stop on your breakpoint! Remember, the breakpoint must be under the “server” package!

Let’s Encrypt Upgrade: Error during SSL Handshake with remote server

Recently, I had to upgrade a LetsEncrypt SSL certificate. I issued the commands:

sudo service apache2 stop
./certbot-auto renew # Assumes you are in the correct directory of 'certbot-auto'
sudo service apache2 start

I tested the site and everything seemed to be working correctly. Unfortunately, a little while later, I got this error message:

Proxy Error

The proxy server could not handle the request GET /.
Reason: Error during SSL Handshake with remote server

Apache/2.4.7 (Ubuntu) Server at {my_web_site} Port 443

I retraced my steps and I forgot to recreate {my_web_site}’s keystore file. This site was a Spring Boot application and was utilizing a .p12 file. Here are the steps to regenerate this file:

cd /etc/letsencrypt/live/{my_domain_name}/ # Changes directory to Let's Encrypt directory.
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name tomcat -CAfile chain.pem -caname root # Generates keystore.p12 file
# At this point, you will be prompted to give a password. It makes sense to give the same password as the one located in your config files so you don't have to update the 
# config file. If you choose to use a new password, you will have to update your app's config file to the new password. 

At this point, the new keystore file has been generated and the next step is to simply replace the old keystore file and republish the application.

If Spring Boot is being utilized, and you are not comfortable overwriting the old keystore file, simply go to your configuration file and find the "server.ssl.key-store={value}" key-value pair and replace the value with the new keystore location. You may need to update the "server.ssl.key-store-password={value}" key-value pair if you changed the keystore’s password when the openssl command prompted a password. It is easiest to avoid these updates sticking to the same keystore location and password.