DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Low-Code Development: Leverage low and no code to streamline your workflow so that you can focus on higher priorities.

DZone Security Research: Tell us your top security strategies in 2024, influence our research, and enter for a chance to win $!

Launch your software development career: Dive head first into the SDLC and learn how to build high-quality software and teams.

Open Source Migration Practices and Patterns: Explore key traits of migrating open-source software and its impact on software development.

Avatar

Alan Hohn

Director, Software Strategy at Lockheed Martin

Warrenton, US

Joined Jul 2008

https://alanhohn.com

About

I'm the author of The Book of Kubernetes, published in 2022 by No Starch Press. I've worked for over 25 years as a software developer, lead, architect, and manager. I've delivered real applications to production in Ada, Java, Python, and Go, amongst others, and have led multiple software teams in modernization efforts, incorporating cloud, microservice architecture, and containerization on complex programs. I'm an Agile and DevSecOps coach and an experienced trainer for Java, Ansible, containers, software architecture, and Kubernetes.

Stats

Reputation: 5296
Pageviews: 1.3M
Articles: 32
Comments: 56
  • Articles
  • Refcards
  • Trend Reports
  • Events
  • Comments

Articles

article thumbnail
Orchestrating the Cloud: Increase Deployment Speed and Avoid Downtime by Orchestrating Infrastructure, Databases, and Containers
Learn about must-have features of cloud orchestration automation and walk through implementation methods for single cloud and cloud-agnostic scenarios.
May 31, 2024
· 2,549 Views · 3 Likes
article thumbnail
OSGi: Declarative Services and the Registry
Meet declarative services and see three ways to get them into the OSGi Service Registry.
November 4, 2016
· 14,967 Views · 3 Likes
article thumbnail
Karaf Features and OSGi Services: A Bundle
Dive into OSGi bundles and declarative services to see how you can incorporate them into your own work.
October 27, 2016
· 13,327 Views · 2 Likes
article thumbnail
Apache Karaf Features at Startup
Apache Karaf uses features to group together OSGi bundles. There are some tips to know about how it works in order to get it working well.
October 26, 2016
· 16,590 Views · 7 Likes
article thumbnail
Apache Karaf Features for OSGi Deployment
When getting started with Apache Karaf, many things appear to happen by magic. This article tries to remove the mystery from one of them.
October 24, 2016
· 25,438 Views · 12 Likes
article thumbnail
Testing REST Services With Pyresttest
A few lines of YAML is all that it takes in order to test a REST service. It's pretty simple. Alan Hohn has all of the details.
September 30, 2016
· 8,805 Views · 3 Likes
article thumbnail
Mockito Custom Answers
Custom argument matchers and custom answer behavior allow us to use Mockito to mock complex and responsive behavior, making for highly realistic tests.
September 13, 2016
· 5,794 Views · 2 Likes
article thumbnail
Mockito Basic Example Using JDBC
Object mocking frameworks use complex code generation and reflection to cut out a lot of boilerplate test code.
September 12, 2016
· 159,803 Views · 18 Likes
article thumbnail
Apache Camel Content Enricher Example
A simple self-contained example of using Apache Camel to route and transform data.
August 26, 2016
· 19,943 Views · 5 Likes
article thumbnail
Inside VRRP: Packet Captures
VRRP is the backbone of redundancy for an IP address. This third article in a series shows the packet level details.
July 22, 2016
· 13,738 Views · 1 Like
article thumbnail
Spring Annotation Processing: How It Works
If you see an annotation, there must be some code somewhere to process it.
May 2, 2016
· 60,318 Views · 13 Likes
article thumbnail
Collaborators and Libraries: Java Design Patterns for Success
Should constructors throw exceptions? What can the 1815 Congress of Vienna teach us about good Java design?
April 26, 2016
· 9,707 Views · 7 Likes
article thumbnail
ANTLR 4 with Python 2 Detailed Example
ANTLR 4 introduced a handy listener-based API, but sometimes it's better not to use it.
April 4, 2016
· 24,025 Views · 1 Like
article thumbnail
Publishing JSON Schema Documentation With Docson
Trying to communicate using JSON files or messages? Here is a tool that will make it easier to share how the JSON should be constructed, without leaving a code editor and browser.
March 17, 2016
· 17,215 Views · 2 Likes
article thumbnail
Fully Dynamic Classes With ASM
ASM is a Java bytecode manipulation library. Mocking frameworks and runtime code generators use it to dynamically generate Java classes. Here is an introduction to how it works.
February 19, 2016
· 38,759 Views · 16 Likes
article thumbnail
Agile in the Defense Industry: Milestone Reviews
Defense programs have built-in checkpoints, with formal reviews and document deliveries more suitable for waterfall than agile. Agile programs find creative ways to make things work.
January 13, 2016
· 4,149 Views · 3 Likes
article thumbnail
Quick Hadoop Startup in a Virtual Environment
A fully-featured Hadoop environment has a number of pieces that need to be integrated. Vagrant and Ansible are just the tools to make things easier.
January 5, 2016
· 11,083 Views · 8 Likes
article thumbnail
Dynamic Class Enhancement with CGLib
Popular libraries like Spring use CGLib to dynamically generate classes at runtime. Understanding how it works can help you parse those notorious stack traces when something goes wrong.
January 2, 2016
· 28,426 Views · 9 Likes
article thumbnail
CGLib Proxies and Hibernate Lazy Fetching
Lazy fetching with Hibernate is a common source of exceptions (and confusion). This article delves into CGLib proxies to reveal why lazy loading works the way it does.
December 31, 2015
· 12,027 Views · 6 Likes
article thumbnail
Java Dynamic Proxies
A lot of modern Java frameworks use dynamically generated code. This article is designed to demystify a little of what is happening behind the scenes.
December 26, 2015
· 22,970 Views · 18 Likes
article thumbnail
Covering Error Cases in Go Unit Tests
Zone Leader Alan Hohn continues his coverage of unit testing in the Go programming language.
December 13, 2015
· 9,501 Views · 2 Likes
article thumbnail
Presentations with Remark and Mermaid
Browser-based presentations are portable, easy to edit, and they convert easily to PDF. Plus embedded code snippets are a lot easier.
November 28, 2015
· 7,754 Views · 4 Likes
article thumbnail
Docker X11 Client Via SSH
Running a GUI program in Docker takes a little work. So does running a GUI program using SSH X11 forwarding. Putting the two together is the most fun of all.
November 19, 2015
· 33,839 Views · 7 Likes
article thumbnail
Standalone Java application with Jersey and Jetty
I’ve built a small example of running a standalone Java application that both serves static HTML, JavaScript, CSS content, and also publishes a REST web service.
July 7, 2015
· 38,389 Views · 3 Likes
article thumbnail
Measuring String Concatenation in Logging
introduction i had an interesting conversation today about the cost of using string concatenation in log statements. in particular, debug log statements often need to print out parameters or the current value of variables, so they need to build the log message dynamically. so you wind up with something like this: logger.debug("parameters: " + param1 + "; " + param2); the issue arises when debug logging is turned off. inside the logger.debug() statement a flag is checked and the method returns immediately; this is generally pretty fast. but the string concatenation had to occur to build the parameter prior to calling the method, so you still pay its cost. since debug tends to be turned off in production, this is the time when this difference matters. for this reason, we have pretty much all been trained to do this: if (logger.isdebugenabled()) { logger.debug("parameters: " + param1 + "; " + param2); } the discussion was about how much difference this “good practice” makes. caliper this kind of question is perfect for a micro benchmark. my own favorite tool for this purpose is caliper . caliper runs small snippets of code enough times to average out variations. it passes in a number of repetitions, which it calculates in order to make sure that the whole method takes long enough to measure given the resolution of the system clock. caliper also detects garbage collection and hotspot compiling that might impact the accuracy of the tests. caliper uploads results to a google app engine application. its sign-in supports google logins and issues an api key that can be used to organize results and list them. a typical timing methods looks like this: public string timemultstringnocheck(long reps) { for (int i = 0; i < reps; i++) { logger.debug(strings[0] + " " + strings[1] + " " + strings[2] + " " + strings[3] + " " + strings[4]); } return strings[0]; } the return string is not used; it is included in the method solely to ensure that java does not optimize away the method. similarly, the content of the variables used should be randomly generated to avoid compile-time optimization. the full example is available in one of my github repositories , in the org.anvard.introtojava.log package. results the outcome is pretty interesting. string concatenation creates a pretty significant penalty, around two orders of magnitude for our example that concatenates five strings. interesting is that even in the case where we do not use string concatenation (i.e. the simplestring methods), the penalty is around 4x. this is probably the time spent pushing the string parameter onto the stack. the examples with doubles, using string.format() , is even more extreme, four orders of magnitude. the elapsed time here about 4ms, large enough that if the log statement were in a commonly used method, the performance hit would be noticeable. the final method, multstringparams , uses a feature that is available in the slf4j api. it works similarly to string.format() , but in a simple token replace fashion. most importantly, it does not perform the token replace unless the logging level is enabled. this makes this form just as fast as the “check” forms, but in a more compact form. of course, this only works if no special formatting is needed of the log string, or if the formatting can be shifted to a method such as tostring() . what is especially surprising is that this method did not show a penalty in building the object array necessary to pass the parameters into the method. this may have been optimized out by the java runtime since there was no chance of the parameters being used. conclusion the practice of checking whether a logging level is enabled before building the log statement is certainly worthwhile and should be something teams check during peer review.
October 20, 2014
· 9,190 Views · 0 Likes
article thumbnail
Generics and Capture Of
Java SE 7 type inference I taught an introductory Java session on generics, and of course demonstrated the shorthand introduced in Java SE 7 for instantiating an instance of a generic type: // Java SE 6 List l = new ArrayList(); // Java SE 7 List l = new ArrayList<>(); This inference is very friendly, especially when we get into more complex collections: // This Map> m = new HashMap>(); // Becomes Map> m = new HashMap<>(); Not only the key and value type of the map, but the type of object stored in the collection used for the value type can be inferred. Of course, sometimes this inference breaks down. It so happens I ran across an interesting example of this. Imagine populating a set from a list, so as to speed up random access and remove duplicates. Something like this will work: List list = ...; // From somewhere Set nodup = new HashSet<>(list); However, this runs into trouble if the list could be null. The HashSetconstructor will not just return an empty set but will throwNullPointerException. So we need to guard against null here. Of course, like all good programmers, we seize the chance to use a ternary operator because ternary operators are cool. List list = ...; // From somewhere Set nodup = (null == list) ? new HashSet<>() : new HashSet<>(list); And here’s where inference breaks down. Because this is no longer a simple assignment, the statement new HashSet<>() can no longer use the left hand side in order to infer the type. As a result, we get that friendly error message, “Type mismatch: cannot convert from HashSet to Set”. What’s especially interesting is that inference breaks down even though the compiler knows that an object of typeSet is what is needed in order to gain agreement of types. The rules for inference are written to be conservative by doing nothing when an invalid inference might cause issues, while the compiler’s type checking is also conservative in what it considers to be matching types. Also interesting is that we only get that error message for the new HashSet<>(). The statement new HashSet<>(list) that uses the list to populate the set works just fine. This is because the inference is completed using the listparameter. Here’s the constructor: public class HashSet extends ... implements ... { ... public HashSet(Collection c) { ... } ... } The List that we pass in gets captured as Collection and this means that E is bound to String, so all is well. As a result, we wind up with the perfectly valid, if a little funny looking: List list = ...; // From somewhere Set nodup = (null == list) ? new HashSet() : new HashSet<>(list); Of course, I imagine most Java programmers do what I do, which is try to use the shortcut and then add the type parameter when the compiler complains. Following the rule about not meddling in the affairs of compilers (subtle; quick to anger), normally I would just fix it without trying very hard to understand why the compiler liked or didn’t like things done in a certain way. But this one was such a strange case I figured it was worth a longer look.
January 28, 2014
· 11,110 Views · 0 Likes
article thumbnail
Spring Static Application Context
Introduction I had an interesting conversation the other day about custom domain-specific languages and we happened to talk about a feature of Spring that I’ve used before but doesn’t seem to be widely known: the static application context. This post illustrates a basic example I wrote that introduces the static application context and shows how it might be useful. It’s also an interesting topic as it shows some of the well-architected internals of the Spring framework. Most uses of Spring start with XML or annotations and wind up with an application context instance. Behind the scenes, Spring has been working hard to instantiate objects, inject properties, invoke context aware listeners, and so forth. There are a set of classes internal to Spring to help this process along, as Spring needs to hold all of the configuration data about beans before any beans are instantiated. (This is because the beans may be defined in any order, and Spring doesn’t have the exhaustive set of dependencies until all beans are defined.) Spring Static Application Context Spring offers a class called StaticApplicationContext that gives programmatic access from Java to this whole configuration and registration process. This means we can define an entire application context from pure Java code, without using XML or Java annotations or any other tricks. The Javadoc for StaticApplicationContext is here, but an example is coming. Why might we use this? As the Javadoc says, it’s mainly useful for testing. Spring uses it for its own testing, but I’ve found it useful for testing applications that use Spring or other dependency management frameworks. Often, for unit testing, we want to inject different objects into a class from those used in production (e.g. mock objects, or objects that simulate remote invocation, database, or messaging). Of course, we can just keep a separate Spring XML configuration file for testing, but it’s very nice to have our whole configuration right there in the Java unit test class as it makes it easier to maintain. Example I’ve added an example to my intro-to-java repository on GitHub. I created aStaticContext class that provides a very basic Java domain-specific language (DSL) for Spring beans. This is just to make it easier to use from the unit test. The DSL only includes the most basic Spring capabilities: register a bean, set properties, and wire dependencies. package org.anvard.introtojava.spring; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.ApplicationContext; import org.springframework.context.support.StaticApplicationContext; public class StaticContext { public class BeanContext { private String name; private Class beanClass; private ConstructorArgumentValues args; private MutablePropertyValues props; private BeanContext(String name, Class beanClass) { this.name = name; this.beanClass = beanClass; this.args = new ConstructorArgumentValues(); this.props = new MutablePropertyValues(); } public BeanContext arg(Object arg) { args.addGenericArgumentValue(arg); return this; } public BeanContext arg(int index, Object arg) { args.addIndexedArgumentValue(index, arg); return this; } public BeanContext prop(String name, Object value) { props.add(name, value); return this; } public BeanContext ref(String name, String beanRef) { props.add(name, new RuntimeBeanReference(beanRef)); return this; } public void build() { RootBeanDefinition def = new RootBeanDefinition(beanClass, args, props); ctx.registerBeanDefinition(name, def); } } private StaticApplicationContext ctx; private StaticContext() { this.ctx = new StaticApplicationContext(); } public static StaticContext create() { return new StaticContext(); } public ApplicationContext build() { ctx.refresh(); return ctx; } public BeanContext bean(String name, Class beanClass) { return new BeanContext(name, beanClass); } } This class uses several classes that are normally internal to Spring: StaticApplicationContext: Holds bean definitions and provides regular Java methods for registering beans. ConstructorArgumentValues: A smart list for a bean’s constructor arguments. Can hold both wire-by-type and indexed constructor arguments. MutablePropertyValues: A smart list for a bean’s properties. Can hold regular objects and references to other Spring beans. RuntimeBeanReference: A reference by name to a bean in the context. Used for wiring beans together because it allows Spring to delay resolution of a dependency until it’s been instantiated. The StaticContext class uses the builder pattern and provides for method chaining. This makes for cleaner use from our unit test code. Here’s the simplest example: @Test public void basicBean() { StaticContext sc = create(); sc.bean("basic", InnerBean.class).prop("prop1", "abc"). prop("prop2", "def").build(); ApplicationContext ctx = sc.build(); assertNotNull(ctx); InnerBean bean = (InnerBean) ctx.getBean("basic"); assertNotNull(bean); assertEquals("abc", bean.getProp1()); assertEquals("def", bean.getProp2()); } A slightly more realistic example that includes wiring beans together is not much more complicated: @Test public void innerBean() { StaticContext sc = create(); sc.bean("outer", OuterBean.class).prop("prop1", "xyz"). ref("inner", "inner").build(); sc.bean("inner", InnerBean.class).prop("prop1", "ghi"). prop("prop2", "jkl").build(); ApplicationContext ctx = sc.build(); assertNotNull(ctx); InnerBean inner = (InnerBean) ctx.getBean("inner"); assertNotNull(inner); assertEquals("ghi", inner.getProp1()); assertEquals("jkl", inner.getProp2()); OuterBean outer = (OuterBean) ctx.getBean(OuterBean.class); assertNotNull(outer); assertEquals("xyz", outer.getProp1()); assertEquals(inner, outer.getInner()); } Note that once we build the context, we can use it like any other Spring application context, including fetching beans by name or type. Also note that the two contexts we created here are completely separate, which is important for unit testing. Conclusion Much like my post on custom Spring XML, the static application context is a specialty feature that isn’t intended for everyday users of Spring. But I’ve found it convenient when unit testing and it provides an interesting peek into how Spring works.
November 13, 2013
· 32,694 Views · 3 Likes
article thumbnail
Including Custom XML in Spring Configuration
Introduction One of the nice recent features of Spring (2.x era) is support for custom XML. This is the way that Spring itself has added all kinds of new tags such as and . The way this works is pretty elegant, to the point that it makes an interesting alternative for configuring Java using XML, particularly if the application already uses Spring. I’ve written an example application to try to give an easily-copied example of how it’s done. The example uses Spring and a custom XML parser to build dynamic Swing menus. It makes a nice comparison to doing dynamic Swing menus using the Digester version I posted a while back. Of course, this is not a good way to make Java menus in general! In most applications, this would be an example of Soft Coding. This would really only make sense in an application where it was really important to be able to add or remove menus without changing Java code. So treat it as a nice example, but please don’t start making your GUIs this way. Spring Custom XML Custom XML works in a Spring configuration file because Spring can dynamically validate and parse XML. To do this, Spring first has to be able to validate the XML it parses against a schema. It does this by looking for all files on the classpath called META-INF/spring.schemas. These files provide a location on the classpath for the XML schema that goes with a given namespace. For example, the “core” XML for Spring is defined in the beansnamespace. The META-INF/spring.schemas file in the spring-beans JAR has entries like this one: http\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd So when we use the beans schema in our Spring XML, it knows where on the classpath to hunt down the schema so it can validate that XML. Once the schema is validated, Spring needs to find a “handler” that knows how to make Spring beans based on the XML. Spring finds handlers by looking through all the files on the classpath called META-INF/spring.handlers. Thespring.handlers file in the spring-beans JAR has entries like this one: http\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler It’s really the job of the handler to make bean definitions, not the regular Java objects that will live as beans in the Spring application context. This is because Spring still has to manage things like beans depending on other beans, which means Spring has to parse all the XML to figure out the dependency graph before any objects can be instantiated. Example Application Our example application has several parts: The spring.schemas and spring.handlers files in META-INF. An XML schema defining what is valid in our custom namespace. MenuNamespaceHandler, the entry class that allows us to register what XML elements go with what parser classes. MenuDefinitionParser, the actual XML parser for our custom XML namespace. A regular Spring XML configuration file that also includes our custom XML. A main class to get the whole thing kicked off. There’s also a Java class called MenuItem that we use to store the ID, the title, and any children of the menu item. It doesn’t know anything about Spring or XML; it’s just a POJO. Defining the custom XML The spring.schemas file is pretty simple. Note that it’s matching to a file on the classpath; Spring is not going to be looking out on the Internet for your XML schema at runtime. http\://anvard.org/springxml/menu.xsd=org/anvard/springxml/menu.xsd The spring.handlers file is also pretty simple. It just points to the right handler class: http\://anvard.org/springxml/menu=org.anvard.springxml.MenuNamespaceHandler The XML schema is omitted here; it’s an XML schema and not much need be said. Of note is that it allows for arbitrary nesting of elements inside other elements. One more piece of boilerplate; the namespace handler. Since our namespace is really simple and only contains one top-level element (menu), it’s a one-liner: public void init() { registerBeanDefinitionParser("menu", new MenuDefinitionParser()); } The parser is where it gets interesting. The parser will get called while Spring is reading the XML file, whenever it comes across an element that belongs to the matching namespace. However, it will only be called for the top-level element; it’s up to us to handle any nested elements as required. protected AbstractBeanDefinition parseInternal(Element element, ParserContext context) { BeanDefinitionBuilder builder = parseItem(element); List childElements = DomUtils.getChildElementsByTagName( element, "menu"); if (null != childElements && childElements.size() > 0) { ManagedList children = new ManagedList<>( childElements.size()); for (Element child : childElements) { children.add(parseInternal(child, context)); } builder.addPropertyValue("children", children); } return builder.getBeanDefinition(); } private BeanDefinitionBuilder parseItem(Element element) { BeanDefinitionBuilder builder = BeanDefinitionBuilder .rootBeanDefinition(MenuItem.class); String id = element.getAttribute("id"); if (StringUtils.hasText(id)) { builder.addPropertyValue("id", id); } String title = element.getAttribute("title"); if (StringUtils.hasText(title)) { builder.addPropertyValue("title", title); } String listener = element.getAttribute("listener"); if (StringUtils.hasText(listener)) { builder.addPropertyReference("listener", listener); } return builder; } In this case, because we allowed for the idea that a menu could contain child menus, we have to handle that here with some recursion. Note that for every element at whatever level, we are creating a separate Spring bean definition (that’s one purpose of the rootBeanDefinition() static method call). The really important thing to notice is that as we build the bean definition, we are not creating a MenuItem object directly, nor are we setting any properties directly. In fact, in the case of the children property, we are not even building a list of the correct type, as the MenuItem class expects to receive a list of MenuItem children, but we are building a list ofAbstractBeanDefinition. Spring handles all of the necessary wiring when it actually instantiates our MenuList objects, including looking up each of the references in the list and populating a new list with the real objects. One other thing that’s slightly confusing is that a reference to a single other Spring bean uses addPropertyReference(), while a managed list of Spring bean definitions uses addPropertyValue(). Using the custom XML Now that these items are in place, we can use the custom XML just the same as any other XML in a Spring configuration file. For example: Note that we can make our custom XML the default namespace so we don’t have to prefix our XML elements; we can also make the bean namespace the default as is more typical in a Spring XML configuration file. We can mix our custom XML freely with standard Spring XML. Also note that our custom XML can make references back to ordinary Spring beans as long as we do the right thing in our parser to make this work. We use a list called toplevel as a handy way of finding the outermost menu items for our menu bar. Once the XML is parsed, the beans are all loaded into the Spring application context and the structure of the XML no longer really applies. Using this file from our main class looks just the same as any Spring code: ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/menuDefinition.xml"); All of our menu items are available in the Spring application context, so we could do ctx.getBean("menu9") and get back the menu item with the title “Child 5”. Conclusion Even though many Spring users are shifting toward annotation-driven configuration, there are still things that are easier to do in XML, like creating many instances of a class with different properties. A custom XML namespace is a way to make Spring XML configuration more compact and more readable.
October 21, 2013
· 17,891 Views · 0 Likes
article thumbnail
Using Maven to Build with Embedded Jetty
Previous posts such as this one have shown using embedded Jetty to REST-enable a standalone Java program. Those posts were lacking an important feature for real applications: packaging into a JAR so the application will run outside of Eclipse and won’t be dependent on Maven and jetty:run. To make this happen, we will use Maven to build an executable JAR that also includes all of the Jetty and Spring dependencies we need. The goal of this work is to get to the point where we can run the example application by: Cloning the Git repository. Running mvn package. Running java -jar target/webmvc-standalone.jar When I started adding the necessary bits to the pom.xml file of my sample application, I expected a relatively straightforward solution. I ended up with a relatively straightforward solution that was completely different from what I expected. So I think it’s worth a detailed discussion of how this solution works and what Maven is doing for us. Our desire to make an executable JAR is complicated by the fact that we want our Maven project to build a WAR as a default package, so that we can use this code in a Java web container if desired. Additionally, we introduce some complexity by making a single JAR with all dependencies, because that causes files in the Spring JARs to collide. I’ll show what I did to address each of these. Build both JAR and WAR The basic idea here is that we want Maven to make both a JAR file and a WAR file during the “package” phase. Our pom.xml file specifies war as the packaging for this project, so the WAR file will be created as expected. We need to add the JAR file without disturbing this. I found a great post here that got me started. The basic idea is to add the following to pom.xml under build/plugins: org.apache.maven.plugins maven-jar-plugin 2.4 package-jar package jar This is the behavior we would get for “free” if we used jar packaging inpom.xml. The execution section ties it to the package phase so that it runs during the default build process. The jar goal tells the plugin what to make. This gets us a basic JAR with the classes in the normal place for a JAR (rather than in WEB-INF/classes as they must be in the WAR file). At the same time, we need to deal with the fact that the Maven resources plugin considers only src/main/resources to be a resources directory, while in our case we have files in src/main/webapp that also need to be included. We want to copy these resources to the target directory so the JAR plugin will pick them up. (This is an important distinction; the typical Maven question, “how do I include extra resources in my JAR?” should really be “how do I get extra resources into target so the JAR plugin will pick them up?”) We add this to the build section of pom.xml: src/main/resources src/main/webapp This causes our new webmvc.jar file to include the HTML, JavaScript, etc. required for our embedded Jetty webapp. JAR with dependencies Next, we make an additional JAR that has the correct Main-Class entry in theMANIFEST.MF file and includes the necessary dependencies so we only have to ship one file. This is done using the Maven assembly plugin. The assembly plugin does repackaging only; that’s why we had to add a JAR artifact above. Without that JAR artifact to work from, the assembly plugin repackages the WAR, and we end up with classes in WEB-INF/classes. This causes Java to complain that it can’t find our main class when we try to run the JAR. The assembly plugin comes with a jar-with-dependencies configuration that can be used simply by adding it as a descriptorRef to the relevant section of pom.xml, as shown in this StackOverflow question. However, this configuration doesn’t work in our particular case, as the Spring dependencies we need have files with overlapping names. As a result, we need to make our own assembly configuration. Fortunately, this is pretty simple. We first add this to the build/plugins section of pom.xml: org.apache.maven.plugins maven-assembly-plugin 2.4 src/assemble/distribution.xml org.anvard.webmvc.server.EmbeddedServer package single As before, we use the executions section to make sure this is run automaticaly during package. We also specify the main class for our application. Finally, we point the plugin to our assembly configuration file, which lives in src/assemble. I present the assembly configuration below, but first we need to talk about the issue with the Spring JARs that made this custom assembly necessary. Spring schemas and handlers With this sample application, we use Spring WebMVC to provide a REST API for ordinary Java classes, as discussed in this post. The Spring code we use is spread across a few different JARs. Recent versions of Spring added a “custom XML namespace” feature that allows the contents of a Spring XML configuration file to be very extensible. Spring WebMVC, and other Spring libraries, use this feature to provide custom XML tags. In order to parse the XML file with these custom tags, Spring needs to be able to match these custom namespaces to handlers. To do this, Spring expects to find files called spring.handlers andspring.schemas in the META-INF directory of any JAR providing a Spring custom namespace. Several of the Spring JARs used by this application include thosespring.handlers and spring.schemas files. Of course, each JAR only includes its own handlers and schemas. When the Maven assembly plugin uses the jar-with-dependencies configuration, only one copy of those files “wins” and makes it into the executable JAR. We really just need a single spring.handlers and spring.schemas that are the concatentation of the respective files. There is probably some Maven magic to accomplish this, but I elected to do it manually as my Bash-fu is much greater than my Maven-fu. I added two files to the src/assemble directory that have the combined contents of the various files in the Spring JARs. Maven assembly configuration The assembly file looks like this: standalone jar true META-INF/spring.handlers META-INF/spring.schemas src/assemble/spring.handlers /META-INF false src/assemble/spring.schemas /META-INF false The id will be used to name this assembly. The baseDirectory tells the assembly plugin that the pieces it assembles should go at the root of the new JAR. (Otherwise they would go into a directory using the project name, in this case “webapp”.) The next two sections are important. We want to exclude thespring.handlers and spring.schemas from the Spring JARs (a.k.a. the dependency set). Instead, we want to explicitly include them from oursrc/assemble directory, and put them into the right place. We also want the assembly plugin to unpack the dependency set JARs so we wind up with Java class files in our new JAR, rather than just JAR-files-inside-JAR-file, which would not run correctly. Notice that there is no directive telling Spring to include all dependencies from the dependency set, including transitive dependencies. This is the default so we don’t need to specify it. It’s also the default to include the unpacked files from our own artifact (webmvc.jar) into the new JAR. Conclusion A real-world application would probably pick either WAR packaging or executable JAR packaging, and be simpler. Additionally, it would be possible to use multiple Maven modules to build a JAR and embed it in the WAR. But it’s interesting to see how to implement a more complex solution that builds everything we need from a single project.
October 18, 2013
· 22,470 Views · 0 Likes
article thumbnail
HTTP and HTTP/S Proxies with Jetty
Introduction I’ve talked before about Jetty as an embedded servlet container. Jetty also includes some useful utility servlet implementations, one of which isProxyServlet. ProxyServlet is a way to create an HTTP or HTTP/S proxy in very few lines of code. Even though it’s part of the Jetty project, it’s modularized to be independent of the Jetty server, so you can use it even in cases where the servlet won’t be run in Jetty. Motivation Why might you need a proxy servlet? One reason is to address issues raised by the same origin policy. In general, a script loaded from one site is not allowed to make requests from a different site. While it is possible to work around this (for example using JSONP) I tend to think a proxy is a more elegant solution as it doesn’t require exploiting a hole to download and evaluate arbitrary JavaScript. A proxy might also be useful to allow a user to access a web service without providing all the information necessary to access it. In our example, we’ll be providing a proxy for Google’s Places API without having to send the Google API key down to the browser. The proxy we’ll be looking at is a per-request proxy, so it’s not something that could conveniently be used for caching remote server responses in case of slow connections or server failures. Example The example is part of the Spring WebMVC application I use to present WebMVC and REST for a Java class. I’ve added the PlacesProxyServletand a basic HTML page to demonstrate fetching Google Places search results and using them in jQuery. Maven POM To get started, we need jetty-proxy in our pom.xml. Prior to Jetty 9, theProxyServlet class lived in jetty-servlets, but it’s been moved, probably to reduce the other Jetty dependencies that have to be pulled in. org.eclipse.jetty jetty-proxy ${jetty.version} Java Next, we create a class that extends ProxyServlet. We need to know the right URI to use for Google Places, and we need a Google API key. The best way to handle this is to allow them to be passed in from the servlet context using init-param, but I like to also allow them to be overridden using Java system properties. We start by overriding the init() method: public void init() throws ServletException { super.init(); ServletConfig config = getServletConfig(); placesUrl = config.getInitParameter("PlacesUrl"); apiKey = config.getInitParameter("GoogleApiKey"); // Allow override with system property try { placesUrl = System.getProperty("PlacesUrl", placesUrl); apiKey = System.getProperty("GoogleApiKey", apiKey); } catch (SecurityException e) { } if (null == placesUrl) { placesUrl = "https://maps.googleapis.com/maps/api/place/search/json"; } } To actually proxy the requests, the key method is rewriteURI. Again, this is new to Jetty 9; previously there was a method called proxyHttpURI that accomplished pretty much the same function. protected URI rewriteURI(HttpServletRequest request) { String query = request.getQueryString(); return URI.create(placesUrl + "?" + query + "&key=" + apiKey); } This method returns the “real” URI that the Jetty proxy servlet will call. All of the data from the client request is available. In this case, we just need the browser’s query parameters so we can pass them on to Google Places. Tweaks To actually get this to work with the Google Places API, there were a couple other changes required. First, the Places API enforces HTTP/S. Note that this doesn’t mean that our client has to connect to our proxy servlet using HTTP/S; regular HTTP is perfectly fine for that connection because our proxy servlet is making a brand new HTTP/S connection (using Jetty’s HttpClientclass). However, it does mean that we need to tell the Jetty HttpClient that it’s OK to use HTTP/S. We do this by overriding the method that theProxyServlet class uses to make a new HttpClient: protected HttpClient newHttpClient() { SslContextFactory sslContextFactory = new SslContextFactory(); HttpClient httpClient = new HttpClient(sslContextFactory); return httpClient; } Second, Google Places didn’t like the fact that the Jetty proxy servlet adds aHost header to the request with the name of the originating server. With this header, the Google Places server returns 404 in response to the request. Fortunately, this is easy to fix; we just have to remove that header before the request goes out. We can do this by overriding the customizeProxyRequestmethod that ProxyServlet thoughtfully provides for just such a problem: protected void customizeProxyRequest(Request proxyRequest, HttpServletRequest request) { proxyRequest.getHeaders().remove("Host"); } Updates to web.xml To get this servlet up and running, we need to add it to web.xml. In the case of the example application, this required updating to Servlet 3.0, since the Jetty proxy servlet wants to use asynchronous connections. This is a good thing in terms of increasing the number of simulataneous requests the proxy servlet can process, but it requires enabling that feature in web.xml: PlacesProxy org.anvard.webmvc.server.PlacesProxyServlet GoogleApiKey YOUR_KEY_HERE 1 true PlacesProxy /places The async-supported tag is important; the proxy servlet won’t work without it. Browser interface On the browser side, we need a way to query and then display the results. I cannibalized some example HTML and JavaScript I had lying around that did something similar with CometD. (Unfortunately, I can’t find the original source to provide a linkback.) The relevant jQuery part looks like this: $.getJSON("/places?location=39.016249,-77.122993&radius=1000&types=food&sensor=false", function ( data ) { console.log( data ); for (i = 0; i < data.results.length; i++) { result =data.results[i]; $('').html(result.name + '' + result.vicinity).appendTo('#contentList'); } }) .fail(function() { console.log( "error" ); }) .always(function() { $("#status").text("Complete."); }); The jQuery makes an AJAX call to the proxy servlet, which then makes a call to Google Places. The resulting JSON response data is sent through as-is. The (anonymous) “success” function then gets called. It iterates through the returned results, adding tags to the existing list for each result it finds. Conclusion Of course, a proxy servlet doesn’t have to be used for sites on the Internet. One of my motivations for creating the example application was to show how easy it was to REST-enable an existing standalone Java application. Many systems that use Java have multiple standalone Java applications, each performing some independent function. This would make it challenging to create a single unified web interface while still allowing each application to define its own REST API. Proxy servlets can help by making it look like there’s a single endpoint for all the various APIs, while not requiring any logic that knows about the contents of the interfaces.
October 15, 2013
· 39,867 Views · 1 Like

Refcards

Refcard #233

Getting Started With Kubernetes

Getting Started With Kubernetes

Refcard #270

Persistent Container Storage

Persistent Container Storage

Trend Reports

Trend Report

Cloud Native

Cloud native has been deeply entrenched in organizations for years now, yet it remains an evolving and innovative solution across the software development industry. Organizations rely on a cloud-centric state of development that allows their applications to remain resilient and scalable in this ever-changing landscape. Amidst market concerns, tool sprawl, and the increased need for cost optimization, there are few conversations more important today than those around cloud-native efficacy at organizations.Google Cloud breaks down "cloud native" into five primary pillars: containers and orchestration, microservices, DevOps, and CI/CD. For DZone's 2024 Cloud Native Trend Report, we further explored these pillars, focusing our research on learning how nuanced technology and methodologies are driving the vision for what cloud native means and entails today. The articles, contributed by experts in the DZone Community, bring the pillars into conversation via topics such as automating the cloud through orchestration and AI, using shift left to improve delivery and strengthen security, surviving observability challenges, and strategizing cost optimizations.

Cloud Native

Trend Report

Kubernetes in the Enterprise

In 2022, Kubernetes has become a central component for containerized applications. And it is nowhere near its peak. In fact, based on our research, 94 percent of survey respondents believe that Kubernetes will be a bigger part of their system design over the next two to three years. With the expectations of Kubernetes becoming more entrenched into systems, what do the adoption and deployment methods look like compared to previous years?DZone's Kubernetes in the Enterprise Trend Report provides insights into how developers are leveraging Kubernetes in their organizations. It focuses on the evolution of Kubernetes beyond container orchestration, advancements in Kubernetes observability, Kubernetes in AI and ML, and more. Our goal for this Trend Report is to help inspire developers to leverage Kubernetes in their own organizations.

Kubernetes in the Enterprise

Events

Watch

On Demand Event Thumbnail

Cloud Native: Championing Cloud Development Across the SDLC

Presenter: Chronosphere, Wiz

Watch

On Demand Event Thumbnail

DZone 2023 Preview: DevOps Edition

Presenter: DZone

Comments

OSGi: Declarative Services and the Registry

Sep 23, 2019 · Alan Hohn

No problem. https://github.com/AlanHohn/karaf-greeter

Adding SSL Support to an Embedded Jetty Server

Aug 29, 2019 · James Sugrue

Unfortunately extra CPU usage is unavoidable with encryption. You might try finding a separate application to do the HTTPS termination, such as HAProxy, and see if it uses less CPU. That separate application can forward traffic to Jetty. But I doubt that would save much CPU.


Mockito Basic Example Using JDBC

Jan 21, 2018 · Alan Hohn

You certainly can test against your specific database as part of integration tests at the microservice or end-to-end test level. Or they can be part of a separate suite of unit tests (e.g. using DBUnit or similar tool) that aren't run as often. (For example, you might run your tests with mocks on every build, but your database integration tests only on the CI server.)

Of course, depending on your circumstances, you might decide that it's not too difficult to just use the real database for your unit tests, and not use mocking for this particular purpose. Remember that this is more of an educational example.

Your definition of the point of mocks is exactly right.

Mockito Basic Example Using JDBC

Jan 19, 2018 · Alan Hohn

It's an excellent question. With this kind of test, there are some things we are testing and some things we are not testing.

We are not testing the validity of the SQL statement created by our Code Under Test. We could test the validity of that (by being a little stricter in how we set up the mock) but that would make the test more brittle when we need to change the SQL statement in some way (e.g. for change in SQL dialect or for performance).

However, we are testing some important things. Since createAndRetrievePerson() performs a create first, then a retrieve, we're testing that on a create, all of the fields are being pulled from the object and put into the database, and that on a retrieve, all of the fields are being pulled from the database and put into the object. If we added a field to our Person object, added it to the test, but left it out of either create() or retrieve() in PersonDao, we would get a test failure.

So we're doing a decent job of testing the "object relational mapping" aspect of our DAO, which is worth something. And we can do it without needing a real database, not even an in-memory one, which means our tests are very easy to set up and are very fast.

If PersonDao was production code instead of an example, we would also check to make sure the right ID is being passed to the prepared statement on retrieve, that retrieving a non-existent object does what we expect, that our code does the right thing if it can't get a database connection, and a few other things. All those things can also be done using mocks.

It still wouldn't replace a test against a real database. But it would mean that our test against a real database could focus on whether we got the SQL right, which means that "real database" test would be simpler and could focus on the 'happy path' (because our mock test already hit things like failure to talk to the database, which can be hard to simulate reliably in the middle of an automated test).

Docker Images Tree Visualization

Aug 08, 2017 · Arran Glen

I think the third code block (execute the alias) should be "dockviz images -t".

And unfortunately that echo command will clobber your ~/.bash_profile. I think you wanted to append with ">>".

Testing REST Services With Pyresttest

May 16, 2017 · Alan Hohn

There doesn't appear to be a flag for Pyresttest to produce CSV, HTML, or a similar kind of output like JSON. Other than asking the author if it's something that can be added, the only other thing I can recommend is calling the relevant logic yourself from a Python program.

If you look at util/pyresttest within the source code, you can see it delegates to pyresttest/resttest.py. That file contains the logic for running the tests and printing the responses.

CSV File Writer Using Scala

Jan 21, 2017 · Sibanjan Das

If I understand your two cases correctly, you about doubled the amount of data and it took about twice as long. That shows that it's O(n) but it still sounds I/O bound to me.

CSV File Writer Using Scala

Jan 19, 2017 · Sibanjan Das

[Comment size limit]

Not that I'm trying to play the "my language is faster" game, since it would be easy to beat my code. The key here is that both of us are probably I/O bound. If there's an improvement in this code, it's that it doesn't wait until the end to write out each row.

If you go to a Spark version it will be important to make sure that there isn't a similar buffering step where you hold all the rows in memory (even for a partition of the rows in a parallel process) before writing them to disk.

CSV File Writer Using Scala

Jan 19, 2017 · Sibanjan Das

Thanks for putting this together!

You probably were interested in using Scala for the sake of expanding knowledge of Scala, which is to be commended. You might also want to have Python in your toolbox for these kinds of "utility" programs. See what you think of this:

https://gist.github.com/AlanHohn/293c98f9dadfc67443b8078d843d4401

On my four-year-old i5 with 4 GB of RAM it took me under 2 minutes to run this code, with a 20GB network file copy going on in the background.

Apache Karaf Features at Startup

Oct 26, 2016 · Alan Hohn

Thanks!

Design Patterns Are Blueprints

May 23, 2016 · Grzegorz Ziemoński

P.S. It's worth saying again that I think the fault is with my piece for not being clear enough in what I was saying. Also, I invite everyone to read the comments from my piece, where people point out that another key reason why design patterns are good is shorthand communication, which is an excellent argument for Grzegorz's statement in favor of using pattern-specific naming.

Design Patterns Are Blueprints

May 23, 2016 · Grzegorz Ziemoński

[continued; silly DZone character limit]

4. Slavish adherence to the exact code from the GoF or other design patterns book will result in poor code, but recognizing and applying the pattern, even if the implementation looks different, will result in joy and happiness.

A "blueprint" is a document that must be followed exactly. So design patterns are good, but they are not blueprints.

Design Patterns Are Blueprints

May 23, 2016 · Grzegorz Ziemoński

It's pretty clear I didn't get across the point of my piece. Not surprising; I can be guilty of needless obscurity. Though I didn't say what you say I said.

Let me summarize my point, since I think we don't really disagree.

1. Design patterns are good.

2. A key reason why design patterns are good is that they present an approach to a set of similar problems.

3. This means that understanding design patterns can help you write good code even if the code you write doesn't look lilke the Official Canonical Version of the Design Pattern from the GoF book.

How to Tell if You’re a Programmer Geek

Oct 20, 2014 · Tony Thomas

That's a great point, thanks. Caliper had to run the "concatenation" test multiple times because it kept getting interrupted by GC.

How to Tell if You’re a Programmer Geek

Oct 20, 2014 · Tony Thomas

That's a great point, thanks. Caliper had to run the "concatenation" test multiple times because it kept getting interrupted by GC.

How to Tell if You’re a Programmer Geek

Oct 20, 2014 · Tony Thomas

That's a great point, thanks. Caliper had to run the "concatenation" test multiple times because it kept getting interrupted by GC.

How to Tell if You’re a Programmer Geek

Oct 20, 2014 · Tony Thomas

That's a great point, thanks. Caliper had to run the "concatenation" test multiple times because it kept getting interrupted by GC.

Measuring String Concatenation in Logging

Oct 20, 2014 · James Sugrue

That's a great point, thanks. Caliper had to run the "concatenation" test multiple times because it kept getting interrupted by GC.

Measuring String Concatenation in Logging

Oct 20, 2014 · James Sugrue

That's a great point, thanks. Caliper had to run the "concatenation" test multiple times because it kept getting interrupted by GC.

Measuring String Concatenation in Logging

Oct 20, 2014 · James Sugrue

That's a great point, thanks. Caliper had to run the "concatenation" test multiple times because it kept getting interrupted by GC.

Measuring String Concatenation in Logging

Oct 20, 2014 · James Sugrue

That's a great point, thanks. Caliper had to run the "concatenation" test multiple times because it kept getting interrupted by GC.

Measuring String Concatenation in Logging

Oct 20, 2014 · James Sugrue

There's an example of that in my test class, and I measured it. It is indeed just as fast as if-then.

I just mentioned it in passing in the blog post; probably should have given it more play and shown a sample.


Measuring String Concatenation in Logging

Oct 20, 2014 · James Sugrue

There's an example of that in my test class, and I measured it. It is indeed just as fast as if-then.

I just mentioned it in passing in the blog post; probably should have given it more play and shown a sample.


Measuring String Concatenation in Logging

Oct 20, 2014 · James Sugrue

There's an example of that in my test class, and I measured it. It is indeed just as fast as if-then.

I just mentioned it in passing in the blog post; probably should have given it more play and shown a sample.


How to Tell if You’re a Programmer Geek

Oct 20, 2014 · Tony Thomas

There's an example of that in my test class, and I measured it. It is indeed just as fast as if-then.

I just mentioned it in passing in the blog post; probably should have given it more play and shown a sample.


How to Tell if You’re a Programmer Geek

Oct 20, 2014 · Tony Thomas

There's an example of that in my test class, and I measured it. It is indeed just as fast as if-then.

I just mentioned it in passing in the blog post; probably should have given it more play and shown a sample.


How to Tell if You’re a Programmer Geek

Oct 20, 2014 · Tony Thomas

There's an example of that in my test class, and I measured it. It is indeed just as fast as if-then.

I just mentioned it in passing in the blog post; probably should have given it more play and shown a sample.


Measuring String Concatenation in Logging

Oct 20, 2014 · James Sugrue

Yes, the template's better if your API has it, and you can use it (not every value has a properly formatted toString()). Otherwise, if-else is way better from a numbers standpoint, though I agree it isn't the most attractive thing in the source.

Cheetahs have managed the perfect balance between beauty and speed. The rest of us have to work at that tradeoff.

How to Tell if You’re a Programmer Geek

Oct 20, 2014 · Tony Thomas

Yes, the template's better if your API has it, and you can use it (not every value has a properly formatted toString()). Otherwise, if-else is way better from a numbers standpoint, though I agree it isn't the most attractive thing in the source.

Cheetahs have managed the perfect balance between beauty and speed. The rest of us have to work at that tradeoff.

How to Tell if You’re a Programmer Geek

Oct 20, 2014 · Tony Thomas

Yes, the template's better if your API has it, and you can use it (not every value has a properly formatted toString()). Otherwise, if-else is way better from a numbers standpoint, though I agree it isn't the most attractive thing in the source.

Cheetahs have managed the perfect balance between beauty and speed. The rest of us have to work at that tradeoff.

How to Tell if You’re a Programmer Geek

Oct 20, 2014 · Tony Thomas

Yes, the template's better if your API has it, and you can use it (not every value has a properly formatted toString()). Otherwise, if-else is way better from a numbers standpoint, though I agree it isn't the most attractive thing in the source.

Cheetahs have managed the perfect balance between beauty and speed. The rest of us have to work at that tradeoff.

Measuring String Concatenation in Logging

Oct 20, 2014 · James Sugrue

Yes, the template's better if your API has it, and you can use it (not every value has a properly formatted toString()). Otherwise, if-else is way better from a numbers standpoint, though I agree it isn't the most attractive thing in the source.

Cheetahs have managed the perfect balance between beauty and speed. The rest of us have to work at that tradeoff.

Measuring String Concatenation in Logging

Oct 20, 2014 · James Sugrue

Yes, the template's better if your API has it, and you can use it (not every value has a properly formatted toString()). Otherwise, if-else is way better from a numbers standpoint, though I agree it isn't the most attractive thing in the source.

Cheetahs have managed the perfect balance between beauty and speed. The rest of us have to work at that tradeoff.

Custom HTML input element with jQuery

Oct 23, 2013 · Juozas Kaziukenas

Thanks, nice to hear. I may add a couple chapters related to how to undo things; like you say there are a huge number of possible scenarios.

If I could find a simple way to explain how to find detached commits, I'd definitely write that up. The times I've really messed myself up with Git and had to resort to extraordinary measures to get things back have all been related to detached commits or a detached HEAD.


Custom HTML input element with jQuery

Oct 23, 2013 · Juozas Kaziukenas

Thanks, nice to hear. I may add a couple chapters related to how to undo things; like you say there are a huge number of possible scenarios.

If I could find a simple way to explain how to find detached commits, I'd definitely write that up. The times I've really messed myself up with Git and had to resort to extraordinary measures to get things back have all been related to detached commits or a detached HEAD.


IE or Firefox: Which is More Secure?

Oct 19, 2013 · Esther Schindler

Abhijeet,

Thanks for the kind words! I liked your post; it's clear that you're trying to think about the right way to do something. And these kinds of things are hard to get right.

The Javadocs for the Object class have a really good description of what rules should be followed when writing hashCode() and equals(). Where possible, hashcode() should be consistent with equals(). If two objects return true from equals(), they MUST return the same hashcode(). The rules are looser the other way, but if two objects return false from equals(), they should return different values from hashcode() where practical.

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)

