Featured FREE Whitepapers

What's New Here?

apache-camel-logo

Riding Camel on Java EE 7 – REST Services with Swagger Documentation

Camel comes with a bunch of features out of the box. One of them is the Swagger integration. Unfortunately, most of the already-there features heavily rely on Spring. But this should not stop us from using them in plain Java EE 7 applications, because it sometimes is just the more lightweight variant of doing things. But I don’t want to start a discussion about this again. Instead, I think that there is a technology choice for all situations and if you run across a project you just want to use Camel with Java EE 7 and you need REST services and want to document them with Swagger, this is the right post for you. Bootstrapping Camel in EE 7 The first thing you need, is to bootstrap Camel in a singleton startup bean. I already wrote an article, about how to do this. The other option is to actually use the wildfly-camel subsystem which is also available, but this requires you to be on JBoss WildFly 8.x. Swagger And Camel Rest Dependencies The Swagger integration in Camel as of today is supported for Spring applications only. So, to make this work, we do have to implement a bit and configure a bit more than usual. But I promise, that it is not too complicated and done in a minute. Let’s start: First thing to add to the basic Camel EE 7 example are the additional dependencies for camel: <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-servlet</artifactId> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-metrics</artifactId> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-swagger</artifactId> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jackson</artifactId> </dependency>Returning The Camel Context For Swagger If we can’t use what is there, we need to implement our own CdiRestSwagger-Camel context lookup. There are some things cooking for upcoming Camel versions, but for now we have to do it on our own. Which is surprisingly simple, because we need to overwrite one method of the RestSwaggerApiDeclarationServlet. And this does nothing else than simply return the injected CdiCamelContext. public class CdiRestSwaggerApiDeclarationServlet extends RestSwaggerApiDeclarationServlet {    @Inject     CdiCamelContext context;    @Override     public CamelContext lookupCamelContext(ServletConfig config) {         return context;     } } Some Further Configuration We’re not done yet. You still have some more configuration to do. As Camel is designed to run in many different environments and there is no specific Java EE 7 version, it still rely on web.xml configuration for the mapping servlets. Please pay extra attention to the CdiRestSwaggerApiDeclarationServlet init-parameters. In this simple example, I did not bother with finding them out, but still rely on them. So, depending on the final name of your application that you set in the Maven build, this needs to be tweaked. <context-param> <param-name>contextConfigLocation</param-name> <!-- to use Java DSL --> <param-value>classpath:camel-config.xml</param-value> </context-param><!-- to setup Camel Servlet --> <servlet> <display-name>Camel Http Transport Servlet</display-name> <servlet-name>CamelServlet</servlet-name> <servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet<load-on-startup>1</load-on-startup> </servlet><!-- to setup Camel Swagger api servlet --> <servlet> <!-- we are using our own swagger-cdi binding servlet --> <servlet-class>org.apache.camel.component.swagger.CdiRestSwaggerApiDeclarationServlet <init-param> <param-name>base.path</param-name> <param-value>http://localhost:8080/camel/rest</param-value> </init-param> <init-param> <param-name>api.path</param-name> <param-value> http://localhost:8080/camel/api-docs </param-value> </init-param> <init-param> <param-name>api.version</param-name> <param-value>1.2.3</param-value> </init-param> <init-param> <param-name>api.title</param-name> <param-value>User Services</param-value> </init-param> <init-param> <param-name>api.description</param-name> <param-value>Camel Rest Example with Swagger that provides an User REST service</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet><!-- swagger api declaration --> <servlet-mapping> <servlet-name>ApiDeclarationServlet</servlet-name> <url-pattern>/api-docs/*</url-pattern> </servlet-mapping><!-- define that url path for the Camel Servlet to use --> <servlet-mapping> <servlet-name>CamelServlet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping><!-- enable CORS filter so people can use swagger ui to browse and test the apis --> <filter> <filter-name>RestSwaggerCorsFilter</filter-name> <filter-class>org.apache.camel.component.swagger.RestSwaggerCorsFilter</filter-class> </filter><filter-mapping> <filter-name>RestSwaggerCorsFilter</filter-name> <url-pattern>/api-docs/*</url-pattern> <url-pattern>/rest/*</url-pattern> </filter-mapping> Enough Configuration – To The Logic! When you’re done with that, you need some logic. The example I’m using here was taken from the official Camel examples and is called camel-example-servlet-rest-tomcat. Please note, that this example contains both, a XML DSL based definition and the Java DSL based definition of the rest-service. I only used the Java DSL and specifically the route defined in the UserRouteBuilder class. Make sure to add a @Named annotation to the UserService and the User and add the route from the UserRouteBuilder to your startup bean.    context.addRoutes(new UserRouteBuilder()); That is it. Now you can browser your API by accessing http://localhost:8080/camel/api-docs. If you want to use the Swagger UI you have to add it to your application. The example application contains everything in the build section, that is needed to do this. So, have a look at the complete GitHub project to find out how to browse the API with the Swagger UI.Reference: Riding Camel on Java EE 7 – REST Services with Swagger Documentation from our JCG partner Markus Eisele at the Enterprise Software Development with Java blog....
scala-logo

Solving “Water buckets” problem using Scala

