Wednesday, December 12, 2018

JPA object is not a known entity type

I have been using EclipseLink JPA for the last 7 years successfully.  Recently, while refactoring some of code I encountered the dreaded exception message "object is not a known entity type".  In the absence of a solution for the problem I settled to use the direct approach of using connection from DataSource and executing a PreparedStatement to create a record in the database.  Not giving up on the issue stumbled across the page: https://java-error-messages.blogspot.com/2011/05/is-not-known-entity-type.html.  Based on the explanation I revisited my code, and realized my mistake, and was able to fix the error.

Base class:
@XmlRootElement
@IdClass(ExtTestCostPK.class)
@MappedSuperclass
public class ExtTestCost implements Serializable {
. . .
. . .
. . .
}

Derived Class
@XmlRootElement
@Entity
@Cacheable(false)
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@Table(name="V_EXT_TEST_COSTS")
public class EstlTestCost extends ExtTestCost {
. . .
. . .
. . .
}

Since I was refactoring the code, I was using following code to persist:
ExtTestCost extTestCost = new ExtTestCost();
// set the class attributes

entityManager.persist(extTestCost);

This piece of code was throwing "object is not a known entity type".  Having spent one sleepless night thinking how to solve the problem, after reading the link mentioned above, realizing the mistake that ExtTestCost indeed is not an entity, modified the code to read:
@XmlRootElement
@IdClass(ExtTestCostPK.class)
@MappedSuperclass
public abstract class ExtTestCost implements Serializable {
. . .
. . .
. . .
}

ExtTestCost extTestCost = new EstlTestCost();
// set the class attributes

entityManager.persist(extTestCost);

so that ExtTestCost can not be instantiated, and ExtTestCost was instantiated as EstlTextCost which indeed is an Entity.  Eclipselink JPA created a record in the database, and the exception disappeared.  Lesson learned is declare the base class abstract so that the default no argument constructor provided by the Java compiler can not be used, and you are forced to use a derived class.  

 

 

Wednesday, March 21, 2018

Tomcat Customization

Introduction