In your case, because you didn't make equals() return true for <A,B> and <B,A> you get two map entries. However, you're taking away a little bit of the efficiency of the map because they wind up in the same hash bucket and HashMap has to do some extra work to keep them separated.

The implementation for Google's Table and Apache's MultiKeyMap are probably way better and more efficient than mine. The MultiKeyMap appears to use XOR in its hashcode(). You can see it here:

http://code.ohloh.net/file?fid=uwUNbunte4axGKi7fSolSmyN3ks&cid=YB-GWSWTwck&s=&browser=Default&fp=310491&mp&projSelected=true#L244

XOR is commutative and associative, so what Apache is saying is that the keys can come in any order and they will be treated as the same. But their equals() method says something different! Those guys are smart, so I figure they assumed that the same keys in a different order was low-probability and a more efficient hash function was more important.

Anyway, I enjoyed your post and thinking about the questions you raised.


IE or Firefox: Which is More Secure?

Oct 19, 2013 · Esther Schindler

Abhijeet,

Thanks for the kind words! I liked your post; it's clear that you're trying to think about the right way to do something. And these kinds of things are hard to get right.

The Javadocs for the Object class have a really good description of what rules should be followed when writing hashCode() and equals(). Where possible, hashcode() should be consistent with equals(). If two objects return true from equals(), they MUST return the same hashcode(). The rules are looser the other way, but if two objects return false from equals(), they should return different values from hashcode() where practical.

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)