I recently came across a puzzle called the “Water Buckets” problem in this book, which totally stumped me. You have a 12-gallon bucket, an 8-gallon bucket and a 5-gallon bucket. The 12-gallon bucket is full of water and the other two are empty. Without using any additional water how can you divide the twelve gallons of water equally so that two of the three buckets have exactly 6 gallons of water in them? I and my nephew spent a good deal of time trying to solve it and ultimately gave up. I remembered then that I have seen a programmatic solution to a similar puzzle being worked out in the “Functional Programming Principles in Scala” Coursera course by Martin Odersky. This is the gist to the solution completely copied from the course: package bucketcase class Pouring(capacity: Vector[Int], initialState: Vector[Int]){ type State = Vector[Int] trait Move { def change(state: State): State } case class Pour(from: Int, to: Int) extends Move { def change(state: State) = { val amount = state(from) min (capacity(to) - state(to)) state updated (from, state(from) - amount) updated (to, state(to) + amount) } } class Path(history: List[Move], val endState: State) { def extend(move: Move) = new Path(move :: history, move change endState) override def toString = (history.reverse mkString " ") + "-->" + endState } val glasses = 0 until capacity.length val moves = for { from ...
agile-logo

The New Agile–Why Is Agile So Popular?

Is it the cool name? Is it the actual successes? Is it the drawings with lots of loops in them? Might be all, but above all else, there are the perceived (and maybe the not actual) value of agile, that organizations want. Let’s look at those:    Reduced waste – When Lean was given its name, it was a genius marketing decision. Lean creates the concept of “do less with more” that executives like so much. Organizations today are so occupied with mitigating risk (much more than innovation), that cutting costs seems as the path to survival. Reducing waste helps cut costs, everybody knows that. Sometimes companies forget that in order to eliminate waste you need to invest in continuous improvement, which is no small investment. But remember, we’re talking about perceived attraction, not what really happens the day after. Increased Speed – Agile reduces time to market. How can it do this magic without raising speed, or how do you guys call it, “velocity”? Agile makes it seem that we can turn the big ship quickly, and leap 500 miles in a single jump. Much like the old days, the investment and commitment in getting there are ignored at that point. Speed however, can now be measured, because Velocity! So we can target velocity and see how we can increase it! That’s where the pressure from management increases and teams begin gaming the system and all kinds of horrible things happen. But hey, that’s the implementer’s problem. Improved Productivity – the vague sister of speed. Everybody wants to be more productive, but no one actually has found a way to measure productivity effectively. Truth is, productivity does not matter that much, it’s more about effectiveness. We can build the wrong product very quickly, but then we’re neither productive or effective. Still to the naked eye and ear, it’s one of agile’s perceived wins. Improved Decision Making – This is where the wisdom of the crowds wins. If everyone is doing agile, that must be the right thing to do. If successful organizations are going agile, they made some great decisions, and apparently agile helped them, because they improved. We want that too! Note that this is a correlation, not causation, yes? But let’s not let that confuse us. The aura of wisdom is not just good for political reasons inside the organization. It also looks attractive to people pursuing careers have probably heard the same about agile, and with this aura, an organization will attract better applicants. Improved Confidence – An agile organization can pivot any time due to agility. Like we already know from the last point, it makes the best decisions, can change them upon failure, and react quickly to changing conditions. That oozes of confidence. You can only make bold decisions with agility. So agile organizations seem able to make bold decisions, and we like this kind of leadership, don’t we? The one that doesn’t hesitate.  We like winners and agile smells like winning. Improved trust and safety – We’re now going deeper, as we’ve moved from P&L realm to people in the organization. Self organizing teams must have trust in each other, and management in them. People want to work in a high-trust environment. People want to be able to fail and learn, and not get beaten with sticks when they do fail. Trust and safety are inferred values, rather than perceived directly. They are great attractors to talents. But caveat emptor: This inference should be checked if it’s real, before jumping ship to a so called agile organization.For the last 15 years, Agile rose to be the method of choice, because it was attractive. With certifications, it was also supported by stable business methodology of managing talent. As you can see, nobody would want something else. But enough cynicism (at least for now), after all that’s the old agile. In the next installments, we’ll dig deeper into actual progress within agile organizations, and what it means to the future of organization work.Reference: The New Agile–Why Is Agile So Popular? from our JCG partner Gil Zilberfeld at the Geek Out of Water blog....
spring-interview-questions-answers

Exposing HTTP Restful API with Inbound Adapters. Part 1 (XML)

1. Introduction The purpose of this post is to implement an HTTP Restful API using Spring Integration HTTP inbound adapters. This tutorial is divided into two parts:              XML configuration example (this same post). Java DSL example. This will be explained in the next part of this tutorial, showing how to configure the application using Spring Integration Java DSL, with examples with both Java 7 and Java 8.Before looking at the code, let’s take a glance at the following diagram, which shows the different services exposed by the application:GET operations are handled by an HTTP inbound gateway, while the rest (PUT, POST and DELETE) are handled by HTTP inbound channel adapters, since no response body is sent back to the client. Each operation will be explained in the following sections:Introduction Application configuration Get operation Put and post operations Delete operation ConclusionThe source code is available at Github. 2. Application configuration The web.xml file contains the definition of the Dispatcher Servlet: <servlet> <servlet-name>springServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:xpadro/spring/integration/configuration/http-inbound-config.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springServlet</servlet-name> <url-pattern>/spring/*</url-pattern> </servlet-mapping> The http-inbound-config.xml file will be explained in the following sections. The pom.xml file is detailed below. It is important to note the jackson libraries. Since we will be using JSON to represent our resources, these libraries must be present in the class path. Otherwise, the framework won’t register the required converter. <properties> <spring-version>4.1.3.RELEASE</spring-version> <spring-integration-version>4.1.0.RELEASE</spring-integration-version> <slf4j-version>1.7.5</slf4j-version> <junit-version>4.9</junit-version> <jackson-version>2.3.0</jackson-version> </properties><dependencies> <!-- Spring Framework - Core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring-version}</version> </dependency> <!-- Spring Framework - Integration --> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-core</artifactId> <version>${spring-integration-version}</version> </dependency> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-http</artifactId> <version>${spring-integration-version}</version> </dependency> <!-- JSON --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson-version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson-version}</version> </dependency> <!-- Testing --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit-version}</version> <scope>test</scope> </dependency> <!-- Logging --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j-version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j-version}</version> </dependency> </dependencies> 3. Get operation The configuration of the flow is shown below: http-inbound-config.xml The gateway receives requests to this path: /persons/{personId}. Once a request has arrived, a message is created and sent to httpGetChannel channel. The gateway will then wait for a service activator (personEndpoint) to return a response:Now, some points need to be explained:supported-methods: this attribute indicates which methods are supported by the gateway (only GET requests). payload-expression: What we are doing here is getting the value from personId variable in the URI template and putting it in the message’s payload. For example, the request path ‘/persons/3’ will become a Message with a value ‘3’ as its payload. request-mapping: We can include this element to specify several attributes and filter which requests will be mapped to the gateway. In the example, only requests that contain the value ‘application/json’ for Content-Type header (consumes attribute) and Accept header (produces attribute) will be handled by this gateway.Once a request is mapped to this gateway, a message is built and sent to the service activator. In the example, we defined a simple bean that will get the required information from a service: @Component public class PersonEndpoint { private static final String STATUSCODE_HEADER = "http_statusCode"; @Autowired private PersonService service; public Message<?> get(Message<String> msg) { long id = Long.valueOf(msg.getPayload()); ServerPerson person = service.getPerson(id); if (person == null) { return MessageBuilder.fromMessage(msg) .copyHeadersIfAbsent(msg.getHeaders()) .setHeader(STATUSCODE_HEADER, HttpStatus.NOT_FOUND) .build(); } return MessageBuilder.withPayload(person) .copyHeadersIfAbsent(msg.getHeaders()) .setHeader(STATUSCODE_HEADER, HttpStatus.OK) .build(); } //Other operations } Depending on the response received from the service, we will return the requested person or a status code indicating that no person was found. Now we will test that everything works as expected. First, we define a ClientPerson class to which the response will be converted: @JsonIgnoreProperties(ignoreUnknown = true) public class ClientPerson implements Serializable { private static final long serialVersionUID = 1L; @JsonProperty("id") private int myId; private String name; public ClientPerson() {} public ClientPerson(int id, String name) { this.myId = id; this.name = name; } //Getters and setters } Then we implement the test. The buildHeaders method is where we specify Accept and Content-Type headers. Remember that we restricted requests with ‘application/json’ values in those headers. @RunWith(BlockJUnit4ClassRunner.class) public class GetOperationsTest { private static final String URL = "http://localhost:8081/int-http-xml/spring/persons/{personId}"; private final RestTemplate restTemplate = new RestTemplate(); private HttpHeaders buildHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); headers.setContentType(MediaType.APPLICATION_JSON); return headers; } @Test public void getResource_responseIsConvertedToPerson() { HttpEntity<Integer> entity = new HttpEntity<>(buildHeaders()); ResponseEntity<ClientPerson> response = restTemplate.exchange(URL, HttpMethod.GET, entity, ClientPerson.class, 1); assertEquals("John" , response.getBody().getName()); assertEquals(HttpStatus.OK, response.getStatusCode()); } @Test public void getResource_responseIsReceivedAsJson() { HttpEntity<Integer> entity = new HttpEntity<>(buildHeaders()); ResponseEntity<String> response = restTemplate.exchange(URL, HttpMethod.GET, entity, String.class, 1); assertEquals("{\"id\":1,\"name\":\"John\",\"age\":25}", response.getBody()); assertEquals(HttpStatus.OK, response.getStatusCode()); } @Test(expected=HttpClientErrorException.class) public void getResource_sendXml_415errorReturned() { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); headers.setContentType(MediaType.APPLICATION_XML); HttpEntity<Integer> entity = new HttpEntity<>(headers); restTemplate.exchange(URL, HttpMethod.GET, entity, ClientPerson.class, 1); } @Test(expected=HttpClientErrorException.class) public void getResource_expectXml_receiveJson_406errorReturned() { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML)); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<Integer> entity = new HttpEntity<>(headers); restTemplate.exchange(URL, HttpMethod.GET, entity, ClientPerson.class, 1); } @Test(expected=HttpClientErrorException.class) public void getResource_resourceNotFound_404errorReturned() { HttpEntity<Integer> entity = new HttpEntity<>(buildHeaders()); restTemplate.exchange(URL, HttpMethod.GET, entity, ClientPerson.class, 8); } } Not specifying a correct value in the Content-Type header will result in a 415 Unsupported Media Type error, since the gateway does not support this media type. On the other hand, specifying an incorrect value in the Accept header will result in a 406 Not Acceptable error, since the gateway is returning another type of content than the expected. 4. Put and post operations For PUT and POST operations, we are using the same HTTP inbound channel adapter, taking advantage of the possibility to define several paths and methods to it. Once a request arrives, a router will be responsible to delivering the message to the correct endpoint. http-inbound-config.xml <int-http:inbound-channel-adapter channel="routeRequest" status-code-expression="T(org.springframework.http.HttpStatus).NO_CONTENT" supported-methods="POST, PUT" path="/persons, /persons/{personId}" request-payload-type="xpadro.spring.integration.server.model.ServerPerson"> <int-http:request-mapping consumes="application/json"/> </int-http:inbound-channel-adapter><int:router input-channel="routeRequest" expression="headers.http_requestMethod"> <int:mapping value="PUT" channel="httpPutChannel"/> <int:mapping value="POST" channel="httpPostChannel"/> </int:router><int:service-activator ref="personEndpoint" method="put" input-channel="httpPutChannel"/> <int:service-activator ref="personEndpoint" method="post" input-channel="httpPostChannel"/> This channel adapter includes two new attributes:status-code-expression: By default, the channel adapter acknowledges that the request has been received and returns a 200 status code. If we want to override this behavior, we can specify a different status code in this attribute. Here, we specify that these operations will return a 204 No Content status code. request-payload-type: This attribute specifies what class will the request body be converted to. If we do not define it, it will not be able to convert to the class that the service activator is expecting (ServerPerson).When a request is received, the adapter sends it to the routeRequest channel, where a router is expecting it. This router will inspect the message headers and depending on the value of the ‘http_requestMethod’ header, it will deliver it to the appropriate endpoint. Both PUT and POST operations are handled by the same bean: @Component public class PersonEndpoint { @Autowired private PersonService service; //Get operation public void put(Message<ServerPerson> msg) { service.updatePerson(msg.getPayload()); } public void post(Message<ServerPerson> msg) { service.insertPerson(msg.getPayload()); } } Return type is void because no response is expected; the inbound adapter will handle the return of the status code. PutOperationsTest validates that the correct status code is returned and that the resource has been updated: @RunWith(BlockJUnit4ClassRunner.class) public class PutOperationsTest { private static final String URL = "http://localhost:8081/int-http-xml/spring/persons/{personId}"; private final RestTemplate restTemplate = new RestTemplate(); //build headers method @Test public void updateResource_noContentStatusCodeReturned() { HttpEntity<Integer> getEntity = new HttpEntity<>(buildHeaders()); ResponseEntity<ClientPerson> response = restTemplate.exchange(URL, HttpMethod.GET, getEntity, ClientPerson.class, 4); ClientPerson person = response.getBody(); person.setName("Sandra"); HttpEntity<ClientPerson> putEntity = new HttpEntity<ClientPerson>(person, buildHeaders()); response = restTemplate.exchange(URL, HttpMethod.PUT, putEntity, ClientPerson.class, 4); assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); response = restTemplate.exchange(URL, HttpMethod.GET, getEntity, ClientPerson.class, 4); person = response.getBody(); assertEquals("Sandra", person.getName()); } } PostOperationsTest validates that the new resource has been added: @RunWith(BlockJUnit4ClassRunner.class) public class PostOperationsTest { private static final String POST_URL = "http://localhost:8081/int-http-xml/spring/persons"; private static final String GET_URL = "http://localhost:8081/int-http-xml/spring/persons/{personId}"; private final RestTemplate restTemplate = new RestTemplate(); //build headers method @Test public void addResource_noContentStatusCodeReturned() { ClientPerson person = new ClientPerson(9, "Jana"); HttpEntity<ClientPerson> entity = new HttpEntity<ClientPerson>(person, buildHeaders()); ResponseEntity<ClientPerson> response = restTemplate.exchange(POST_URL, HttpMethod.POST, entity, ClientPerson.class); assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); HttpEntity<Integer> getEntity = new HttpEntity<>(buildHeaders()); response = restTemplate.exchange(GET_URL, HttpMethod.GET, getEntity, ClientPerson.class, 9); person = response.getBody(); assertEquals("Jana", person.getName()); } } 5. Delete operation The last operation of our restful API is the delete operation. This time we use a single channel adapter for this purpose: <int-http:inbound-channel-adapter channel="httpDeleteChannel" status-code-expression="T(org.springframework.http.HttpStatus).NO_CONTENT" supported-methods="DELETE" path="/persons/{personId}" payload-expression="#pathVariables.personId"> <int-http:request-mapping consumes="application/json"/> </int-http:inbound-channel-adapter><int:service-activator ref="personEndpoint" method="delete" input-channel="httpDeleteChannel"/> The channel adapter lets us define the returning status code and we are using the payload-expression attribute to map the requested personId to the message body. The configuration is a little bit different from  those in previous operations but there’s nothing not already explained here. The service activator, our person endpoint, will request the person service to delete this resource. public void delete(Message<String> msg) { long id = Long.valueOf(msg.getPayload()); service.deletePerson(id); } Finally, the required test: @RunWith(BlockJUnit4ClassRunner.class) public class DeleteOperationsTest { private static final String URL = "http://localhost:8081/int-http-xml/spring/persons/{personId}"; private final RestTemplate restTemplate = new RestTemplate(); //build headers method @Test public void deleteResource_noContentStatusCodeReturned() { HttpEntity<Integer> entity = new HttpEntity<>(buildHeaders()); ResponseEntity<ClientPerson> response = restTemplate.exchange(URL, HttpMethod.DELETE, entity, ClientPerson.class, 3); assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); try { response = restTemplate.exchange(URL, HttpMethod.GET, entity, ClientPerson.class, 3); Assert.fail("404 error expected"); } catch (HttpClientErrorException e) { assertEquals(HttpStatus.NOT_FOUND, e.getStatusCode()); } } } 6. Conclusion This post has been an introduction to our application in order to understand how it is structured from a known point of view (xml configuration). In the next part of this tutorial, we are going to implement this same application using Java DSL. The application will be configured to run with Java 8, but when lambdas are used, I will also show how it can be done with Java 7. I’m publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.Reference: Exposing HTTP Restful API with Inbound Adapters. Part 1 (XML) from our JCG partner Xavier Padro at the Xavier Padró’s Blog blog....
software-development-2-logo

You Do Need Independent Technical Reviews!

Do you have a team of brilliant and enthusiastic programmers? Of course! You’ve carefully chosen them from a hundred candidates! Are they passionate about the product? Absolutely! They use cutting-edge technologies, never sleep, and hardly eat or drink anything except coffee! Do they believe in your business success? No doubts about it; they live and breathe all those features, releases, continuous delivery, user experience, etc. Are you sure they are developing the product correctly? Well, yes, you’re pretty sure; why wouldn’t they? … Does this sound familiar? I can’t count how many times I’ve heard these stories told by startup founders. Most of them are in love with their teams … until that day when it’s time to hire a new one. There could be many possible reasons for such a fiasco, but one of them is a lack of regular, systematic, and independent technical reviews. Nothing demotivates a development team more than a lack of attention to their deliverables. On the other hand, a regular reconciliation of their results and your quality expectations is one of the key factors that will guarantee technical success for your startup. Below I summarize my experience with organizing such technical reviews. An independent review is when you ask someone outside of your team to look at your source code and other technical resources and give you an objective opinion about them. Every modern software team should also use internal code reviews, which is is something else entirely. An internal review occurs when one programmer shows his code to other peers on the team and asks their opinion. This usually happens as a daily activity and has nothing to do with independent reviews. An independent review is performed by a programmer who knows nothing about your team. He comes on board, checks out the code from your repository, spends a few hours (or days) looking at it and trying to understand what it does. Then, he tells you what is wrong and where. He explains how he would do it better, where he would change it, and what he would do instead. Then, you pay him and he leaves. You may never see him again, but his conclusions and suggestions help you check the reality of your code and evaluate how your team is really doing. We, at teamed.io, do independent reviews with every project of ours, and this is a list of principles we use: Make Independent Reviews Systematic. This is the first and most important rule — organize such technical reviews regularly. Moreover, inform your team about the schedule, and let them be prepared for the reviews. Once a month is a good practice, according to my experience. Depending on your source code size, a full review should take from two to eight hours. Don’t spend more than eight hours; there is no point in going too deep into the code during independent reviews. Pay for Bugs Found. We always pay for bugs, not for the time spent finding them. We ask our reviewers to look at the code and report as many bugs as we think we need. For each bug, we pay 15 minutes for their time. In other words, we assume that a good reviewer can find and report approximately four problems in one hour. For example, a reviewer charges $150 per hour. We hire him and ask him to find and report the 20 most criticial issues he can discover. Our estimate is that he should spend five hours on this work. Thus, he will get $750 when we have 20 bugs in our tracking system reported by him. If he finds fewer, he gets proportionally less money. This payment schedule will help you focus your reviewer on the main objective of the review process — finding and reporting issues. There are no other goals. The only thing you’re interested in is knowing what the issues with your current technical solution are. That’s what you’re paying for. Hire the Best and Pay Well. My experience tells me that the position of an independent reviewer is a very important one. He is not just a programmer but more of an architect who is capable of looking at the solution from a very high level of abstraction, while at the same time paying a lot of attention to details; he should be very good at designing similar systems; he should know how to report a bug correctly and with enough detail; he should understand your business domain; etc. Besides all that, he should be well motivated to help you. You’re not hiring him for full-time work but rather just for a few-hour gig. My advice is to try to get the best guys, and pay them as much as they ask, usually over $100 per hour. Don’t negotiate, just pay. It’s just a few hundred dollars for you, but the effect of their contribution will be huge. Ask For and Expect Criticism. It is a very common mistake to ask a reviewer, “Do you like our code?” Don’t expect him to tell you how great your code is. This is not what you’re paying him for! You already have a full team of programmers for cheering you up; they can tell you a lot about the code they are creating and how awesome it is. You don’t want to hear this again from the reviewer. Instead, you want to know what is wrong and needs to be fixed. So your questions should sound like, “What problems do you think we should fix first?” Some reviewers will try to please you with positive comments, but ignore that flattery and bring them back to the main goal — bugs. The payment schedule explained above should help. Regularly Change Reviewers. Try not to use the same reviewer more than once on the same project (I mean the same code base). I believe the reason here is obvious, but let me re-iterate: You don’t need your reviewer to be nice to you and tell you how great your code is. You want him to be objective and focused on problems, not on bright sides. If you hire the same person again and again, psychologically you make him engaged to the source code. He’s seen it once; now he has to see it again. He already told you about some problem, and now he has to repeat it again. He won’t feel comfortable doing it. Instead, he will start feeling like a member of the team and will feel responsible for the source code and its mistakes. He, as any other team member, will start hiding issues instead of revealing them. Thus, for every independent technical review, get a new person. Be Polite and Honest With Your Team. Independent reviews can be rather offensive to your programmers. They may think that you don’t trust them. They may feel that you don’t respect them as technical specialists. They may even decide that you’re getting ready to fire them all and are currently looking for new people. This is a very possible and very destructive side effect of an independent review. How do you avoid it? I can’t give you universal advice, but the best suggestion I can give is this: be honest with them. Tell them that the quality of the product is critical for you and your business. Explain to them that the business is paying them for their work and that in order to keep paychecks coming, you have to stress quality control — regularly, objectively, independently, and honestly. In the end, if you manage to organize reviews as this article explains, the team will be very thankful to you. They will gain a lot of new ideas and thoughts from every review and will ask you to repeat them regularly. Review From Day One. Don’t wait until the end of the project! I’ve seen this mistake many times. Very often startup founders think that until the product is done and ready for the market, they shouldn’t distract their team. They think they should let the team work toward project milestones and take care of quality later, “when we have a million visitors per day”. This day will never come if you let your team run without control! Start conducting independent reviews from the moment your Git repository has its first file. Until the repository is big enough, you may only spend $300 once a month to receive an objective, independent opinion about its quality. Will this ruin your budget? Prohibit Discussions, and Ask for Formal Reporting. Don’t let your reviewers talk to the team. If you do, the entire idea of a review being independent falls apart. If a reviewer is able to ask informal questions and discuss your system design with your programmers, their answers will satisfy him, and he will move on. But you, the owner of the business, will stay exactly where you were before the review. The point of the review is not to make the reviewer happy. It is exactly the opposite. You want to make him confused! If he is confused, your design is wrong and he feels the need to report a bug. The source code should speak for itself, and it should be easy enough for a stranger (the reviewer) to understand how it works. If this is not the case, there is something wrong that should be fixed. Treat Any Question as a Bug. Don’t expect a review to produce any bugs in functionality, like “I click this button and the system crashes”. This will happen rarely, if ever. Your team is very good at discovering these issues and fixing them. Independent reviews are not about that kind of bugs. The main goal of an independent review is to discover bugs in the architecture and design. Your product may work, but its architecture may have serious design flaws that won’t allow you, for example, to handle exponential growth in web traffic. An independent reviewer will help you find those flaws and address them sooner than later. In order to get bugs of that kind from the reviewer, you should encourage him to report anything he doesn’t like — unmotivated use of a technology, lack of documentation, unclear purpose of a file, absence of a unit test, etc. Remember, the reviewer is not a member of your team and has his own ideas about the technologies you’re using and software development in general. You’re interested in matching his vision with your team’s. Then, you’re interested in fixing all critical mismatches. Review Everything, Not Just Source Code. Let your reviewer look at all technical resources you have, not just source code files (.java, .rb, .php, etc.) Give him access to the database schema, continuous integration panel, build environment, issue tracking system, plans and schedules, work agendas, uptime reports, deployment pipeline, production logs, customer bug reports, statistics, etc. Everything that could help him understand how your system works, and more importantly, where and how it breaks, is very useful. Don’t limit the reviewer to the source code only — this is simply not enough! Let him see the big picture, and you will get a much more detailed and professional report. Track How Inconsistencies Are Resolved. Once you get a report from the reviewer, make sure that the most important issues immediately get into your team’s backlog. Then, make sure they are addressed and closed. That doesn’t mean you should fix them all and listen to everything said by the reviewer. Definitely not! Your architect runs the show, not the reviewer. Your architect should decide what is right and what is wrong in the technical implementation of the product. But it’s important to make him resolve all concerns raised by the reviewer. Very often you will get answers like these from him: “We don’t care about it now”, “we won’t fix it until the next release”, or “he is wrong; we’re doing it better”. These answers are perfectly valid, but they have to be given (reviewers are people and they also make mistakes). The answers will help you, the founder, understand what your team is doing and how well they understand their business.Reference: You Do Need Independent Technical Reviews! from our JCG partner Yegor Bugayenko at the About Programming blog....
software-development-2-logo

Why I Won’t Accept ANY Magic Number

One of the first things I like to establish in a new project is the use of tools like Checkstyle and Findbugs in order to codify some code guidelines and to avoid bugs that can be determined by static code analysis. Sooner or later with these tools one stumbles over a case where people have the feeling it is going to far. One such case is the check for Magic Numbers of Checkstyle. It will warn about any use of numeric literals except -1, 0, 1 and 2 that aren’t used to define a constant. Many developers have a problem with this check as one can see from the resulting code. I have seen code like this:   private static final int FOUR = 4; and also private static final int FOUR = 5; and my all time favorite (I’m not making this up!): firstname = rs.getString(1); lastname = rs.getString(2); city = rs.getString(2 + 1); zip = rs.getString(2 + 2); country = rs.getString(2 + 2 + 1); But there is a different case where the discussion comes up. It’s with obvious constants like 100 for converting fractions into percent values or 1024 for conversion between bytes and kibibytes. Some argue these aren’t magic numbers (or magic numbers but not as bad) because their meaning is obvious and they won’t change. I disagree and will vote to make them constants any time. Here is why:The meaning is NOT obvious. What does value * 100 mean? Is a fraction converted to percent? Is a length measured in meters, converted to centimeters? Or something multiplied by a rough approximation of g*g with g being the gravitational acceleration on earth? Or maybe I’m multiplying something with the size of an array, that happens to be 100. Can’t tell. A simple constant with a proper name will fix that. Ok, I do agree, many of these constants won’t change. But the purpose of defining constants (or methods, or classes) is not (only) to enable later change, but to make reading, understanding and reasoning more easy. So the question if a value might change in the future is completely irrelevant. (This one is the argument that I’m missing in most of the discussions) I just don’t want to think about it or have others think about it. I have seen dozens, probably hundreds of instances, where a properly named constant would have helped tremendously understanding a piece of code. And I have seen very few cases where it might have hurt readability and not a single one where it hurt badly. Therefore: just extract a constant and be done with it.Note: Just because it is a constant doesn’t mean it has to be public, or even a class level field. If it is used only in a single method a local variable is just fine.Reference: Why I Won’t Accept ANY Magic Number from our JCG partner Jens Schauder at the Schauderhaft blog....
java-logo

Looking into the Java 9 Money and Currency API (JSR 354)

JSR 354 defines a new Java API for working with Money and Currencies, which is planned to be included in Java 9. In this post we will look at the current state of the reference implementation: JavaMoney. Like my post about the Java 8 Date/Time API this post will be mainly driven by code that shows the new API. But before we start, I want to quote a short section from the specification that pretty much sums up the motivation for this new API:   Monetary values are a key feature of many applications, yet the JDK provides little or no support. The existing java.util.Currency class is strictly a structure used for representing current ISO 4217 currencies, but not associated values or custom currencies. The JDK also provides no support for monetary arithmetic or currency conversion, nor for a standard value type to represent a monetary amount. If you use Maven, you can easily try the current state of the reference implementation by adding the following dependency to your project: <dependency>   <groupId>org.javamoney</groupId>   <artifactId>moneta</artifactId>   <version>0.9</version> </dependency> All specification classes and interfaces are located in the javax.money.* package. We will start with the two core interfaces CurrencyUnit and MonetaryAmount. After that, we will look into exchange rates, currency conversion and formatting. CurrencyUnit and MonetaryAmount CurrencyUnit models a currency. CurrencyUnit is very similar to the existing java.util.Currency class, except it allows custom implementations. According to the specification it should be possible that java.util.Currency implements CurrencyUnit. CurrencyUnit instances can be obtained using the MonetaryCurrencies factory: // getting CurrencyUnits by currency code CurrencyUnit euro = MonetaryCurrencies.getCurrency("EUR"); CurrencyUnit usDollar = MonetaryCurrencies.getCurrency("USD");// getting CurrencyUnits by locale CurrencyUnit yen = MonetaryCurrencies.getCurrency(Locale.JAPAN); CurrencyUnit canadianDollar = MonetaryCurrencies.getCurrency(Locale.CANADA); MontetaryAmount represents a concrete numeric representation of a monetary amount. A MonetaryAmount is always bound to a CurrencyUnit. Like CurrencyUnit, MonetaryAmount is an interface that supports different implementations. CurrencyUnit and MonetaryAmount implementations must be immutable, thread safe, serializable and comparable. // get MonetaryAmount from CurrencyUnit CurrencyUnit euro = MonetaryCurrencies.getCurrency("EUR"); MonetaryAmount fiveEuro = Money.of(5, euro);// get MonetaryAmount from currency code MonetaryAmount tenUsDollar = Money.of(10, "USD");// FastMoney is an alternative MonetaryAmount factory that focuses on performance MonetaryAmount sevenEuro = FastMoney.of(7, euro); Money and FastMoney are two MonetaryAmount implementations of JavaMoney. Money is the default implementation that stores number values using BigDecimal. FastMoney is an alternative implementation which stores amounts in long fields. According to the documentation  operations on FastMoney are 10-15 times faster compared to Money. However, FastMoney is limited by the size and precision of the long type. Please note that Money and FastMoney are implementation specific classes (located in org.javamoney.moneta.* instead of javax.money.*). If you want to avoid implementation specific classes, you have to obtain a MonetaryAmountFactory to create a MonetaryAmount instance: MonetaryAmount specAmount = MonetaryAmounts.getDefaultAmountFactory()     .setNumber(123.45)     .setCurrency("USD")     .create(); Two MontetaryAmount instances are considered equal if the implementation classes, the currency units and the numeric values are equal: MonetaryAmount oneEuro = Money.of(1, MonetaryCurrencies.getCurrency("EUR")); boolean isEqual = oneEuro.equals(Money.of(1, "EUR")); // true boolean isEqualFast = oneEuro.equals(FastMoney.of(1, "EUR")); // false MonetaryAmount has various methods that allow accessing the assigned currency, the numeric amount, its precision and more: MonetaryAmount monetaryAmount = Money.of(123.45, euro); CurrencyUnit currency = monetaryAmount.getCurrency(); NumberValue numberValue = monetaryAmount.getNumber();int intValue = numberValue.intValue(); // 123 double doubleValue = numberValue.doubleValue(); // 123.45 long fractionDenominator = numberValue.getAmountFractionDenominator(); // 100 long fractionNumerator = numberValue.getAmountFractionNumerator(); // 45 int precision = numberValue.getPrecision(); // 5// NumberValue extends java.lang.Number.  // So we assign numberValue to a variable of type Number Number number = numberValue; Working with MonetaryAmounts Mathematical operations can be performed with MonetaryAmount: MonetaryAmount twelveEuro = fiveEuro.add(sevenEuro); // "EUR 12" MonetaryAmount twoEuro = sevenEuro.subtract(fiveEuro); // "EUR 2" MonetaryAmount sevenPointFiveEuro = fiveEuro.multiply(1.5); // "EUR 7.5"// MonetaryAmount can have a negative NumberValue MonetaryAmount minusTwoEuro = fiveEuro.subtract(sevenEuro); // "EUR -2"// some useful utility methods boolean greaterThan = sevenEuro.isGreaterThan(fiveEuro); // true boolean positive = sevenEuro.isPositive(); // true boolean zero = sevenEuro.isZero(); // false// Note that MonetaryAmounts need to have the same CurrencyUnit to do mathematical operations // this fails with: javax.money.MonetaryException: Currency mismatch: EUR/USD fiveEuro.add(tenUsDollar); Rounding is another important part when working with money. MonetaryAmounts can be rounded using a rounding operator: CurrencyUnit usd = MonetaryCurrencies.getCurrency("USD"); MonetaryAmount dollars = Money.of(12.34567, usd); MonetaryOperator roundingOperator = MonetaryRoundings.getRounding(usd); MonetaryAmount roundedDollars = dollars.with(roundingOperator); // USD 12.35 Here 12.3456 US Dollars are rounded with the default rounding for this currency. When working with collections of MonetaryAmounts, some nice utility methods for filtering, sorting and grouping are available. These methods can be used together with the Java 8 Stream API. Consider the following collection: List<MonetaryAmount> amounts = new ArrayList<>(); amounts.add(Money.of(2, "EUR")); amounts.add(Money.of(42, "USD")); amounts.add(Money.of(7, "USD")); amounts.add(Money.of(13.37, "JPY")); amounts.add(Money.of(18, "USD")); We can now filter amounts by CurrencyUnit: CurrencyUnit yen = MonetaryCurrencies.getCurrency("JPY"); CurrencyUnit dollar = MonetaryCurrencies.getCurrency("USD");// filter by currency, get only dollars // result is [USD 18, USD 7, USD 42] List<MonetaryAmount> onlyDollar = amounts.stream()     .filter(MonetaryFunctions.isCurrency(dollar))     .collect(Collectors.toList());// filter by currency, get only dollars and yen // [USD 18, USD 7, JPY 13.37, USD 42] List<MonetaryAmount> onlyDollarAndYen = amounts.stream()     .filter(MonetaryFunctions.isCurrency(dollar, yen))     .collect(Collectors.toList()); We can also filter out MonetaryAmounts smaller or greater than a specific threshold: MonetaryAmount tenDollar = Money.of(10, dollar);// [USD 42, USD 18] List<MonetaryAmount> greaterThanTenDollar = amounts.stream()     .filter(MonetaryFunctions.isCurrency(dollar))     .filter(MonetaryFunctions.isGreaterThan(tenDollar))     .collect(Collectors.toList()); Sorting works in a similar way: // Sorting dollar values by number value // [USD 7, USD 18, USD 42] List<MonetaryAmount> sortedByAmount = onlyDollar.stream()     .sorted(MonetaryFunctions.sortNumber())     .collect(Collectors.toList());// Sorting by CurrencyUnit // [EUR 2, JPY 13.37, USD 42, USD 7, USD 18] List<MonetaryAmount> sortedByCurrencyUnit = amounts.stream()     .sorted(MonetaryFunctions.sortCurrencyUnit())     .collect(Collectors.toList()); Grouping functions: // Grouping by CurrencyUnit // {USD=[USD 42, USD 7, USD 18], EUR=[EUR 2], JPY=[JPY 13.37]} Map<CurrencyUnit, List<MonetaryAmount>> groupedByCurrency = amounts.stream()     .collect(MonetaryFunctions.groupByCurrencyUnit());// Grouping by summarizing MonetaryAmounts Map<CurrencyUnit, MonetarySummaryStatistics> summary = amounts.stream()     .collect(MonetaryFunctions.groupBySummarizingMonetary()).get();// get summary for CurrencyUnit USD MonetarySummaryStatistics dollarSummary = summary.get(dollar); MonetaryAmount average = dollarSummary.getAverage(); // "USD 22.333333333333333333.." MonetaryAmount min = dollarSummary.getMin(); // "USD 7" MonetaryAmount max = dollarSummary.getMax(); // "USD 42" MonetaryAmount sum = dollarSummary.getSum(); // "USD 67" long count = dollarSummary.getCount(); // 3 MonetaryFunctions also provides reduction function that can be used to obtain the max, min and sum of a MonetaryAmount collection: List<MonetaryAmount> amounts = new ArrayList<>(); amounts.add(Money.of(10, "EUR")); amounts.add(Money.of(7.5, "EUR")); amounts.add(Money.of(12, "EUR"));Optional<MonetaryAmount> max = amounts.stream().reduce(MonetaryFunctions.max()); // "EUR 7.5" Optional<MonetaryAmount> min = amounts.stream().reduce(MonetaryFunctions.min()); // "EUR 12" Optional<MonetaryAmount> sum = amounts.stream().reduce(MonetaryFunctions.sum()); // "EUR 29.5" Custom MonetaryAmount operations MonetaryAmount provides a nice extension point called MonetaryOperator. MonetaryOperator is a functional interface that takes a MonetaryAmount as input and creates a new MonetaryAmount based on the input. // A monetary operator that returns 10% of the input MonetaryAmount // Implemented using Java 8 Lambdas MonetaryOperator tenPercentOperator = (MonetaryAmount amount) -> {   BigDecimal baseAmount = amount.getNumber().numberValue(BigDecimal.class);   BigDecimal tenPercent = baseAmount.multiply(new BigDecimal("0.1"));   return Money.of(tenPercent, amount.getCurrency()); };MonetaryAmount dollars = Money.of(12.34567, "USD");// apply tenPercentOperator to MonetaryAmount MonetaryAmount tenPercentDollars = dollars.with(tenPercentOperator); // USD 1.234567 Some standard API features are implemented as MonetaryOperator. For example, the rounding features we saw above are implemented as MonetaryOperator. Exchange rates Currency exchange rates can be obtained using an ExchangeRateProvider. JavaMoney comes with multiple different ExchangeRateProvider implementations. The two most important implementations are ECBCurrentRateProvider and IMFRateProvider. ECBCurrentRateProvider queries the European Central Bank (ECB) data feed for getting current exchange rates while IMFRateProvider uses International Monetary Fund (IMF) conversion rates. // get the default ExchangeRateProvider (CompoundRateProvider) ExchangeRateProvider exchangeRateProvider = MonetaryConversions.getExchangeRateProvider();// get the names of the default provider chain // [IDENT, ECB, IMF, ECB-HIST] List<String> defaultProviderChain = MonetaryConversions.getDefaultProviderChain();// get a specific ExchangeRateProvider (here ECB) ExchangeRateProvider ecbExchangeRateProvider = MonetaryConversions.getExchangeRateProvider("ECB"); If no specific ExchangeRateProvider is requested a CompoundRateProvider will be returned. CompoundRateProvider delegates exchange rate requests to a chain of ExchangeRateProviders and returns the result from the first provider that returns an adequate result. // get the exchange rate from euro to us dollar ExchangeRate rate = exchangeRateProvider.getExchangeRate("EUR", "USD");NumberValue factor = rate.getFactor(); // 1.2537 (at time writing) CurrencyUnit baseCurrency = rate.getBaseCurrency(); // EUR CurrencyUnit targetCurrency = rate.getCurrency(); // USD Currency conversion Conversion between currencies is be done with CurrencyConversions that can be obtained from ExchangeRateProviders: // get the CurrencyConversion from the default provider chain CurrencyConversion dollarConversion = MonetaryConversions.getConversion("USD");// get the CurrencyConversion from a specific provider CurrencyConversion ecbDollarConversion = ecbExchangeRateProvider.getCurrencyConversion("USD");MonetaryAmount tenEuro = Money.of(10, "EUR");// convert 10 euro to us dollar  MonetaryAmount inDollar = tenEuro.with(dollarConversion); // "USD 12.537" (at the time writing) Note that CurrencyConversion implements MonetaryOperator. Like other operators it can be applied using MonetaryAmount.with(). Formatting and parsing MonetaryAmounts can be parsed/formatted from/to string using a MonetaryAmountFormat: // formatting by locale specific formats MonetaryAmountFormat germanFormat = MonetaryFormats.getAmountFormat(Locale.GERMANY); MonetaryAmountFormat usFormat = MonetaryFormats.getAmountFormat(Locale.CANADA);MonetaryAmount amount = Money.of(12345.67, "USD");String usFormatted = usFormat.format(amount); // "USD12,345.67" String germanFormatted = germanFormat.format(amount); // 12.345,67 USD// A MonetaryAmountFormat can also be used to parse MonetaryAmounts from strings MonetaryAmount parsed = germanFormat.parse("12,4 USD"); With AmountFormatQueryBuilder custom formats can be created: // Creating a custom MonetaryAmountFormat MonetaryAmountFormat customFormat = MonetaryFormats.getAmountFormat(     AmountFormatQueryBuilder.of(Locale.US)         .set(CurrencyStyle.NAME)         .set("pattern", "00,00,00,00.00 ¤")         .build());// results in "00,01,23,45.67 US Dollar" String formatted = customFormat.format(amount); Note that the ¤ symbol (\u00A) is used as currency placeholder inside the pattern string. Summary We looked at many parts of the new Money and Currency API. The implementation already looks quite solid (but definitely needs some more documentation). I am looking forward to see this API in Java 9!You can find all the examples shown here on GitHub.Reference: Looking into the Java 9 Money and Currency API (JSR 354) from our JCG partner Michael Scharhag at the mscharhag, Programming and Stuff blog....
java-logo

How is Java / JVM built ? Adopt OpenJDK is your answer!

Introduction & history As some of you may already know, starting with Java 7, OpenJDK is the Reference Implementation (RI) to Java. The below timeline gives you an idea about the history of OpenJDK:          See Adopt OpenJDK – the past present and future [1] for some more details. If you have wondered about the JDK or JRE binaries that you download from vendors like Oracle, Red Hat, etcetera, then the clue is that these all stem from OpenJDK. Each vendor then adds some extra artefacts that are not open source yet due to security, proprietary or other reasons. What is OpenJDK made of ? OpenJDK is made up of a number of repositories, namely corba, hotspot, jaxp, jaxws, jdk, langtools, and nashorn. Between OpenjJDK8 and OpenJDK9 there have been no new repositories introduced, but lots of new changes and restructuring, primarily due to Jigsaw – the modularisation of Java itself [2] [3] [4] [5].  How has Java the language and platform built over the years ? Java is built by bootstrapping an older (previous) version of Java – i.e. Java is built using Java itself as its building block. Where older components are put together to create a new component which in the next phase becomes the building block. A good example of bootstrapping can be found at Scheme from Scratch [6] or even on Wikipedia [7]. OpenJDK8 [8] is compiled and built using JDK7, similarly OpenJDK9 [9] is compiled and built using JDK8. In theory OpenJDK8 can be compiled using the images created from OpenJDK8, similarly for OpenJDK9 using OpenJDK9. Using a process called bootcycle images – a JDK image of OpenJDK is created and then using the same image, OpenJDK is compiled again, which can be accomplished using a make command option: $ make bootcycle-images       # Build images twice, second time with newly built JDK make offers a number of options under OpenJDK8 and OpenJDK9, you can build individual components or modules by naming them, i.e. $ make [component-name] | [module-name] or even run multiple build processes in parallel, i.e. $ make JOBS=<n>                 # Run <n> parallel make jobs Finally install the built artefact using the install option, i.e. $ make install Some myths busted OpenJDK or Hotspot to be more specific isn’t completely written in C/C++, a good part of the code-base is good ‘ole Java (see the composition figure above). So you don’t have to be a hard-core developer to contribute to Open JDK. Even the underlying C/C++ code code-base isn’t scary or daunting to look at. For example here is an extract of a code snippet from vm/memory/universe.cpp in the HotSpotrepo – http://hg.openjdk.java.net/jdk6/jdk6/hotspot/raw-file/a541ca8fa0e3/src/share/vm/memory/universe.cpp [10]: . . . Universe::initialize_heap()if (UseParallelGC) { #ifndef SERIALGC Universe::_collectedHeap = new ParallelScavengeHeap(); #else // SERIALGC fatal("UseParallelGC not supported in this VM."); #endif // SERIALGC} else if (UseG1GC) { #ifndef SERIALGC G1CollectorPolicy* g1p = new G1CollectorPolicy(); G1CollectedHeap* g1h = new G1CollectedHeap(g1p); Universe::_collectedHeap = g1h; #else // SERIALGC fatal("UseG1GC not supported in java kernel vm."); #endif // SERIALGC} else { GenCollectorPolicy* gc_policy;if (UseSerialGC) { gc_policy = new MarkSweepPolicy(); } else if (UseConcMarkSweepGC) { #ifndef SERIALGC if (UseAdaptiveSizePolicy) { gc_policy = new ASConcurrentMarkSweepPolicy(); } else { gc_policy = new ConcurrentMarkSweepPolicy(); } #else // SERIALGC fatal("UseConcMarkSweepGC not supported in this VM."); #endif // SERIALGC } else { // default old generation gc_policy = new MarkSweepPolicy(); }Universe::_collectedHeap = new GenCollectedHeap(gc_policy); } . . . (please note that the above code snippet might have changed since published here) The things that appears clear from the above code-block are, we are looking at how pre-compiler notations are used to create Hotspot code that supports a certain type of GC i.e. Serial GC or Parallel GC. Also the type of GC policy is selected in the above code-block when one or more GC switches are toggled i.e. UseAdaptiveSizePolicy when enabled selects the Asynchronous Concurrent Mark and Sweep policy. In case of either Use Serial GC or Use Concurrent Mark Sweep GC are not selected, then the GC policy selected is Mark and Sweep policy. All of this and more is pretty clearly readable and verbose, and not just nicely formatted code that reads like English. Further commentary can be found in the section called Deep dive Hotspot stuff in the Adopt OpenJDK Intermediate & Advance experiences [11] document. Steps to build your own JDK or JRE Earlier we mentioned about JDK and JRE images – these are no longer only available to the big players in the Java world, you and I can build such images very easily. The steps for the process have been simplified, and for a quick start see the Adopt OpenJDK Getting Started Kit [12] and Adopt OpenJDK Intermediate & Advance experiences [11] documents. For detailed version of the same steps, please see the Adopt OpenJDK home page [13]. Basically building a JDK image from the OpenJDK code-base boils down to the below commands: (setup steps have been made brief and some commands omitted, see links above for exact steps) $ hg clone http://hg.openjdk.java.net/jdk8/jdk8 jdk8  (a)...OpenJDK8 or $ hg clone http://hg.openjdk.java.net/jdk9/jdk9 jdk9  (a)...OpenJDK9 $ ./get_sources.sh                                    (b) $ bash configure                                      (c) $ make clean images                                   (d) (setup steps have been made brief and some commands omitted, see links above for exact steps) To explain what is happening at each of the steps above: (a) We clone the openjdk mercurial repo just like we would using git clone …. (b) Once we have step (a) completed, we change into the folder created, and run the get_sources.sh command, which is equivalent to a git fetch or a git pull, since the step (a) only brings down base files and not all of the files and folders. (c) Here we run a script that checks for and creates the configuration needed to do the compile and build process (d) Once step (c) is success we perform a complete compile, build and create JDK and JRE images from the built artefacts As you can see these are dead-easy steps to follow to build an artefact or JDK/JRE images [step (a) needs to be run only once]. Benefitscontribute to the evolution and improvement of the Java the language & platform learn about the internals of the language and platform learn about the OS platform and other technologies whilst doing the above get involved in F/OSS projects stay on top the latest changes in the Java / JVM sphere knowledge and experience that helps professionally but also these are not readily available from other sources (i.e. books, training, work-experience, university courses, etcetera) advancement in career personal development (soft skills and networking)Contribute Join the Adopt OpenJDK [14] and Betterrev [15] projects and contribute by giving us feedback about everything Java including these projects. Join the Adoption Discuss mailing list and other OpenJDK related mailing lists to start with, these will keep you updated with latest progress and changes to OpenJDK. Fork any of the projects you see and submit changes via pull-requests. Thanks and support Adopt OpenJDK [14] and umbrella projects have been supported and progressed with help of JCP [21], the Openjdk team [22], JUGs like London Java Community [16], SouJava [17] and other JUGs in Brazil, a number of JUGs in Europe i.e. BGJUG (Bulgarian JUG) [18], BeJUG (Belgium JUG) [19], Macedonian JUG [20], and a number of other small JUGs. We hope in the coming time more JUGs and individuals would get involved. If you or your JUG wish to participate please get in touch.Reference: How is Java / JVM built ? Adopt OpenJDK is your answer! from our JCG partner Mani Sarkar at the Java Advent Calendar blog....
software-development-2-logo

A True SQL Gem You Didn’t Know Yet: The EVERY() Aggregate Function

We’ve just added support for the EVERY() aggregate function (#1391) to jOOQ, and would like to take the opportunity of letting you know of this true SQL gem that can come in handy EVERY(now and then) (pun intended). Let’s assume we have four books in our table:             INSERT INTO book VALUES (1, 1, '1984'); INSERT INTO book VALUES (2, 1, 'Animal Farm'); INSERT INTO book VALUES (3, 2, 'O Alquimista'); INSERT INTO book VALUES (4, 2, 'Brida'); Now the question is: Is EVERY() ID lower than 10? We’ll ask: SELECT EVERY(id < 10) FROM book And the answer is: every ----- true Does EVERY() book for each author end with the letter ‘a’? We’ll ask: SELECT author_id, EVERY(title LIKE '%a') FROM book GROUP BY author_id And the answer is: author_id every ----------------- 1 false 2 true Wonderful! As with all aggregate functions, we can even use them as a window function! SELECT book.*, EVERY(title LIKE '%a') OVER (PARTITION BY author_id) FROM book Which will produce: id author_id title every ------------------------------------ 1 1 1984 false 2 1 Animal Farm false 3 2 O Alquimista true 4 2 Brida true Who supports EVERY() Well, the SQL standard has it: 10.9 <aggregate function><aggregate function> ::= COUNT <left paren> <asterisk> <right paren> [ <filter clause> ] | <general set function> [ <filter clause> ] | <binary set function> [ <filter clause> ] | <ordered set function> [ <filter clause> ] | <array aggregate function> [ <filter clause> ]<general set function> ::= <set function type> <left paren> [ <set quantifier> ] <value expression> <right paren><set function type> ::= <computational operation><computational operation> ::= AVG | MAX | MIN | SUM | EVERY <-- yes, here! EVERY! | ANY | SOME | COUNT | STDDEV_POP | STDDEV_SAMP | VAR_SAMP | VAR_POP | COLLECT | FUSION | INTERSECTIONAnd, of course PostgreSQL! But if your database is not PostgreSQL, don’t worry. EVERY() can be emulated on EVERY() database using SUM() and CASE expressions. Here’s how to emulate the first query: -- SELECT EVERY(id < 10) -- FROM bookSELECT CASE SUM(CASE WHEN id < 10 THEN 0 ELSE 1 END) WHEN 0 THEN 1 ELSE 0 END FROM book; Or as window functions -- SELECT -- book.*, -- EVERY(title LIKE '%a') OVER (PARTITION BY author_id) -- FROM bookSELECT book.*, CASE SUM(CASE WHEN title LIKE '%a' THEN 0 ELSE 1 END) OVER(PARTITION BY author_id) WHEN 0 THEN 1 ELSE 0 END FROM book; And, as always on this blog, we’re happy to conclude that the upcoming jOOQ 3.6 will now handle EVERY(emulation) for you, so you can write: DSL.using(configuration) .select(BOOK.fields()) .select(every(BOOK.TITLE.like("%a")) .over(partitionBy(BOOK.AUTHOR_ID))) .from(BOOK) .fetch(); Have fun with this new function!Reference: A True SQL Gem You Didn’t Know Yet: The EVERY() Aggregate Function from our JCG partner Lukas Eder at the JAVA, SQL, AND JOOQ blog....
java-interview-questions-answers

Java EE Workflows on OpenShift (Tech Tip #64)

                       This webinar shows how create a Java EE workflow on OpenShift using WildFly, JBoss Tools, Forge, Arquillian, and OpenShift. Specifically it talks about:How a Java EE application can be easily developed using JBoss Developer Studio and deployed directly to OpenShift Set up Test and Production instances on OpenShift Enable Jenkins to provide Continuous Integration Run the tests on Test and push the WAR to ProductionMore detailed blog entries are at:Deployment Pipeline for Java EE 7 with WildFly, Arquillian, Jenkins, and OpenShift (Tech Tip #56) Arquillian tests on a WildFly instance hosted on OpenShift (Tech Tip #55) Java EE 7 Hands-on Lab on WildFly and OpenShift (Tech Tip #33) Getting Started with WildFly in OpenShift and JBoss Developer Studio (Tech Tip #21)And a lot more at blog.arungupta.me/tag/openshift/. Enjoy!Reference: Java EE Workflows on OpenShift (Tech Tip #64) from our JCG partner Arun Gupta at the Miles to go 2.0 … blog....
Java Code Geeks and all content copyright © 2010-2015, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close