Recently I had a business requirement to intercept the raw request to a servlet container.  The normal entry point to a servlet through the ServletContext was inadequate.  Having worked with Tomcat for a long time, since its earlier version 3.0, I downloaded the source code, and the stepped through the code.  While stepping through the code I noticed that the method service(org.apache.coyote.Request req, org.apache.coyote.Response resof class org.apache.catalina.connector.CoyoteAdapter initiates the request processing and the raw request could be intercepted in this method, and hard coded and is instantiated in the class org.apache.catalina.connector.Connector.  While tomcat server configuration file conf/server.xml provides xml attributes for customization of Connector, could not figure out a way to customize CoyoteAdapter.  With these observations, I added a new parameter to the Connector class to dynamically instantiate the adapter class as against the hard coded CoyoteAdpater class.  With this dynamic instantiation of the AdapterClass I was able to achieve the required customization of Tomcat.  Details of the code changes are detailed in this blog.

Server Configuration


conf/server.xml is the configuration file for Tomcat.  The connector element as shown below is the one which provided the configuration parameters for Tomcat. 

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

For dynamically instantiating the adapter, I added a new parameter called adapterClassName.  With the addition of the new parameter the Connector element changed to:


<Connector port="8080" protocol="HTTP/1.1"
               adapterClassName="<my custom adapter full class name>"
               connectionTimeout="20000"
               redirectPort="8443" />

Modifications to Connector

To read adapterClassName from the server configuration file added a new attribute 
adapterClassName to the Connector class, org.apache.catalina.connector.Connector and provided accessor and mutator methods.
To provide CoyoteAdpater as the default adapter and to dynamically instantiate the adapter based on the attribute specified in the server configuration, code related to adapter instantiation was changed from:
        adapter = new CoyoteAdapter(this);
to:
if(adapterClassName == null) {
adapter = new CoyoteAdapter(this);
} else {
        try {
Class<?> clazz = Class.forName(adapterClassName);
Constructor<Adapter> constructor = (Constructor<Adapter>) clazz.getConstructor(this.getClass());
adapter = (Adapter) constructor.newInstance(this);
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
As can be seen dynamic instantiation of custom adapter was no different than the existing instantiation except that reflection was used to instantiate the adapter.

Extending CoyoteAdpater

The class CoyoteAdpater is about 300 lines of code.  Instead of trying to rewrite the code, I went with the option of extending class and override the service method.

Compiling Tomcat

Since the custom adapter class is dynamically invoked the Tomcat's libraries are independent of the custom adapter and hence existing ant scripts in Tomcat's source code did not require any changes to compile the code.

Compiling Custom Adpater

Custom adpater class is dependent on several Tomcat libraries.  As such a separate Java project was created, with Tomcat libraries as dependencies.  A jar file containing the custom container was created, added to Tomcat lib folder.  Probably the jar file can be added to Tomcat's endorsed directory.  With these few changes I was able to see that custom adapter was instantiated and was working similar to CayoteAdapter.
The CustomAdpater can potentially be used for customizing Tomcat, and there could be several uses.  A few of them would be a proxy server for Microservices where microservice internal location could be determined from a variety of resources.

Summary

Intercepting raw http request in Tomcat requires Tomcat customization.  A simple solution using dynamic invocation was provided to intercept http raw request, and Tomcat customization was presented.  The minimal code changes required for Tomcat customization are presented.



Sunday, March 18, 2018

Integrating Microsoft Exchange Server with Web Applications in Java

Introduction

Recently in one of the projects I have been working I had a requirement to provide email address search where the backend email server was a Microsoft Exchange Server.  After trying several options, came across the open source java api, ews-java-api.  While getting started guide was pretty good, did not provide examples for searching the email addresses, which was my primary requirement.  Having searched the web for several hours then came across the commercial product, Jwebservices for Exchange.  This product provided a trial license for 30 days, and is relatively inexpensive compared with the hourly rates billed by developers.  The product has nice organized examples.  While trying the example code, it was observed that the class names in the commercial products were very similar to the open source API.  Based on the examples I was able to make some simple changes and use it in my web application for searching the email addresses.  Presented here is the sample code I was able to use within my application.

Sample Code

Following is the sample code I used:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import microsoft.exchange.webservices.data.core.ExchangeService;
import microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion;
import microsoft.exchange.webservices.data.credential.ExchangeCredentials;
import microsoft.exchange.webservices.data.credential.WebCredentials;
import microsoft.exchange.webservices.data.misc.NameResolution;
import microsoft.exchange.webservices.data.misc.NameResolutionCollection;
import microsoft.exchange.webservices.data.property.complex.EmailAddress;


public class MyExchangeService {

private ExchangeService service;

public MyExchangeService(String emailAddress, String password) {
service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
ExchangeCredentials credentials = new WebCredentials(emailAddress, password);
service.setCredentials(credentials);

try {
service.autodiscoverUrl(emailAddress);
} catch (Exception e) {
e.printStackTrace();
}
}

public List<EmailAddress> getEmailsAddress(String searchString) {
List<EmailAddress> emailAddresses = new ArrayList<>();
try {
NameResolutionCollection response = service.resolveName(searchString);
if(searchString.startsWith(". ")) {
Iterator<NameResolution> iterator = response.iterator();
while(iterator.hasNext()) {
NameResolution nameResolution = iterator.next();
emailAddresses.add(nameResolution.getMailbox());
}

} else {
Iterator<NameResolution> iterator = response.iterator();
while(iterator.hasNext()) {
NameResolution nameResolution = iterator.next();
emailAddresses.add(nameResolution.getMailbox());
}
}
} catch (Exception e) {
e.printStackTrace();
}

return emailAddresses;
}

public static void main(String[] args) {
final String EMAILADDRESS = "nonone@nowhere.none";
final String PASSWORD = "secret";

MyExchangeService myExchangeService = new MyExchangeService(EMAILADDRESS, PASSWORD);

String searchString = ". AC";
searchString = "somoone@somewhere.com";
List<EmailAddress> emailAddresses = myExchangeService.getEmailsAddress(searchString);

for(EmailAddress emailAddress : emailAddresses) {
System.out.println(emailAddress);
}
}
}

Performance

Compared with the commercial product the open source version is a little bit slower.  But for requirement the open source code worked.  I did not have to goto my project sponsor for $500/-

Saturday, February 24, 2018

Service Discovery using Curator Framework

In an environment hosting large number of web applications employing the traditional architecture with web server farm in the DMZ, and web applications in the walled garden zone static routing of requests using Apache mod_proxy or similar variants require restarting of web servers which require careful planning for maintenance.  In addition large number of entries for static routing in configuration files is error prone.  A better alternate would be a mod_proxy replacement which doesn't require restart of web servers, and automatic discovery of availability of services with the capability to add new services, and withdraw existing services.

Discussed in this blog is a simple idea introducing a proxy between the web servers and the application servers to enable dynamic routing of requests from the web servers to the application servers which eliminates the need for restarting web servers.

Traditional Architecture

The traditional architecture with web server farm in DMZ, and application servers within walled garden zone provide a neat scalable architecture for high volume web services.  In the traditional approach web servers in DMZ are configured as proxy servers to application servers using web server specific modules/connectors: e.g. apache mod_proxy.so for Apache Web Server, Tomcat AJP connector for routing the requests to Tomcat server, and several variations of the same proxy concept.

Need for a Dynamic Proxy

Typically the proxy configuration is manual, and any change to the configuration requires a restart of the web server.  While the manual configuration of routing can be automated using a variety of techniques, the requirement of restarting web servers for the changes to be effective is a significant drawback in case of micro services with large number of applications with large volumes of requests, new services added, existing services withdrawn.  A desired solution would be a proxy module which can automatically pick up the changes in the environment, and the changes in the environment do not require web server restart for the changes to be effective.  One such solution is to use a repository service where services register themselves, and de-register when withdrawn, and the proxy search the repository for the availability and end point of services.  The repository could be a database, a network file system, a zookeeper or any other shared storage system.  Apache Curator Framework provides extensions for such a storage system to store and query services and their endpoints.  As such the dynamic proxy discussed herein is targeted towards using Apache Curator Framework.     

Apache Curator Framework

Apache Curator Framework is a high-level API that greatly simplifies using ZooKeeper adding many features that build on ZooKeeper.  In addition extensions for Service Discovery, and Service Discovery Server are provided.

Self Registration

A service hosted in a servlet container can make use of the servlet container's life cycle methods for publishing their availability after servlet context initialized, and unavailability within the servlet context destroyed method.  Within the servlet context initialized method using the servlet context hostname, and port bindings can be obtained and used to register the internal end point for self registration. With self registration of services, services can publish their end points and availability dynamically.

Service Discovery

Depending on how the services publish their end points these end points could be accessible either externally or internally or both.  Client would execute a query for the service end point, and the query would then send the request to the end point thus retrieved.

Issues with Accessing Services through Load Balancer

The published end points could be external server names/ip addresses or internal server names/ip addresses which the load balancer is unaware off until load balancer is reconfigured.  While applications within the walled garden zone may be able to access these services using the internal addresses, either(both) load balancer reconfiguration, and web server proxy reconfiguration is(are) mandatory to make these services available through the load balancer.  In addition publishing internal server names/ip addresses to to the external services is not desirable as it could potentially be a security threat or the internal server names could not be resolved by external clients or the ip addresses are not accessible.

Services Aware Dynamic Proxy

Routing requests from load balancer/web server proxy to a services aware proxy server would eliminate the need for reconfiguring the load balancer or web server proxy, and restarting web servers in case of web servers being used as proxies.  This dynamic proxy would be responsible for routing the services to actual service end points using the internal hostname/IP Address.  As the proxy can access the services using the internal ip addresses, proxying the requests through the load balancer, web server would enable accessing the services externally through the load balancer.

This proxy will be responsible for intercepting the request, route the request to a functional endpoint using service discovery.  Apache mod_proxy can be modified to dynamically route the requests or a new module using Apache HttpClient library can be created querying the service discovery server, and routing the requests dynamically, eliminating the need to restart the web server.  Code at use-netty-to-proxy-your-requests can be modified to create the dynamic proxy as suggested herein.

Summary

Discussing the need for a dynamic proxy proposed a dynamic proxy querying the service discovery server to dynamically route the requests which would simplify deployment of services. 

Friday, February 23, 2018

Spring Framework - Injecting Map for Session Facade


Introduction

Spring Framework - Injecting Map Examples provided a working example for Injecting Map in Spring Framework.  With an extensive background in J2EE applications, and recently working with spring framework my immediate reaction was to use the same concept for implementing Session Facade in a web application.

Discussed in this blog is a simple implementation of Session Facade using Spring Framework. 

Demonstration Interface, and Classes

An interface Greeter with a single method getGreeting() which would return greeting is defined.  EnglishGreeter implementing Greeter would return "Welcome", and SpanishGreeter implementing the same would return "Bienvenido".  

Session Facade in Non-J2EE Applications

Similar to J2EE Applications several classes implement a common interface defining the specific business implementation.  Acknowledging that there are several methods of facade implementation, a simple implementation using switch statement to get Greeter based on language is shown below:

public interface Greeter {
  public String getGreeting();
}

public class EnglishGreeter implements Greeter {

  @Override
  public String getGreeting() {
    return "Welcome";
  }
}

public class SpanishGreeter implements Greeter {

  @Override
  public String getGreeting() {
    return "Bienvenido";
  }
}

public Greeter getGreeter(Sting lang) {
  Greeter greeter;
  switch (lang) {
    case "English":
      greeter = new EnglishGreeter();
      break;
    case "Spanish":
      greeter = new SpanishGreeter();
      break;
    case default:
      break;
    }
    return greeter;
}


Session Facade in J2EE Applications

Session Facade is one of the most employed design patterns in J2EE applications.  In case of Enterprise Java Beans(EJB) the session facade is implemented using a common interface with several EJBs implementing the base interface and incorporating the business specific logic within the implementing EJBs.

Again acknowledging that several implementations of session facade are possible, a simple implementation using if statement is demonstrated below: 


@Local
public interface Greeter {
  public String getGreeting();

}

@Stateless(name = "englishGreeter", mappedName = "ejb/englishGreeter")
public class EnglishGreeter implements Greeter {

  @Override
  public String getGreeting() {
    return "Welcome";
  }
}

@Stateless(name = "englishGreeter", mappedName = "ejb/spanishGreeter")
public class SpanishGreeter implements Greeter {

  @Override
  public String getGreeting() {
    return "Bienvenido";
  }
}

A simple client consuming above EJBs would look something similar to the following code:

@Local
public class GreeterClient {

  @EJB(mappedName = "ejb/englishGreeter")
  private Greeter englishGreeter;

  @EJB(mappedName = "ejb/spanishGreeter")
  private Greeter spanishGreeter;

  private Map<String, Greeter> map;

  public GreeterClient() {
    map.put("english", englishGreeter);
    map.put("spanish", spanishGreeter);
  }

  public void getGreeting(String lang) {
    Greeter greeter = map.get(lang);
    return greeter.getGreeting();
  }
}

Spring Framework Session Facade Injecting Map


Using Spring framework the same classes with annotations are shown below:

@Component(value="english")
@Qualifier("greeters")
public class EnglishGreeter implements Greeter {

  @Override
  public String getGreeting() {
    return "Welcome";
  }
}

@Component(value="english")
@Qualifier("greeters")
public class SpanishGreeter implements Greeter {

  @Override
  public String getGreeting() {
    return "Bienvenido";
  }
}

@Component
public class GreeterMapper {
    private Map<String, Greeter> map;

    @Autowired
    @Qualifier("greeters")
    public void setMap (Map<String, Greeter> map) {
        this.map = map;
    }

    public Map<String, Greeter> getMap () {
        return map;
    }
}

Spring framework uses value of the component as key, and class name as the value using the GreeterMapper.  The @Qualifier attribute enables grouping of the classes based on the value of the @Qualifier attribute.  GreeterMapper can be obtained from the SpringContext as shown below: 


GreeterMapper bean = context.getBean(GreeterMapper.class);
  
where context is the SpringContext.  Contents of GreeterBean demonstrating the mapping are shown below:

{english=com.teletubbies.util.EnglishGreeter@123f1134, spanish=com.teletubbies.util.SpanishGreeter@7d68ef40}

Language specific greeter from the facade can be obtained from a simple lookup of the map using Map's get method:

Greeter greeter = bean.getMap().get(lang);

Summary

With the help of sample code demonstrated simple facade implementation in ejb applications, and non-ejb applications without spring framework.  Compared with non-spring framework implementations, the annotation @Qualifier within the spring framework simplifies session facade implementation by automating the mapping for session facade.