In your case, because you didn't make equals() return true for <A,B> and <B,A> you get two map entries. However, you're taking away a little bit of the efficiency of the map because they wind up in the same hash bucket and HashMap has to do some extra work to keep them separated.

The implementation for Google's Table and Apache's MultiKeyMap are probably way better and more efficient than mine. The MultiKeyMap appears to use XOR in its hashcode(). You can see it here:

http://code.ohloh.net/file?fid=uwUNbunte4axGKi7fSolSmyN3ks&cid=YB-GWSWTwck&s=&browser=Default&fp=310491&mp&projSelected=true#L244

XOR is commutative and associative, so what Apache is saying is that the keys can come in any order and they will be treated as the same. But their equals() method says something different! Those guys are smart, so I figure they assumed that the same keys in a different order was low-probability and a more efficient hash function was more important.

Anyway, I enjoyed your post and thinking about the questions you raised.


IE or Firefox: Which is More Secure?

Oct 19, 2013 · Esther Schindler

Abhijeet,

Thanks for the kind words! I liked your post; it's clear that you're trying to think about the right way to do something. And these kinds of things are hard to get right.

The Javadocs for the Object class have a really good description of what rules should be followed when writing hashCode() and equals(). Where possible, hashcode() should be consistent with equals(). If two objects return true from equals(), they MUST return the same hashcode(). The rules are looser the other way, but if two objects return false from equals(), they should return different values from hashcode() where practical.

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)

In your case, because you didn't make equals() return true for <A,B> and <B,A> you get two map entries. However, you're taking away a little bit of the efficiency of the map because they wind up in the same hash bucket and HashMap has to do some extra work to keep them separated.

The implementation for Google's Table and Apache's MultiKeyMap are probably way better and more efficient than mine. The MultiKeyMap appears to use XOR in its hashcode(). You can see it here:

http://code.ohloh.net/file?fid=uwUNbunte4axGKi7fSolSmyN3ks&cid=YB-GWSWTwck&s=&browser=Default&fp=310491&mp&projSelected=true#L244

XOR is commutative and associative, so what Apache is saying is that the keys can come in any order and they will be treated as the same. But their equals() method says something different! Those guys are smart, so I figure they assumed that the same keys in a different order was low-probability and a more efficient hash function was more important.

Anyway, I enjoyed your post and thinking about the questions you raised.


IE or Firefox: Which is More Secure?

Oct 19, 2013 · Esther Schindler

Abhijeet,

Thanks for the kind words! I liked your post; it's clear that you're trying to think about the right way to do something. And these kinds of things are hard to get right.

The Javadocs for the Object class have a really good description of what rules should be followed when writing hashCode() and equals(). Where possible, hashcode() should be consistent with equals(). If two objects return true from equals(), they MUST return the same hashcode(). The rules are looser the other way, but if two objects return false from equals(), they should return different values from hashcode() where practical.

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)

In your case, because you didn't make equals() return true for <A,B> and <B,A> you get two map entries. However, you're taking away a little bit of the efficiency of the map because they wind up in the same hash bucket and HashMap has to do some extra work to keep them separated.

The implementation for Google's Table and Apache's MultiKeyMap are probably way better and more efficient than mine. The MultiKeyMap appears to use XOR in its hashcode(). You can see it here:

http://code.ohloh.net/file?fid=uwUNbunte4axGKi7fSolSmyN3ks&cid=YB-GWSWTwck&s=&browser=Default&fp=310491&mp&projSelected=true#L244

XOR is commutative and associative, so what Apache is saying is that the keys can come in any order and they will be treated as the same. But their equals() method says something different! Those guys are smart, so I figure they assumed that the same keys in a different order was low-probability and a more efficient hash function was more important.

Anyway, I enjoyed your post and thinking about the questions you raised.


IE or Firefox: Which is More Secure?

Oct 19, 2013 · Esther Schindler

Abhijeet,

Thanks for the kind words! I liked your post; it's clear that you're trying to think about the right way to do something. And these kinds of things are hard to get right.

The Javadocs for the Object class have a really good description of what rules should be followed when writing hashCode() and equals(). Where possible, hashcode() should be consistent with equals(). If two objects return true from equals(), they MUST return the same hashcode(). The rules are looser the other way, but if two objects return false from equals(), they should return different values from hashcode() where practical.

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)

In your case, because you didn't make equals() return true for <A,B> and <B,A> you get two map entries. However, you're taking away a little bit of the efficiency of the map because they wind up in the same hash bucket and HashMap has to do some extra work to keep them separated.

The implementation for Google's Table and Apache's MultiKeyMap are probably way better and more efficient than mine. The MultiKeyMap appears to use XOR in its hashcode(). You can see it here:

http://code.ohloh.net/file?fid=uwUNbunte4axGKi7fSolSmyN3ks&cid=YB-GWSWTwck&s=&browser=Default&fp=310491&mp&projSelected=true#L244

XOR is commutative and associative, so what Apache is saying is that the keys can come in any order and they will be treated as the same. But their equals() method says something different! Those guys are smart, so I figure they assumed that the same keys in a different order was low-probability and a more efficient hash function was more important.

Anyway, I enjoyed your post and thinking about the questions you raised.


IE or Firefox: Which is More Secure?

Oct 19, 2013 · Esther Schindler

Abhijeet,

Thanks for the kind words! I liked your post; it's clear that you're trying to think about the right way to do something. And these kinds of things are hard to get right.

The Javadocs for the Object class have a really good description of what rules should be followed when writing hashCode() and equals(). Where possible, hashcode() should be consistent with equals(). If two objects return true from equals(), they MUST return the same hashcode(). The rules are looser the other way, but if two objects return false from equals(), they should return different values from hashcode() where practical.

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)

In your case, because you didn't make equals() return true for <A,B> and <B,A> you get two map entries. However, you're taking away a little bit of the efficiency of the map because they wind up in the same hash bucket and HashMap has to do some extra work to keep them separated.

The implementation for Google's Table and Apache's MultiKeyMap are probably way better and more efficient than mine. The MultiKeyMap appears to use XOR in its hashcode(). You can see it here:

http://code.ohloh.net/file?fid=uwUNbunte4axGKi7fSolSmyN3ks&cid=YB-GWSWTwck&s=&browser=Default&fp=310491&mp&projSelected=true#L244

XOR is commutative and associative, so what Apache is saying is that the keys can come in any order and they will be treated as the same. But their equals() method says something different! Those guys are smart, so I figure they assumed that the same keys in a different order was low-probability and a more efficient hash function was more important.

Anyway, I enjoyed your post and thinking about the questions you raised.


IE or Firefox: Which is More Secure?

Oct 13, 2013 · Esther Schindler

Won't this return the same hashcode for <A,B> as it will for <B,A>?

I think you want something like the example from Joshua Bloch's Effective Java:

 public int hashCode() { int result = 17; result = 31 * result + (key1 == null) ? 0 : key1.hashCode(); result = 31 * result + (key2 == null) ? 0 : key2.hashCode(); return result; } 


I also think there's something odd with your equals() method. If I read it right, it will consider (null,null) equal to any other key. Assuming you want to treat null as equal with itself, which is uncommon but desired in some cases, I suggest something more like this. I haven't tested it, so treat with caution.

public boolean equals (Object other) { if (null == other) return false; if (this.getClass() != other.getClass()) return false; MapKey otherMK = (MapKey)other; if (otherMK.key1 == null && this.key1 != null) return false; if (otherMK.key2 == null && this.key2 != null) return false; if (key1 == null && otherMK.key1 != null) return false; if (key2 == null && otherMK.key2 != null) return false; return ((key1 == null || key1.equals(otherMK.key1)) && (key2 == null || key2.equals(otherMK.key2))); } 
Extending Silverlight AutoCompleteBox

Oct 09, 2013 · Mr B Loid

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Extending Silverlight AutoCompleteBox

Oct 09, 2013 · Mr B Loid

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Extending Silverlight AutoCompleteBox

Oct 09, 2013 · Mr B Loid

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Extending Silverlight AutoCompleteBox

Oct 09, 2013 · Mr B Loid

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Extending Silverlight AutoCompleteBox

Oct 09, 2013 · Mr B Loid

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Add REST to Standalone Java with Jetty and Spring WebMVC

Oct 09, 2013 · mitchp

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Extending Silverlight AutoCompleteBox

Oct 09, 2013 · Mr B Loid

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Extending Silverlight AutoCompleteBox

Oct 09, 2013 · Mr B Loid

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Add REST to Standalone Java with Jetty and Spring WebMVC

Oct 09, 2013 · mitchp

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Add REST to Standalone Java with Jetty and Spring WebMVC

Oct 09, 2013 · mitchp

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Add REST to Standalone Java with Jetty and Spring WebMVC

Oct 09, 2013 · mitchp

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Add REST to Standalone Java with Jetty and Spring WebMVC

Oct 09, 2013 · mitchp

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Add REST to Standalone Java with Jetty and Spring WebMVC

Oct 09, 2013 · mitchp

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



Add REST to Standalone Java with Jetty and Spring WebMVC

Oct 09, 2013 · mitchp

Yep, exactly, thanks.

I've been lazy and been running it within Eclipse using Eclipse's Maven support, just running the main() in EmbeddedServer. I really ought to get Maven making an executable JAR that could be run anywhere - the idea is to be independent of jetty:run.



User has been successfully modified

Failed to modify user

ABOUT US

  • About DZone
  • Send feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: