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

Latest Articles - DZone

article thumbnail
Reading data from Google spreadsheet using JAVA
System Requirements: Eclipse Kepler Service Release 2 JDK 1.5 or above Installed Google App Engine SDK on eclipse – this is required for second version of this example. Create a google spreadsheet – login to your google account and create a new spreadsheet, if you want to read existing one then put that url in SPREADSHEET_URL. Once you create a new spreadsheet our url will be like – https://docs.google.com/spreadsheets/d/1L8xtAJfOObsXL-XemliUV10wkDHQNxjn6jKS4XwzYZ8/ but don’t put this url in SPREADSHEET_URL, Use the below url simply change the bold part. public static final String SPREADSHEET_URL = “https://spreadsheets.google.com/feeds/spreadsheets/1L8xtAJfOObsXL-XemliUV10wkDHQNxjn6jKS4XwzYZ8“; // Fill in google spreadsheet URI package org.gopaldas.readsps; import java.io.IOException; import java.net.URL; import com.google.gdata.client.spreadsheet.SpreadsheetService; import com.google.gdata.data.spreadsheet.ListEntry; import com.google.gdata.data.spreadsheet.ListFeed; import com.google.gdata.data.spreadsheet.SpreadsheetEntry; import com.google.gdata.data.spreadsheet.WorksheetEntry; import com.google.gdata.util.ServiceException; public class ReadSpreadsheet { public static final String GOOGLE_ACCOUNT_USERNAME = "[email protected]"; // Fill in google account username public static final String GOOGLE_ACCOUNT_PASSWORD = "xxxx"; // Fill in google account password public static final String SPREADSHEET_URL = "https://spreadsheets.google.com/feeds/spreadsheets/1L8xtAJfOObsXL-XemliUV10wkDHQNxjn6jKS4XwzYZ8"; //Fill in google spreadsheet URI public static void main(String[] args) throws IOException, ServiceException { /** Our view of Google Spreadsheets as an authenticated Google user. */ SpreadsheetService service = new SpreadsheetService("Print Google Spreadsheet Demo"); // Login and prompt the user to pick a sheet to use. service.setUserCredentials(GOOGLE_ACCOUNT_USERNAME, GOOGLE_ACCOUNT_PASSWORD); // Load sheet URL metafeedUrl = new URL(SPREADSHEET_URL); SpreadsheetEntry spreadsheet = service.getEntry(metafeedUrl, SpreadsheetEntry.class); URL listFeedUrl = ((WorksheetEntry) spreadsheet.getWorksheets().get(0)).getListFeedUrl(); // Print entries ListFeed feed = (ListFeed) service.getFeed(listFeedUrl, ListFeed.class); for(ListEntry entry : feed.getEntries()) { System.out.println("new row"); for(String tag : entry.getCustomElements().getTags()) { System.out.println(" "+tag + ": " + entry.getCustomElements().getValue(tag)); } } } }
April 29, 2014
by Gopal Das
· 39,963 Views
article thumbnail
Using Http Session With Spring Based Web Applications
There are multiple ways to get hold of and use an Http session with a Spring based web application. This is a summarization based on an experience with a recent project. Approach 1 Just inject in HttpSession where it is required. @Service public class ShoppingCartService { @Autowired private HttpSession httpSession; ... } Though surprising, since the service above is a singleton, this works well. Spring intelligently injects in a proxy to the actual HttpSession and this proxy knows how to internally delegate to the right session for the request. The catch with handling session this way though is that the object being retrieved and saved back in the session will have to be managed by the user: public void removeFromCart(long productId) { ShoppingCart shoppingCart = getShoppingCartInSession(); shoppingCart.removeItemFromCart(productId); updateCartInSession(shoppingCart); } Approach 2 Accept it as a parameter, this will work only in the web tier though: @Controller public class ShoppingCartController { @RequestMapping("/addToCart") public String addToCart(long productId, HttpSession httpSession) { //do something with the httpSession } } Approach 3 Create a bean and scope it to the session this way: @Component @Scope(proxyMode=ScopedProxyMode.TARGET_CLASS, value="session") public class ShoppingCart implements Serializable{ ... } Spring creates a proxy for a session scoped bean and makes the proxy available to services which inject in this bean. An advantage of using this approach is that any state changes on this bean are handled by Spring, it would take care of retrieving this bean from the session and propagating any changes to the bean back to the session. Further if the bean were to have any Spring lifecycle methods(say @PostConstruct or @PreDestroy annotated methods), they would get called appropriately. Approach 4 Annotating Spring MVC model attributes with @SessionAttribute annotation: @SessionAttributes("shoppingCart") public class OrderFlowController { public String step1(@ModelAttribute("shoppingCart") ShoppingCart shoppingCart) { } public String step2(@ModelAttribute("shoppingCart") ShoppingCart shoppingCart) { } public String step3(@ModelAttribute("shoppingCart") ShoppingCart shoppingCart, SessionStatus status) { status.setComplete(); } } The use case for using SessionAttributes annotation is very specific, to hold state during a flow like above Given these approaches, I personally prefer Approach 3 of using session scoped beans, this way depending on Spring to manage the underlying details of retrieving and storing the object into session. Other approaches have value though based on the scenario that you may be faced with, ranging from requiring more control over raw Http Sessions to needing to handle temporary state like in Approach 4 above.
April 29, 2014
by Biju Kunjummen
· 143,476 Views · 1 Like
article thumbnail
10 Useful Apple Store Apps for Programmers and Alpha Geeks
Recently, Lukas Eder wrote a post about The Top 10 Productivity Booster Techs for Programmers and in one of the comments he challenged me to write my own list of cool tools. I decided to give it a try and in my attempt I discovered it is not so easy to define your 10 most favorite tools. Actually, right now, my board is full with names of cool tools that I, as a programmer, use very often. I realize that I could probably make a 10-list on many different categories. So, to enrich what Lukas originally wrote, I have decided to start with a list of the kind of cool apps that any alpha-geek programmers would probably love to install in their Apple devices. Lisping If you are a fan of functional programming and particularly of the Lisp family of programming languages, then you are going to love Lisping. It is available for iPhone and iPad and you can create and run programs for the Scheme and Clojure programming languages. To avoid confusion with all the parenthesis the applications offers a very interesting and intuitive way of edition that allows you to focus on a specific context at once. Honestly I found it difficult to edit programs with it in my iPad, but still it is a tool that any alpha-geek can appreciate. Now you can test your small Scheme programs from theSICP book while you watch the extended DVD edition of the Lord of the Rings for the fifth time. Raskell So, not a fan of dynamically-typed functional programming languages? Well, if you prefer the safety of static typing instead then you’ll surely love Raskell. There you can edit and run programs for the Haskell programming language and it is also available for iPhone and iPad. Now, you can test those code snippets from Learn you a Haskell for Great Good while you’re comfortably reading in bed and trying to see if this time you can actually figure out what the heck is a monad!!!. Pythonista If multiparadigm programming languages is your thing, and particularly if you are fan of the Python programming language then Pythonista is the application you are looking for. The app is available for both iPhone and iPad and as you might expect lets you edit and run programs for the Python programming language, but it goes beyond that, it provides support for multi-touch, animations and sound, so that your programs can really take advantage of your device. Now you can let your Pythonicspirit run free while you wait the end of the five-minute TV commercials broadcast during your latest episode of The Big Bang Theory. Textastic Well, not every one of our favorite programming languages has a cool app editor. So, for those of us fan of other programming languages, we have this great application editor called Textastic which provides syntax highlighting support for more then 80 different programming languages and with really cool edition features that makes it really easy to use it in mobile devices. When used in the iPad or the iPhone the keyboard is extended with a new set of keys typically used by programmers and that makes writing code much simpler. The app is also available for MAC OSx. So, now you can edit your cool open source programs while you girlfriend tries to tell you all about her day at dinner together in that fancy restaurant. Penultimate What about software design? Well, I have not been able to find a decent app to do things like flowcharts or UML diagrams. However, I found that if you have an stylus, you can create your own handwritten designs in Penultimate. I have actually defined a good collection of flowcharts and UML diagrams in this way. It is a great tool to discuss design ideas, algorithms or simply to keep your thoughts and great software ideas properly recorded. Dash (Docs & Snippets) Are you tired of searching the Web for the Javadocs of a given class? Did you forget the methods of one of those angular services? What were the parameters of that git command? Heck, every time I want to read the Javadocs I have to first search the URL in Google. Well, with Dash those days are over. It is like the Google search of programmers. It offers offline instant access to dozens of different API documentations. Just type a term and it’ll find the answer you were looking for. Code Runner Does it happen to you too that sometimes you would like to test just small code snippet of Java, or JavaScript and you are forced to setup an entire project in you IDE just to test a small idea? Well, withCode Runner you avoid all these complications. It is a simple way to run small code snippets or simply a tool to run any program in any programming language with just a single click. It comes with a set of predefined programming languages, but you can extend it with more. Instapaper It is hard to keep up with the latest trends in technology. Every week I find several interesting articles I would like to read and often I try to remember articles I had read in the past. In order to keep up with all this information, for me, there is no tool like Instapaper. I save there articles I want to read and then read them offline later on, when I have time, directly from my iPad or iPhone. So this is the perfect tool for those days when you girlfriend says she’s got a headache. Keep it near bed, it will help you concentrate on something else and believe me you’re going to be the most well informed geek in your community. Evernote Finally I have a tool to keep all my ideas organized and available at all times. I have been in dozens of projects and always lose important data from every one. I can barely remember details of requirements, or the IP address for a server, or the location of all repositories, or what about the FQDN of the development server which I need to access via SSH? And those other cool ideas for projects or investigations in progress. Not to mention those great ideas for articles posts, etc. Well, with Evernote all this gets very simple. Never ever again lose any of those cool ideas or investigations in progress, or important things to remember. And if you combine it with Evernote Web Clipper it will serve the same purpose as Instapaper, mentioned above. SSH Term Pro So you’re watching again the remasterized version of Star Wars and then you feel curiosity to know if that script you left running on your server on Friday before going home has finished successfully. Well, you no longer need to get up from your couch. With SSH Term Pro you can access your server via SSH and have access to a terminal and go crazy. Your boss is going to love you for getting this tool. Well, that’s all I’ve got for now. If you guys know of any other cool apps that you consider are a must-have for alpha geeks do not hesitate a second to leave a comment and maybe we can enrich this list with even more cool apps like these.
April 29, 2014
by Edwin Dalorzo
· 25,337 Views · 1 Like
article thumbnail
Java EE: The Basics
wanted to go through some of the basic tenets, the technical terminology related to java ee. for many people, java ee/j2ee still mean servlets, jsps or maybe struts at best. no offence or pun intended! this is not a java ee 'bible' by any means. i am not capable enough of writing such a thing! so let us line up the 'keywords' related to java ee and then look at them one by one java ee java ee apis (specifications) containers services multitiered applications components let's try to elaborate on the above mentioned points. ok. so what is java ee? 'ee' stands for enterprise edition. that essentially makes java ee - java enterprise edition. if i had to summarize java ee in a couple of sentences, it would go something like this "java ee is a platform which defines 'standard specifications/apis' which are then implemented by vendors and used for development of enterprise (distributed, 'multi-tired', robust) 'applications'. these applications are composed of modules or 'components' which use java ee 'containers' as their run-time infrastructure." what is this 'standardized platform' based upon? what does it constitute? the platform revolves around 'standard' specifications or apis . think of these as contracts defined by a standard body e.g. enterprise java beans (ejb), java persistence api (jpa), java message service (jms) etc. these contracts/specifications/apis are implemented by different vendors e.g. glassfish, oracle weblogic, apache tomee etc alright. what about containers? containers can be visualized as 'virtual/logical partitions' . each container supports a subset of the apis/specifications defined by the java ee platform they provide run-time 'services' to the 'applications' which they host the java ee specification lists 4 types of containers ejb container web container application client container applet container java ee containers i am not going to dwell into details of these containers in this post. services?? well, 'services' are nothing but a result of the vendor implementations of the standard 'specifications' (mentioned above). examples of specifications are - jersey for jax-rs (restful services), tyrus (web sockets), eclipselink (jpa), weld (cdi) etc. the 'container' is the interface between the deployed application ('service' consumer) and the application server. here is a list of 'services' which are rendered by the 'container' to the underlying 'components' (this is not an exhaustive list) persistence - offered by the java persistence api (jpa) which drives object relational mapping (orm) and an abstraction for the database operations. messaging - the java message service (jms) provides asynchronous messaging between disparate parts of your applications. contexts & dependency injection - cdi provides loosely coupled and type safe injection of resources. web services - jaxrs and jaxws provide support for rest and soap style services respectively transaction - provided by the java transaction api (jta) implementation what is a typical java ee 'application'? what does it comprise of? applications are composed of different ' components ' which in turn are supported by their corresponding ' container ' supported 'component' types are: enterprise applications - make use of the specifications like ejb, jms, jpa etc and are executed within an ejb container web applications - they leverage the servlet api, jsp, jsf etc and are supported by a web container application client - executed in client side. they need an application client container which has a set of supported libraries and executes in a java se environment. applets - these are gui applications which execute in a web browser. how are java ee applications structured? as far as java ee 'application' architecture is concerned, they generally tend follow the n-tier model consisting of client tier, server tier and of course the database (back end) tier client tier - consists of web browsers or gui (swing, java fx) based clients. web browsers tend to talk to the 'web components' on the server tier while the gui clients interact directly with the 'business' layer within the server tier server tier - this tier comprises of the dynamic web components (jsp, jsf, servlets) and the business layer driven by ejbs, jms, jpa, jta specifications. database tier - contains 'enterprise information systems' backed by databases or even legacy data repositories. generic 3-tier java ee application architecture java ee - bare bones, basics.... as quickly and briefly as i possibly could. that's all for now! :-) stay tuned for more java ee content, specifically around the latest and greatest version of the java ee platform --> java ee 7 happy reading!
April 29, 2014
by Abhishek Gupta DZone Core CORE
· 40,733 Views · 3 Likes
article thumbnail
The 7 Log Management Tools Java Developers Should Know
splunk vs. sumo logic vs. logstash vs. graylog vs. loggly vs. papertrails vs. splunk>storm splunk, sumo logic, logstash, graylog, loggly, papertrails - did i miss someone? i’m pretty sure i did. logs are like fossil fuels - we’ve been wanting to get rid of them for the past 20 years, but we’re not quite there yet. well, if that's the case i want a bmw! to deal with the growth of log data a host of log management & analysis tools have been built over the last few years to help developers and operations make sense of the growing data. i thought it’d be interesting to look at our options and what are each tools’ selling point, from a developer’s standpoint . splunk as the biggest tool in this space, i decided to put splunk in a category of its own. that’s not to say it’s the best tool for what you need, but more to give credit to a product who essentially created a new category. pros splunk is probably the most feature rich solution in the space. it’s got hundreds of apps (i counted 537 ) to make sense of almost every format of log data, from security to business analytics to infrastructure monitoring. splunk’s search and charting tools are feature rich to the point that there’s probably no set of data you can’t get to through its ui or apis. cons splunk has two major cons. the first, that is more subjective, is that it’s an on-premise solution which means that setup costs in terms of money and complexity are high. to deploy in a high-scale environment you will need to install and configure a dedicated cluster. as a developer, it’s usually something you can't or don’t want to do as your first choice. splunk’s second con is that it’s expensive. to support a real-world application you’re looking at tens of thousands of dollars, which most likely means you’ll need sign offs from high-ups in your organization, and the process is going to be slow. if you’ve got a new app and you want something fast that you can quickly spin up and ramp as things progress - keep reading. some more enterprise log analyzers can be found here . saas log analyzers sumo logic sumo was founded as a saas version of splunk, going so far as to imitate some of splunk’s features and visuals early on. having said that, sl has developed to a full fledged enterprise class log management solution. pros sl is chock-full of features to reduce, search and chart mass amounts of data. out of all the saas log analyzers, it’s probably the most feature rich. also, being a saas offering it inherently means setup and ongoing operation are easier. one of sumo logic’s main points of attraction is the ability to establish baselines and to actively notify you when key metrics change after an event such as a new version rollout or a breach attempt. cons this one is shared across all saas log analyzers, which is you need to get the data to the service to actually do something with it. this means that you’ll be looking at possible gbs (or more) uploaded from your servers. this can create issues on multiple fronts - as a developer, if you're logging sensitive or pii you need to make sure it’s redacted. there may be a lag between the time data is logged and the time it’s visible to to the service. there’s additional overhead on your machines transmitting gbs of data, which really depends on your logging throughput. sumo’s pricing is also not transparent , which means you might be looking at a buying process which is more complex than swiping your team’s credit card to get going. loggly loggly is also a robust log analyzer, focusing on simplicity and ease of use for a devops audience. pros whereas sumo logic has a strong enterprise and security focus, loggly is geared more towards helping devops find and fix operational problems. this makes it very developer-friendly. things like creating custom performance and devops dashboards are super-easy to do. pricing is also transparent, which makes start of use easier. cons don't expect loggly to scale into a full blown infrastructure, security or analytics solution. if you need forensics or infrastructure monitoring you’re in the wrong place. this is a tools mainly for devops to parse data coming from your app servers. anything beyond that you’ll have to build yourself. papertrails papertrails is a simple way to look and search through logs from multiple machines, in one consolidated easy-to-use interface. think of it like tailing your log in the cloud, and you won't be too far off. pros pt is what it is. a simple way to look at log files from multiple machines in a singular view in the cloud. the ux itself is very similar to looking at a log on your machine, and so are the search commands. it aims to do something simple and useful, and does it elegantly. it’s also very affordable . cons pt is mostly text based. looking for any advanced integrations, predictive or reporting capabilities? you're barking up the wrong tree. splunk>storm this is splunk’s little (some may say step) saas brother. it’s a pretty similar offering that’s hosted on splunk’s servers. pros storm lets you experiment with splunk without having to install the actual software on-premise, and contains much of the features available in the full version. cons this isn't really a commercial offering, and you're limited in the amount of data you can send. it seems to be more of an online limited version of splunk meant to help people test out the product without having to deploy first. a new service called splunk cloud is aimed at providing a full-blown splunk saas experience. open source analyzers logstash logstash is an open source tool for collecting and managing log files. it’s part of an open-source stack which includes elasticsearch for indexing and searching through data and kibana for charting and visualizing data. together they form a powerful log management solution. pros being an open-source solution means you're inherently getting a lot of a control and a very good price. logstash uses three mature and powerful components, all heavily maintained, to create a very robust and extensible package. for an open-source solution it’s also very easy to install and start using. we use logstash and love it. cons as logstash is essentially a stack, it means you're dealing with three different products. that means that extensibility also becomes complex. logstash filters are written in ruby, kibana is pure javascript and elasticsearch has its own rest api as well as json templates. when you move to production, you’ll also need to separate the three into different machines, which adds to the complexity. graylog2 a fairly new player in the space, gl2 is an open-source log analyzer backed by mongodb as well as elasticsearch (similar to logstash) for storing and searching through log errors. it’s mainly focused on helping developers detect and fix errors in their apps. also in this category you can find fluentd and kafka whose one of its main use-cases is also storing log data. phew, so many choices! takipi for logs while this post is not about takipi, i thought there’s one feature it has which you might find relevant to all of this. the biggest disadvantage in all log analyzers and log files in general, is that the right data has to be put there by you first. from a dev perspective, it means that if an exception isn’t logged, or the variable data you need to understand why it happened isn't there, no log file or analyzer in the world can help you. production debugging sucks. one of the things we’ve added to takipi is the ability to jump into a recorded debugging session straight from a log file error. this means that for every log error you can see the actual source code and variable values at the moment of error. you can learn more about it here . this is one post where i would love to hear from you guys about your experiences with some of the tools mentioned (and some that i didn’t). i’m sure there are things you would disagree with or would like to correct me on - so go ahead, the comment section is below and i would love to hear from you. originally posted on takipi blog
April 29, 2014
by Chen Harel
· 37,835 Views
article thumbnail
My Thoughts on the Datomic License
Yeah, it's not Open I have a greenfield project where the choice of database is open. I have been very interested in Datomic for a couple of years now and figured that I'd try Datomic out for the project. Then I tried to actually download and install it and decided against it... mostly because the value of Datomic does not clearly outweigh the cost of using proprietary software. I am writing this post to communicate my perception. Making Money People who write software should be reasonable compensated for their work. I write software... some open and some proprietary... and I like to be compensated for my work. It's important to have financial incentives aligned with software development as we've recently learned in the whole Heart Bleed disaster. We also know that pricing models are complex beasts. I am all in favor of finding ways to reasonably price software so that a reasonable amount of money flows to the authors such that the authors can keep writing/improving the software. In terms of software, I prefer the mostly open approach to making money. Zimbra is an excellent example. They have an open version of their mail server. Download it and install it. Want support? There's a fee for that. Want the Exchange connector to make it work nicely with Outlook, that's proprietary and costs a non-trivial amount. Zimbra makes enough off support and the "Network" edition to support robust development of the core open product. Yay! Chattin' with Rich I had a conversation with Rich Hickey about open sourcing Datomic. He has a lot of valid reasons for keeping Datomic closed and charging for it. While I think there are other ways that Cognitect can make money from Datomic, this post is not trying to change Rich's mind. It is, however, information to help the Cognitect folks improve the way they present a proprietary piece of software in a world that is mostly open. My Experience with trying Datomic I've got this project. I'm making a Docker container for my development. Ideally, I'd have a package that I can apt-get install with the data storage. A second is to have something that can be wgeted when I'm building the Docker container. A very distant third is to put the tar file in my git repo and have the bytes loaded into the container on build. I go to Datomic.com and look for the download link. None... but a lot of big buttons for Get Datomic so I click on one of those. But I have to visit My Datomic to actually get anything. I register my user name and wait 15 minutes for the validation link in the email. I get the validation link and I log into My Datomic. I go to the download link and there's only the option for Datomic Pro... no easy way to find the Datomic "Free" version that's supposed to be fine for open source projects. Part of the download is an admonition to read the End User License Agreement and being a developer who cares about other developers' rights and a lawyer by training, I start reading. Problems So, the first problem is in the License Grant clause: The Licensee is permitted to create copies the Software solely for data protection, archiving and backup purposes. Basically, this means that making of Datomic and putting it in a git repo and distributing that git repo to GitHub/BitBucket is a violation of the terms of the EULA. Yes, one might argue that the preceding sentence: ... or for Licensee's own internal non-production use for the purpose of development or testing on an unlimited number of Licensed Processes. Means that putting a copy in git is "for the purpose of development" and I'm sure that's what the current Datomic management intents. But when Oracle buys Cognitect, Oracle may have a different read on the license. Also, I think that if Oracle were to sue me for having copies of Datomic strewn around in git, I would likely escape liability under copyright law. On the other hand, I would not be able to get a legal action dismissed with a Rule 11 motion and anything that's going to a judge is a place I don't want to be, I also understand the complexities of trying to use "rights to copy bits" as a lever for extracting money for functionality that isn't directly associated with those bits is a tough issue to deal with. But, the Datomic EULA doesn't even try to address that. Next, let's take a look at the Restrictions clause: (a) copy or use the Software in any manner except as expressly permitted in this EULA; There's nothing in the EULA that is express about what can be done with the software. Yes, the "install and use the Software only for the Licensee's own internal production use by Licensed Processes, subject to the condition that the Licensee must ensure the maximum number of processes accessing and using the Software is equal to the number of Licensed Processes for which the necessary Fees have been paid" clause gives us a hint. But there's really nothing that says I can store data in Datomic. If the above clause referenced the documentation as a guide to the manner in which the software could be used, fine. And yes, I'm being picky. (c) transfer, sell, rent, lease, lend, distribute, or sublicense the Software to any third party; Does this mean I have to run Datomic on my own physical hardware servers? Does this mean that I can't allow a consultant to access Datomic in my git repo? If I run it on AWS, I'm transferring the bytes of the software to Amazon. Also, this clause likely conflicts with most cloud hosting agreements where one has to grant at least certain copying rights to the hosting service. (d) use the Software for providing time-sharing services, service bureau services or as part of an application services provider or as a service offering primarily designed to offer the functionality of the Software; Okay... so you can't use Datomic for a cloud service. The conjunction above is or so each of the above is a EULA violation. (j) publicly display or communicate the results of internal performance testing or other benchmarking or performance evaluation of the Software; Sure, Oracle has no-benchmarking clauses. But really. Cognitect? Come on. (l) except as otherwise permitted in this EULA, publish, use, promote, broadcast, circulate or refer publicly to any Cognitect's name, trade name, trademark, service mark or logo; Once you install Datomic, no more blogging about Cognitect. (m) commit any act or omission the likely result of which is that Cognitect's or any of its third party suppliers' reputation will be brought into disrepute or which act or omission could reasonably be expected to have or does have a material and adverse effect on Cognitect's interests; I don't know what circumstances could lead to the above, but I don't know why it has a place in a EULA. (o) perform or facilitate any act which, directly or indirectly, causes to be transmitted to, uploaded or downloaded by, the Cognitect or any end user any software viruses, worms, Trojan horses, time bombs, trap doors or any other computer code, files or programs or repetitive requests for information designed to interrupt, destroy or limit the functionality of any computer software or hardware or telecommunications equipment or to diminish the quality of, interfere with the performance of, or impair the functionality of the Software (individually and collectively, a "Virus"); Once again, I don't know why this clause should be in a EULA for a database. There are criminal laws that deal with hacking and viruses. Further, there's no limitation for intent. The above clause could allow Cognitect to pull a Datomic license from a user who fails to stop the spread of a virus. (p) use the Software for any immoral, unethical, illegal or otherwise nefarious purpose; Um... really. Who gets to determine morals here. If I use Datomic to build a site for Marriage Equality USA, would Brendan Eich be the moral decision maker. What if I build a site for a Prop 215 company... can Cognitect pull the license even though the company is legal in California, but not at the federal level? I Could go On But at the end of the day, the Datomic EULA isn't something that I can feel comfortable with. That means I can't build software on software that's bound by a EULA that is internally inconsistent and that exposes me and my clients to a fair number of license loss scenarios. I really do want to use Datomic. I also want Cognitect to be wildly successful and I deeply appreciate what they've done with Clojure and the Clojure community. I will also gladly pay Cognitect for Datomic if I get it into production for a non-trivial site. But where the EULA is now and the sense that I get from the Datomic web site... I'm going to pass on it for right now. I'll use PostgreSQL 9.3 with JSON support. Yeah, it's technically not as good, but I know what my rights are.
April 29, 2014
by David Pollak
· 13,337 Views · 1 Like
article thumbnail
Git Showing File as Modified Even if It Is Unchanged
This is one annoying problem that happens sometimes to git users: the symptom is: git status command shows you some files as modified (you are sure that you had not modified that files), you revert all changes with a git checkout — . but the files stills are in modified state if you issue another git status. This is a real annoying problem, suppose you want to switch branch with git checkout branchname, you will find that git does not allow you to switch because of uncommitted changes. This problem is likely caused by the end-of-line normalization (I strongly suggest you to read all the details in Pro Git book or read the help of github). I do not want to enter into details of this feature, but I only want to help people to diagnose and avoid this kind of problem. To understand if you really have a Line Ending Issue you should run git diff -w command to verify what is really changed in files that git as modified with git status command. The -w options tells git to ignore whitespace and line endings, if this command shows no differences, you are probably victim of problem in Line Ending Normalization. This is especially true if you are working with git svn, connecting to a subversion repository where developers did not pay attention to line endings and it happens usually when you have files with mixed CRLF / CR / LF. If you work in mixed environment (Unix/Linux, Windows, Macintosh) it is better to find files that are listed as modified and manually (or with some tool) normalize Line Endings. If you do not work in mixed environment you can simply turn off eol normalizationfor the single repository where you experience the problem. To do this you can issue a git config –local core.autocrlf false but it works only for you and not for all the other developers that works to the project. Moreover some people reports that they still have problem even with core.autocrlf to false. Remember that git supports .gitattributes files, used to change settings for a single subdirectory. If you set core.autocrlf to false and still have line ending normalization problem, please search for .gitattribuges files in every subdirectory of your repository, and verify if it has a line where autocrlf is turned on: * text=auto now you can turn off in all .gitattributes files you find in your repository * text=off To be sure that every developer of the team works with autocrlf turned off, you should place a .gitattributes file in repository root with autocrlf turned off. Remember that it is a better option to normalize files and leave autocrlf turned on, but if you are working with legacy code imported from another VCS, or you work with git svn, git-tf or similar tools, probably it is better turn autocrlf to off if you start experiencing that kind of problems.
April 29, 2014
by Ricci Gian Maria
· 93,136 Views
article thumbnail
Understanding the Tomcat NIO Connector and How to Configure It
Get a rundown on the Tomcat NIO Connector as well as a tutorial on how to set it up.
April 29, 2014
by Faheem Sohail
· 208,318 Views · 18 Likes
article thumbnail
Neo4j & Cypher: Creating a Time Tree Down to the Day
Michael recently wrote a blog post showing how to create a time tree representing time down to the second using Neo4j’s Cypher query language, something I built on top of for a side project I’m working on. The domain I want to model is RSVPs to meetup invites – I want to understand how much in advance people respond and how likely they are to drop out at a later stage. For this problem I only need to measure time down to the day so my task is a bit easier than Michael’s. After a bit of fiddling around with leap years, I believe the following query will create a time tree representing all the days from 2011 – 2014, which covers the time the London Neo4j meetup has been running: WITH range(2011, 2014) AS years, range(1,12) as months FOREACH(year IN years | MERGE (y:Year {year: year}) FOREACH(month IN months | CREATE (m:Month {month: month}) MERGE (y)-[:HAS_MONTH]->(m) FOREACH(day IN (CASE WHEN month IN [1,3,5,7,8,10,12] THEN range(1,31) WHEN month = 2 THEN CASE WHEN year % 4 <> 0 THEN range(1,28) WHEN year % 100 <> 0 THEN range(1,29) WHEN year % 400 <> 0 THEN range(1,29) ELSE range(1,28) END ELSE range(1,30) END) | CREATE (d:Day {day: day}) MERGE (m)-[:HAS_DAY]->(d)))) The next step is to link adjacent days together so that we can easily traverse between adjacent days without needing to go back up and down the tree. For example we should have something like this: (jan31)-[:NEXT]->(feb1)-[:NEXT]->(feb2) We can build this by first collecting all the ‘day’ nodes in date order like so: MATCH (year:Year)-[:HAS_MONTH]->(month)-[:HAS_DAY]->(day) WITH year,month,day ORDER BY year.year, month.month, day.day WITH collect(day) as days RETURN days And then iterating over adjacent nodes to create the ‘NEXT’ relationship: MATCH (year:Year)-[:HAS_MONTH]->(month)-[:HAS_DAY]->(day) WITH year,month,day ORDER BY year.year, month.month, day.day WITH collect(day) as days FOREACH(i in RANGE(0, length(days)-2) | FOREACH(day1 in [days[i]] | FOREACH(day2 in [days[i+1]] | CREATE UNIQUE (day1)-[:NEXT]->(day2)))) Now if we want to find the previous 5 days from the 1st February 2014 we could write the following query: MATCH (y:Year {year: 2014})-[:HAS_MONTH]->(m:Month {month: 2})-[:HAS_DAY]->(:Day {day: 1})<-[:NEXT*0..5]-(day) RETURN y,m,day If we want to we can create the time tree and then connect the day nodes all in one query by using ‘WITH *’ like so: WITH range(2011, 2014) AS years, range(1,12) as months FOREACH(year IN years | MERGE (y:Year {year: year}) FOREACH(month IN months | CREATE (m:Month {month: month}) MERGE (y)-[:HAS_MONTH]->(m) FOREACH(day IN (CASE WHEN month IN [1,3,5,7,8,10,12] THEN range(1,31) WHEN month = 2 THEN CASE WHEN year % 4 <> 0 THEN range(1,28) WHEN year % 100 <> 0 THEN range(1,29) WHEN year % 400 <> 0 THEN range(1,29) ELSE range(1,28) END ELSE range(1,30) END) | CREATE (d:Day {day: day}) MERGE (m)-[:HAS_DAY]->(d)))) WITH * MATCH (year:Year)-[:HAS_MONTH]->(month)-[:HAS_DAY]->(day) WITH year,month,day ORDER BY year.year, month.month, day.day WITH collect(day) as days FOREACH(i in RANGE(0, length(days)-2) | FOREACH(day1 in [days[i]] | FOREACH(day2 in [days[i+1]] | CREATE UNIQUE (day1)-[:NEXT]->(day2)))) Now I need to connect the RSVP events to the tree!
April 29, 2014
by Mark Needham
· 4,900 Views
article thumbnail
3 Reasons Why Knowledge Worker Engagement Is Decreasing
Due to the technological development with the Internet and social media, markets are no longer created and controlled with broadcast marketing. People can now find and connect with people like themselves all over the world – and no longer limited to the people in their close proximity and to existing ties such as family members, friends, colleagues or neighbors. They can connect with anyone, and they all influence each other, immediately and with multiplier effects. The power is shifting from companies to consumers. It is a radical shift, but it was predicted already in the mid 90’ies by marketing guru Philip Kotler as a consequence of the Internet. So we shouldn’t be too surprised. Yet a lot of companies are. And they haven’t prepared at all for this. Companies and organizations are waking up to a new reality, and the wake-up call can sometimes be harsh. A number of things are changing, and I will mention four of these here. 1. Change and uncertainty is the new normal To start with, today’s business environment is anything but static. It’s changing faster and faster, and in new ways. It’s becoming more and more unpredictable. This means that companies and organizations can’t do long-term planning like they used to. Instead they have to be prepared for change, to quickly adapt to new conditions and situations, such as changing consumer behaviors, new competition, new innovations, and so forth. 2. Diminishing return on optimization efforts The second big change is that the return on optimization efforts is diminishing. The companies that lead the development in their industries, and get all the profit are those that are able to create new value. They don’t do that with optimization. They do it by innovating new product and services, by creating and developing relationships with consumers and others, by collaborating internally and externally, and by constantly learning how change theirs strategies 3. Growth and efficiency is not enough Thirdly, being able to grow in terms of production volumes, market presence and market share is not enough to be successful, neither is it to produce and market products or services as efficiently as possible. Instead, continuous innovation and high responsiveness to change and customer demands is becoming more and more critical. This obviously can’t be addressed solely by streamlining and optimizing transactional processes, as we have done for the last few decades with the help of information technology. Innovation and responsiveness requires empowered people that can collaborate efficiently and effectively. That is why collaboration is the new productivity frontier. 4. Non-routine knowledge work is increasing in importance Finally, we can see that work is shifting from manual work to knowledge work, but most importantly from routine work to non-routine work. Computers and software are taking over repetitive and routine-based knowledge work, just as robots have replaced workers doing repetitive and routine manual work in the factories. The work that is remaining and increasing is the non-routine knowledge work that is often highly interdependent such as problem solving, product development, sales and so forth. Knowledge work is something completely different than most of the work that organizations have tried to improve and optimize during the 20th century. It’s fluid, dynamic, unpredictable, and non-repeatable. Knowledge workers need to look beyond the standard ways of doing things, to question information, rules, and ways of working. This is something completely different to how it is to work at a production line in a factory, where workers follow predefined and highly repeatable processes and procedure. Most organizations have been designed for efficiency and economies of scale, not for empowering people enabling collaboration, innovation and responsiveness. Too often, knowledge workers feel like they are just cogs in a big machinery. And unfortunately, in most cases, their feelings are motivated. We see all over that employees are increasingly dissatisfied with their jobs. Employee engagement is falling. It is especially bad in large and distributed organizations. The consequences are many and severe. Innovation is stifling. Productivity is, if not falling, not improving. People are leaving, or they want to leave, their jobs. It is hard to sustain and improve quality. And it’s not possible to recruit and retain talent by the quality and numbers that are needed. So what is causing this? I have grouped a number of causes into three overall themes; complexity, inflexibility, and disconnectedness. 1. Complexity As knowledge workers we often find ourselves stuck between a rock and a hard place. Workload and complexity at work is increasing, while we at the same time are expected to produce more, faster and faster. And adapt to new conditions. Not only that, we are expected to be creative and innovative as well. Still, if we look at an average day in the life of a knowledge worker, we struggle a lot with finding answers to basic questions, such as what is happening in our work environment, who is doing what, where I can fiend a piece of information, when it is my turn to contribute, and so on. This means that we spend a lot of time on things that are not creating value, just getting ready to create value. For example, Intel estimated that their employees spent one day per week on trying to find information and locating the expertise they needed to do their job. Although the tasks of knowledge workers come in all shapes and sizes, many of them rely on a number of basic capabilities, such as finding information or locating expertise. These capabilities are vital to knowledge worker productivity, but also to innovation, and it is evident that poor capabilities generate a lot of waste. Of course, we constantly get new tools that aim to help us. But when new tools and features are introduced to knowledge worker, there often is no guidance, and little customizing it to fit our needs. The problem is that we already have this huge pile of complex products to deal with, and we need to fit these. This technology-centric approach adds complexity instead of reducing it, instead of making things simpler for us. A study by Oracle found that productivity of enterprise application users had fallen almost 1/5 over a period of only three years. It’s like giving everybody Friday off. How can that be? I would argue that it’s the increasing complexity that is hampering productivity. 2. Inflexibility The second theme is inflexibility. By this I mean that our organizations and the systems that are there to help us get our work done are designed in a way that makes change, creativity and improvisation hard. Instead of empowering knowledge workers, our organizations often constrain and prevent us from being productive and innovative. First of all, there is a mismatch between what science knows and what organizations do when it comes to how they try to motivate knowledge workers to perform better. In most organizations, existing performance models are built on extrinsic motivators, or carrots and sticks if you like. These models worked pretty fine for routine, left-brain, rule-based work of 20th century, but they are not working very well for right-brained, creative, and self-propelled people performing non-routine and highly collaborative conceptual tasks. For example, bonuses and commissions don’t work for this kind of work. As a matter of fact, science shows they have the opposite effect than intended; the higher the extrinsic rewards, the worse the performance gets. Organizations are apparently making important decisions about their future based on the wrong assumptions. The left circle in this venn diagram represents things that have been considered important for trying to maximize the productivity of manual routine work. The right circle represents things that are important for motivating knowledge workers doing non-repetitive work. There is still little understanding and experience of how to do the things the right circle, so organizations and managers tend to stick with the things they know how to do. Those are the things in the left circle. Furthermore, knowledge workers need to have flexible working conditions. When it comes to knowledge work, work is not a place, it is something you do. Most knowledge worker tasks can be performed from any location, even those that require close collaboration with others. Organizations need to support this, not only to increase performance, but also to make people more engaged at work. Research shows that what employees of all age groups want is the flexibility to determine for themselves where, when, and how they work, and that increasing workplace flexibility has a positive effect on employee engagement and thereby also on employee productivity. A Virgin Media Business study found that 40% of the surveyed organizations often overhear employees complain about being tied to their desks and 7 in 10 organizations believe flexible working would make their employees both happier and more productive, boosting employee engagement. 3. Inconnectedness Finally, we have a theme that I call disconnectedness. It is about people and information being disconnected from each other, and thereby unable to share, cooperate and collaborate as is required to be productive and deal with the challenges organizations face. Collaborating isn’t as easy as it sometimes might sound, especially not in large and distributed organizations; there are too many barriers to collaborate naturally across an organization and across locations. In a complex and constantly changing work environment, it becomes even harder to find time and energy to overcome these barriers. It is only natural that we tend to share, cooperate and collaborate with people in our close proximity and that we already know and trust, failing to help and collaborate with others or share information that they might have use for. People work in silos. Silo thinking is a typical phenomenon in large organizations. Teams tend to focus on the parts they are responsible for and specialize in. They sub-optimize and focus on their own goals. They become organizational barriers that limit communication and impede sharing, collaboration, and innovation within the enterprise. Organizations have also created digital work environments to optimize personal productivity and teamwork, but doing so they have neglected the fact that knowledge work is increasingly relying on collaboration in networks across locations and organizations and stretching far beyond teams. It might seem as a paradox, but the modern and increasingly digital work environments have in fact made people more isolated and unaware of what is happening at work. This disconnectedness means that people become less engaged. And in a rapidly changing and complex work environment, this has serious implications, such as lost productivity and innovations. Or worse – talent is wasted and people leave. What do to about it? So what should organizations do to avoid the negative consequences of complexity, inflexibility and disconnectedness? The simple answer is that they should start working towards increased simplicity, flexibility and connectedness. What they should do and how, I will return to in my next post.
April 28, 2014
by Oscar Berg
· 3,437 Views
article thumbnail
Using BDD with web-services: a tutorial using JBehave and Thucydides
behavior driven development (bdd) is an approach that uses conversions around concrete examples to discover, describe and formalize the behavior of a system. bdd tools such as jbehave and cucumber are often used for writing web-based automated acceptance testing. but bdd is also an excellent approach to adopt if you need to design a web service. in this article, we will see how you can use jbehave and thucydides to express and to automate clear, meaningful acceptance criteria for a restful web service. (the general approach would also work for a web service using soap.) we will also see how the reports (or "living documentation", in bdd terms) generated by these automated acceptance criteria also do a great job to document the web service. thucydides is an open source bdd reporting and acceptance testing library that is used in conjunction with other testing tools, either bdd testing frameworks such as jbehave , cucumber or specflow , or more traditional libraries such as junit. web services are easy to model and test using bdd techniques, in many ways more so than web applications. web services are (or should be) relatively easy to describe in behavioral terms. they accept a well-defined set of input parameters, and return a well-defined result. so they fit well into the typical bdd-style way of describing behavior, using given-when-then format: given some precondition when something happens then a particular outcome is expected during the rest of this article we will see how to describe and automate web service behavior in this way. to follow along, you will need java and maven installed on your machine (i used java 8 and maven 3.2.1). the source code is also available on github (https://github.com/thucydides-webtests/webservice-demo). if you want to build the project from scratch, first create a new thucydides/jbehave project from the command line like this: mvn archetype:generate -dfilter=thucydides-jbehave enter whatever artifact and group names you like: it doesn't make any difference for this example: choose archetype: 1: local -> net.thucydides:thucydides-jbehave-archetype (thucydides automated acceptance testing project using selenium 2, junit and jbehave) choose a number or apply filter (format: [groupid:]artifactid, case sensitive contains): : 1 define value for property 'groupid': : com.wakaleo.training.webservices define value for property 'artifactid': : bdddemo define value for property 'version': 1.0-snapshot: : 1.0.0-snapshot define value for property 'package': com.wakaleo.training.webservices: : confirm properties configuration: groupid: com.wakaleo.training.webservices artifactid: bdddemo version: 1.0.0-snapshot package: com.wakaleo.training.webservices y: : this will create a simple project set up with jbehave and thucydides. it is designed to test web applications, but it is easy enough to adapt to work with a restful web service. we don't need the demo code, so you can safely delete all of the java classes (except for the acceptancetestsuite class) and the jbehave .story files. now, update the pom.xml file to use the latest version of thucydides, e.g. utf-8 0.9.239 0.9.235 once you have done this, you need to define some stories and scenarios for your web service. to keep things simple in this example, we will be working with two simple requirements: shortening and expanding urls using google's url shortening service . we will describe these in two jbehave story files. create a stories directory under src/test/resources , and create a sub-directory for each requirement called expanding_urls and shortening_urls . each directory represents a high-level capability that we want to implement. inside these directories we place jbehave story files ( expanding_urls.story and shortening_urls.story ) for the features we need. (this structure is a little overkill in this case, but is useful for real-world project where the requirements are more numerous and more complex). this structure is shown here: [img_assist|nid=167149|title=|desc=|link=popup|align=left|width=600|height=234] the story files contain the bdd-style given-when-then scenarios that describe how the web service should behave. when you design a web service using bdd, you can express behavior at two levels (and many projects use both). the first approach is to describe the json data in the bdd scenarios, as illustrated here: scenario: shorten urls given a url http://www.google.com when i request the shortened form of this url then i should obtain the following json message: { "kind": "urlshortener#url", "id": "http://goo.gl/fbss", "longurl": "http://www.google.com/" } this works well if your scenarios have a very technical audience (i.e. if you are writing a web service purely for other developers), and if the json contents remain simple. it is also a good way to agree on the json format that the web sevice will produce. but if you need to discuss the scenario with business, bas or even testers, and/or if the json that you are returning is more complicated, putting json in the scenarios is not such a good idea. this approach also works poorly for soap-based web services where the xml message structure is more complex. a better approach in these situations is to describe the inputs and expected outcomes in business terms, and then to translate these into the appropriate json format within the step definition: scenario: shorten urls given a url when i request the shortened form of this url then the shortened form should be examples: | providedurl | expectedurl | | http://www.google.com/ | http://goo.gl/fbss | | http://www.amazon.com/ | http://goo.gl/xj57 | let's see how we would automate this scenario using jbehave and thucydides. first, we need to write jbehave step definitions in java for each of the given/when/then steps in the scenarios we just saw. create a class called processingurls next to the acceptancetestsuite class, or in a subdirectory underneath this class. [img_assist|nid=167151|title=|desc=|link=popup|align=left|width=600|height=240] the step definitions for this scenario are simple, and largely delegate to a class called urlshortenersteps to do the heavy-weight work. this approach make a cleaner separation of th what from the how , and makes reuse easier - for example, if we need to change underlying web service we used to implement the url shortening feature, these step definitions should remain unchanged: public class processingurls { string providedurl; string returnedmessage; @steps urlshortenersteps urlshortener; @given("a url ") public void givenaurl(string providedurl) { this.providedurl = providedurl; } @when("i request the shortened form of this url") public void shortenurl() { returnedmessage = urlshortener.shorten(providedurl); } @when("i request the expanded form of this url") public void expandurl() { returnedmessage = urlshortener.expand(providedurl); } @then("the shortened form should be ") public void shortenedformshouldbe(string expectedurl) throws jsonexception { urlshortener.response_should_contain_shortened_url(returnedmessage, expectedurl); } } now add the urlshortenersteps class. this class contains the actual test code that interacts with your web service we could use any java rest client for this, but here we are using the spring resttemplate . the full class looks like this: public class urlshortenersteps extends scenariosteps { resttemplate resttemplate; public urlshortenersteps() { resttemplate = new resttemplate(); } @step("longurl={0}") public string shorten(string providedurl) { map urlform = new hashmap(); urlform.put("longurl", providedurl); return resttemplate.postforobject("https://www.googleapis.com/urlshortener/v1/url", urlform, string.class); } @step("shorturl={0}") public string expand(string providedurl) { return resttemplate.getforobject("https://www.googleapis.com/urlshortener/v1/url?shorturl={shorturl}", string.class, providedurl); } @step public void response_should_contain_shortened_url(string returnedmessage, string expectedurl) throws jsonexception { string expectedjsonmessage = "{'id':'" + expectedurl + "'}"; jsonassert.assertequals(expectedjsonmessage, returnedmessage, jsoncomparemode.lenient); } @step public void response_should_contain_long_url(string returnedmessage, string expectedurl) throws jsonexception { string expectedjsonmessage = "{'longurl':'" + expectedurl + "'}"; jsonassert.assertequals(expectedjsonmessage, returnedmessage, jsoncomparemode.lenient); } } the spring resttemplate class is an easy way to interact with a web service with a minimum of fuss. in the shorten() method, we invoke the urlshortener web service using a post operation to shorten a url: @step("longurl={0}") public string shorten(string providedurl) { map urlform = new hashmap(); urlform.put("longurl", providedurl); return resttemplate.postforobject("https://www.googleapis.com/urlshortener/v1/url", urlform, string.class); } the expand service is even simpler to call, as it just uses a simple get operation: @step("shorturl={0}") public string expand(string providedurl) { return resttemplate.getforobject("https://www.googleapis.com/urlshortener/v1/url?shorturl={shorturl}", string.class, providedurl); } in both cases, we return the json document produced by the web service, and verify the contents in the then step using the jsonassert library. there are many libraries you can use to verify the json data returned from a web service. if you need to check the entire json structure, jsonassert provides a convenient api to do so. jsonassert lets you match json documents strictly (all the elements must match, in the right order), or leniently (you only specify a subset of the fields that need to appear in the json document, regardless of order). the following step checks that the json documet contains an id field with the expected url value. the full json document will appear in the reports because it is being passed as a parameter to this step. @step public void response_should_contain_shortened_url(string returnedmessage, string expectedurl) throws jsonexception { string expectedjsonmessage = "{'id':'" + expectedurl + "'}"; jsonassert.assertequals(expectedjsonmessage, returnedmessage, jsoncomparemode.lenient); } you can run these scenarios using mvn verify from the command line: this will produce the test reports and the thucydides living documentation for these scenarios. once you have run mvn verify , open the index.html file in the target/site/thucydides directory. this gives an overview of the test results. if you click on the requirements tab, you will see an overview of the results in terms of capabilities and features. we call this "feature coverage": drill down into the "shorten urls" test result. here you will see a summary of the story or feature illustrated by this scenario: [img_assist|nid=167153|title=|desc=|link=popup|align=none|width=600|height=324] and if you scroll down further, you will see the details of how this web service was tested, including the json document returned by the service: [img_assist|nid=167155|title=|desc=|link=popup|align=none|width=640|height=346] bdd is a great fit for developing and testing web services. if you want to learn more about bdd, be sure to check out the bdd , tdd and test automation workshops we are running in sydney and melbourne this may! john ferguson smart is a well-regarded consultant, coach, and trainer in technical agile practices based in sydney, australia. a prominent international figure in the domain of behaviour driven development, automated testing and software life cycle development optimisation, john helps organisations around the world to improve their agile development practices and to optimise their java development processes and infrastructures. he is the author of several books, most recently bdd in action for manning.
April 28, 2014
by John Ferguson Smart
· 18,737 Views · 2 Likes
article thumbnail
Neo4j 2.0.0: Query Not Prepared Correctly / Type Mismatch: Expected Map
I was playing around with Neo4j’s Cypher last weekend and found myself accidentally running some queries against an earlier version of the Neo4j 2.0 series (2.0.0). My first query started with a map and I wanted to create a person from an identifier inside the map: WITH {person: {id: 1} AS params MERGE (p:Person {id: params.person.id}) RETURN p When I ran the query I got this error: ==> SyntaxException: Type mismatch: expected Map but was Boolean, Number, String or Collection (line 1, column 62) ==> "WITH {person: {id: 1} AS params MERGE (p:Person {id: params.person.id}) RETURN p" If we try the same query in 2.0.1 it works as we’d expect: ==> +---------------+ ==> | p | ==> +---------------+ ==> | Node[1]{id:} | ==> +---------------+ ==> 1 row ==> Nodes created: 1 ==> Properties set: 1 ==> Labels added: 1 ==> 47 ms My next query was the following which links topics of interest to a person: WITH {topics: [{name: "Java"}, {name: "Neo4j"}]} AS params MERGE (p:Person {id: 2}) FOREACH(t IN params.topics | MERGE (topic:Topic {name: t.name}) MERGE (p)-[:INTERESTED_IN]->(topic) ) RETURN p In 2.0.0 that query fails like so: ==> InternalException: Query not prepared correctly! but if we try it in 2.0.1 we’ll see that it works as well: ==> +---------------+ ==> | p | ==> +---------------+ ==> | Node[4]{id:2} | ==> +---------------+ ==> 1 row ==> Nodes created: 1 ==> Relationships created: 2 ==> Properties set: 1 ==> Labels added: 1 ==> 53 ms So if you’re seeing either of those errors, then get yourself upgraded to 2.0.1 as well!
April 28, 2014
by Mark Needham
· 4,493 Views
article thumbnail
Groovy Goodness: Restricting Script Syntax With SecureASTCustomizer
Running Groovy scripts with GroovyShell is easy. We can for example incorporate a Domain Specific Language (DSL) in our application where the DSL is expressed in Groovy code and executed by GroovyShell. To limit the constructs that can be used in the DSL (which is Groovy code) we can apply a SecureASTCustomizer to the GroovyShell configuration. With the SecureASTCustomizer the Abstract Syntax Tree (AST) is inspected, we cannot define runtime checks here. We can for example disallow the definition of closures and methods in the DSL script. Or we can limit the tokens to be used to just a plus or minus token. To have even more control we can implement the StatementChecker andExpressionChecker interface to determine if a specific statement or expression is allowed or not. In the following sample we first use the properties of the SecureASTCustomizer class to define what is possible and not within the script: package com.mrhaki.blog import org.codehaus.groovy.control.customizers.SecureASTCustomizer import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.ast.stmt.* import org.codehaus.groovy.ast.expr.* import org.codehaus.groovy.control.MultipleCompilationErrorsException import static org.codehaus.groovy.syntax.Types.PLUS import static org.codehaus.groovy.syntax.Types.MINUS import static org.codehaus.groovy.syntax.Types.EQUAL // Define SecureASTCustomizer to limit allowed // language syntax in scripts. final SecureASTCustomizer astCustomizer = new SecureASTCustomizer( // Do not allow method creation. methodDefinitionAllowed: false, // Do not allow closure creation. closuresAllowed: false, // No package allowed. packageAllowed: false, // White or blacklists for imports. importsBlacklist: ['java.util.Date'], // or importsWhitelist staticImportsWhitelist: [], // or staticImportBlacklist staticStarImportsWhitelist: [], // or staticStarImportsBlacklist // Make sure indirect imports are restricted. indirectImportCheckEnabled: true, // Only allow plus and minus tokens. tokensWhitelist: [PLUS, MINUS, EQUAL], // or tokensBlacklist // Disallow constant types. constantTypesClassesWhiteList: [Integer, Object, String], // or constantTypesWhiteList // or constantTypesBlackList // or constantTypesClassesBlackList // Restrict method calls to whitelisted classes. // receiversClassesWhiteList: [], // or receiversWhiteList // or receiversClassesBlackList // or receiversBlackList // Ignore certain language statement by // whitelisting or blacklisting them. statementsBlacklist: [IfStatement], // or statementsWhitelist // Ignore certain language expressions by // whitelisting or blacklisting them. expressionsBlacklist: [MethodCallExpression] // or expresionsWhitelist ) // Add SecureASTCustomizer to configuration for shell. final conf = new CompilerConfiguration() conf.addCompilationCustomizers(astCustomizer) // Create shell with given configuration. final shell = new GroovyShell(conf) // All valid script. final result = shell.evaluate ''' def s1 = 'Groovy' def s2 = 'rocks' "$s1 $s2!" ''' assert result == 'Groovy rocks!' // Some invalid scripts. try { // Importing [java.util.Date] is not allowed shell.evaluate ''' new Date() ''' } catch (MultipleCompilationErrorsException e) { assert e.message.contains('Indirect import checks prevents usage of expression') } try { // MethodCallExpression not allowed shell.evaluate ''' println "Groovy rocks!" ''' } catch (MultipleCompilationErrorsException e) { assert e.message.contains('MethodCallExpressions are not allowed: this.println(Groovy rocks!)') } To have more fine-grained control on which statements and expression are allowed we can implement the StatementChecker andExpressionChecker interfaces. These interfaces have one method isAuthorized with a boolean return type. We return true if a statement or expression is allowed and false if not. package com.mrhaki.blog import org.codehaus.groovy.control.customizers.SecureASTCustomizer import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.ast.stmt.* import org.codehaus.groovy.ast.expr.* import org.codehaus.groovy.control.MultipleCompilationErrorsException import static org.codehaus.groovy.control.customizers.SecureASTCustomizer.ExpressionChecker import static org.codehaus.groovy.control.customizers.SecureASTCustomizer.StatementChecker // Define SecureASTCustomizer. final SecureASTCustomizer astCustomizer = new SecureASTCustomizer() // Define expression checker to deny // usage of variable names with length of 1. def smallVariableNames = { expr -> if (expr instanceof VariableExpression) { expr.variable.size() > 1 } else { true } } as ExpressionChecker astCustomizer.addExpressionCheckers smallVariableNames // In for loops the collection name // can only be 'names'. def forCollectionNames = { statement -> if (statement instanceof ForStatement) { statement.collectionExpression.variable == 'names' } else { true } } as StatementChecker astCustomizer.addStatementCheckers forCollectionNames // Add SecureASTCustomizer to configuration for shell. final CompilerConfiguration conf = new CompilerConfiguration() conf.addCompilationCustomizers(astCustomizer) // Create shell with given configuration. final GroovyShell shell = new GroovyShell(conf) // All valid script. final result = shell.evaluate ''' def names = ['Groovy', 'Grails'] for (name in names) { print "$name rocks! " } def s1 = 'Groovy' def s2 = 'rocks' "$s1 $s2!" ''' assert result == 'Groovy rocks!' // Some invalid scripts. try { // Variable s has length 1, which is not allowed. shell.evaluate ''' def s = 'Groovy rocks' s ''' } catch (MultipleCompilationErrorsException e) { assert e.message.contains('Expression [VariableExpression] is not allowed: s') } try { // Only names as collection expression is allowed. shell.evaluate ''' def languages = ['Groovy', 'Grails'] for (name in languages) { println "$name rocks!" } ''' } catch (MultipleCompilationErrorsException e) { assert e.message.contains('Statement [ForStatement] is not allowed') } Code written with Groovy 2.2.2.
April 27, 2014
by Hubert Klein Ikkink
· 9,260 Views
article thumbnail
Tracking Exceptions - Part 5 - Scheduling With Spring
It seems that I'm finally getting close to the end of this series of blogs on Error Tracking using Spring and for those who haven’t read any blogs in the series I’m writing a simple, but almost industrial strength, Spring application that scans for exceptions in log files and then generates a report. From the first blog in the series, these were my initial requirements: Search a given directory and its sub-directories (possibly) looking for files of a particular type. If a file is found then check its date: does it need to be searched for errors? If the file is young enough to be checked then validate it, looking for exceptions. If it contains exceptions, are they the ones we’re looking for or have they been excluded? If it contains the kind of exceptions we’re after, then add the details to a report. When all the files have been checked, format the report ready for publishing. Publish the report using email or some other technique. The whole thing will run at a given time every day This blog takes a look at meeting requirement number 8: "The whole thing will run at a given time every day" and this means implementing some kind of scheduling. Now, Java has been around for what seems like a very long time, which means that there are a number of ways of scheduling a task. These range from: Using a simple thread with a long sleep(...). Using Timer and TimerTask objects. Using a ScheduledExecutorService. Using Spring’s TaskExecutor and TaskScheduler classes. Using Spring’s @EnableScheduling and @Scheduled annotations (Spring 3.1 onwards). Using a more professional schedular. The more professional variety of schedulers range from Quartz (free) to Obsidian (seemingly much more advanced, but costs money). Spring, as you might expect, includes Quartz Scheduler support; in fact there are two ways of integrating the Quartz Scheduler into your Spring app and these are: Using a JobDetailBean Using a MethodInvokingJobDetailFactoryBean. For this application, I’m using the Spring’s Quartz integration together with a MethodInvokingJobDetailFactoryBean; the reason is that using Quartz allows me to configure my schedule using a a cron expression and MethodInvokingJobDetailFactoryBean can be configured quickly and simply using a few lines of XML. The cron expression technique used by Spring and Quartz has been shamelessly taken from Unix’s cron scheduler. For more information on how Quartz deals with cron expressions, take a look at the Quartz cron page. If you need help in creating your own cron expressions then you’ll find that Cron Maker is a really useful utility. The first thing to do when setting up Spring and Quartz is to include the following dependencies to your POM project file: org.springframework spring-context-support ${org.springframework-version} commons-logging commons-logging org.springframework spring-tx ${org.springframework-version} org.quartz-scheduler quartz 1.8.6 This is fairly straight forward with one tiny ’Gotcha’ at the end. Firstly Spring’s Quartz support is located in the spring-context-support-3.2.7.RELEASE.jar (substitute your Spring version number as applicable). Secondly, you also need to include the Spring transaction library - spring-td-3.2.7.RELEASE.jar. Lastly, you need to include a version of the Quartz scheduler; however, be careful as Spring 3.x and Quartz 2.x do not work together "out of the box" (although if you look around there are ad-hoc fixes to be found). I've used Quartz version 1.8.6, which does exactly what I need it to do. The next thing to do is to sort out the XML configuration and this involves three steps: Create an instance of a MethodInvokingJobDetailFactoryBean. This has two properties: the name of the bean that you want to call at a scheduled interval and the name of the method on that bean that you want to invoke. Couple the MethodInvokingJobDetailFactoryBean to a cron expression using a CronTriggerFactoryBean Finally, schedule the whole caboodle using a SchedulerFactoryBean Having configured these three beans, you get some XML that looks something like this: Note that I’ve use a place-holder for my cron expression. The actual cron expression can be found in the app.properties file: # run every morning at 2 AM cron.expression=0 0 2 * * ? # Use this to test the app (every minute) #cron.expression=0 0/1 * * * ? Here, I’ve got two expressions: one that schedules the job to run at 2AM every morning and another, commented out, that runs the job every minute. This is an instance of the app not quite being industrial strength. If there were a 'proper' app then I'd probably be using a different set of properties in every environment (DEV, UAT and production etc.). There are only a couple of steps left before this app can be released and the first one of these is creating an executable JAR file. More on that next time. The code for this blog is available on Github at: https://github.com/roghughe/captaindebug/tree/master/error-track. If you want to look at other blogs in this series take a look here... Tracking Application Exceptions With Spring Tracking Exceptions With Spring - Part 2 - Delegate Pattern Error Tracking Reports - Part 3 - Strategy and Package Private Tracking Exceptions - Part 4 - Spring's Mail Sender
April 25, 2014
by Roger Hughes
· 7,256 Views
article thumbnail
Dynamically Generating Python Test Cases
Testing is crucial. While many different kinds and levels of testing exist, there’s good library support only for unit tests (the Python unittest package and its moral equivalents in other languages). However, unit testing does not cover all kinds of testing we may want to do – for example, all kinds of whole program tests and integration tests. This is where we usually end up with a custom "test runner" script. Having written my share of such custom test runners, I’ve recently gravitated towards a very convenient approach which I want to share here. In short, I’m actually using Python’s unittest, combined with the dynamic nature of the language, to run all kinds of tests. Let’s assume my tests are some sort of data files which have to be fed to a program. The output of the program is compared to some "expected results" file, or maybe is encoded in the data file itself in some way. The details of this are immaterial, but seasoned programmers usually encounter such testing rigs very frequently. It commonly comes up when the program under test is a data-transformation mechanism of some sort (compiler, encryptor, encoder, compressor, translator etc.) So you write a "test runner". A script that looks at some directory tree, finds all the "test files" there, runs each through the transformation, compares, reports, etc. I’m sure all these test runners share a lot of common infrastructure – I know that mine do. Why not employ Python’s existing "test runner" capabilities to do the same? Here’s a very short code snippet that can serve as a template to achieve this: import unittest class TestsContainer(unittest.TestCase): longMessage = True def make_test_function(description, a, b): def test(self): self.assertEqual(a, b, description) return test if __name__ == '__main__': testsmap = { 'foo': [1, 1], 'bar': [1, 2], 'baz': [5, 5]} for name, params in testsmap.iteritems(): test_func = make_test_function(name, params[0], params[1]) setattr(TestsContainer, 'test_{0}'.format(name), test_func) unittest.main() What happens here: The test class TestsContainer will contain dynamically generated test methods. make_test_function creates a test function (a method, to be precise) that compares its inputs. This is just a trivial template – it could do anything, or there can be multiple such "makers" fur multiple purposes. The loop creates test functions from the data description in testmap and attaches them to the test class. Keep in mind that this is a very basic example. I hope it’s obvious that testmap could really be test files found on disk, or whatever else. The main idea here is the dynamic test method creation. So what do we gain from this, you may ask? Quite a lot. unittest is powerful – armed to its teeth with useful tools for testing. You can now invoke tests from the command line, control verbosity, control "fast fail" behavior, easily filter which tests to run and which not to run, use all kinds of assertion methods for readability and reporting (why write your own smart list comparison assertions?). Moreover, you can build on top of any number of third-party tools for working with unittest results – HTML/XML reporting, logging, automatic CI integration, and so on. The possibilities are endless. One interesting variation on this theme is aiming the dynamic generation at a different testing "layer". unittest defines any number of "test cases" (classes), each with any number of "tests" (methods). In the code above, we generate a bunch of tests into a single test case. Here’s a sample invocation to see this in action: $ python dynamic_test_methods.py -v test_bar (__main__.TestsContainer) ... FAIL test_baz (__main__.TestsContainer) ... ok test_foo (__main__.TestsContainer) ... ok ====================================================================== FAIL: test_bar (__main__.TestsContainer) ---------------------------------------------------------------------- Traceback (most recent call last): File "dynamic_test_methods.py", line 8, in test self.assertEqual(a, b, description) AssertionError: 1 != 2 : bar ---------------------------------------------------------------------- Ran 3 tests in 0.001s FAILED (failures=1) As you can see, all data pairs in testmap are translated into distinctly named test methods within the single test case TestsContainer. Very easily, we can cut this a different way, by generating a whole test case for each data item: import unittest class DynamicClassBase(unittest.TestCase): longMessage = True def make_test_function(description, a, b): def test(self): self.assertEqual(a, b, description) return test if __name__ == '__main__': testsmap = { 'foo': [1, 1], 'bar': [1, 2], 'baz': [5, 5]} for name, params in testsmap.iteritems(): test_func = make_test_function(name, params[0], params[1]) klassname = 'Test_{0}'.format(name) globals()[klassname] = type(klassname, (DynamicClassBase,), {'test_gen_{0}'.format(name): test_func}) unittest.main() Most of the code here remains the same. The difference is in the lines within the loop: now instead of dynamically creating test methods and attaching them to the test case, we create whole test cases – one per data item, with a single test method. All test cases derive from DynamicClassBase and hence from unittest.TestCase, so they will be auto-discovered by the unittest machinery. Now an execution will look like this: $ python dynamic_test_classes.py -v test_gen_bar (__main__.Test_bar) ... FAIL test_gen_baz (__main__.Test_baz) ... ok test_gen_foo (__main__.Test_foo) ... ok ====================================================================== FAIL: test_gen_bar (__main__.Test_bar) ---------------------------------------------------------------------- Traceback (most recent call last): File "dynamic_test_classes.py", line 8, in test self.assertEqual(a, b, description) AssertionError: 1 != 2 : bar ---------------------------------------------------------------------- Ran 3 tests in 0.000s FAILED (failures=1) Why would you want to generate whole test cases dynamically rather than just single tests? It all depends on your specific needs, really. In general, test cases are better isolated and share less, than tests within one test case. Moreover, you may have a huge amount of tests and want to use tools that shard your tests for parallel execution – in this case you almost certainly need separate test cases. I’ve used this technique in a number of projects over the past couple of years and found it very useful; more than once, I replaced a whole complex test runner program with about 20-30 lines of code using this technique, and gained access to many more capabilities for free. Python’s built-in test discovery, reporting and running facilities are very powerful. Coupled with third-party tools they can be even more powerful. Leveraging all this power for any kind of testing, and not just unit testing, is possible with very little code, due to Python’s dynamism. I hope you find it useful too.
April 25, 2014
by Eli Bendersky
· 12,646 Views · 2 Likes
article thumbnail
HashMap Performance Improvements in Java 8
See how HashMap performance has been improved with new features of Java 8.
April 23, 2014
by Tomasz Nurkiewicz
· 136,884 Views · 60 Likes
article thumbnail
Update Row With Highest ID In MySQL
Recently needed to update the last inserted row of a table but didn't have anyway in knowing what the highest ID in the table was. I can easily do this by using the max() function to select the highest ID in the table. SELECT MAX(id) FROM table; Then I can use the result of this query in the UPDATE query to edit the record with the highest ID. But this is quite a easy query so I should be able to do this in one query by using a nested select query on the UPDATE. UPDATE table SET name='test_name' WHERE id = (SELECT max(id) FROM table) But the problem with this is that the MAX() function doesn't work inside a nested select so had to find another way of doing this. I found out that you can use an ORDER BY and a LIMIT in an UPDATE query therefore I can use a combination of these in the UPDATE query to make sure I only update the record with the highest ID, by doing a descendant order on the ID and limiting the return to only 1 record. UPDATE table SET name='test_name' ORDER BY id DESC LIMIT 1;
April 23, 2014
by Paul Underwood
· 21,610 Views
article thumbnail
Java 7 vs. Java 8: Performance Benchmarking of Fork/Join
with the recent release of java 8, developers are still just beginning to asses the strengths and weaknesses of the new platform. the most pressing question is: does java 8 have the fastest jvm so far? a good way to asses the progress of java 8 is to test its ability to work with something that was new to java 7... fork/join. oleg shelajev uses the "infamous" java microbenchmark harness project (jmh) to create a benchmark test for the two most recent versions of java. but before implementing the benchmark, he takes the time to give a brief overview of fork/join and how it changes between java 7 and 8. here is a graph of the results : based on these results, oleg recommends taking a chance and upgrading to java 8, especially if you are working with mapreducing or fork/join. this is his interpretation of the data that lead him to that conclusion: one can see that the baseline results, which show the throughput of running the math directly in a single thread do not differ between the jdk 7 and 8. however, when we include the overhead of managing recursive tasks and going through a forkjoin execution then java 8 is much faster. the numbers for this simple benchmark suggest that the overhead of managing forkjoin tasks is around 35% more performant in the latest release. check out the full article ! it is very informative, has great visuals, and tackles complexity with clarity.
April 22, 2014
by Sarah Ervin
· 60,620 Views · 1 Like
article thumbnail
Java Regular Expressions to Validate Credit Cards
Visa Card ^4[0-9]{12}(?:[0-9]{3})?$^5[1-5][0-9]{14}$ Amex Card ^3[47][0-9]{13}$ Carte Blanche Card ^389[0-9]{11}$ Diners Club Card ^3(?:0[0-5]|[68][0-9])[0-9]{11}$ Discover Card ^65[4-9][0-9]{13}|64[4-9][0-9]{13}|6011[0-9]{12}|(622(?:12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|9[01][0-9]|92[0-5])[0-9]{10})$ JCB Card ^(?:2131|1800|35\d{3})\d{11}$ Visa Master Card ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14})$ Insta Payment Card ^63[7-9][0-9]{13}$ Laser Card ^(6304|6706|6709|6771)[0-9]{12,15}$ Maestro Card ^(5018|5020|5038|6304|6759|6761|6763)[0-9]{8,15}$ Solo Card ^(6334|6767)[0-9]{12}|(6334|6767)[0-9]{14}|(6334|6767)[0-9]{15}$ Switch Card ^(4903|4905|4911|4936|6333|6759)[0-9]{12}|(4903|4905|4911|4936|6333|6759)[0-9]{14}|(4903|4905|4911|4936|6333|6759)[0-9]{15}|564182[0-9]{10}|564182[0-9]{12}|564182[0-9]{13}|633110[0-9]{10}|633110[0-9]{12}|633110[0-9]{13}$ Union Pay Card ^(62[0-9]{14,17})$ KoreanLocalCard ^9[0-9]{15}$ BCGlobal ^(6541|6556)[0-9]{12}$ As you can see, regular expressions are incredibly powerful and the above examples are very basic. Regular expressions are essential for all sorts of application from web scraping, form validation and pattern matching. Hopefully you will find this resource useful and would come back to refer again and again.
April 22, 2014
by Jagadeesh Motamarri
· 12,562 Views · 1 Like
article thumbnail
Java String length confusion
Facts and Terminology As you probably know, Java uses UTF-16 to represent Strings. In order to understand the confusion about String.length(), you need to be familiar with some Encoding/Unicode terms. Code Point: A unique integer value which represents a character in the code space. Code Unit: A bit sequence used to encode characters (Code Points). One or more Code Units may be required to represent a Code Point. UTF-16 Unicode Code Points are logically divided into 17 planes. The first plane, the Basic Multilingual Plane (BMP) contains the “classic” characters (from U+0000 to U+FFFF). The other planes contain the supplementary characters (from U+10000 to U+10FFFF). Characters (Code Points) from the first plane are encoded in one 16-bit Code Unit with the same value. Supplementary characters (Code Points) are encoded in two Code Units (encoding-specific, see Wiki for the explanation). Example Character: A Unicode Code Point: U+0041 UTF-16 Code Unit(s): 0041 Character: Mathematical double-struck capital A Unicode Code Point: U+1D538 UTF-16 Code Unit(s): D835 DD38 As you can see here, there are characters which are encoded in two Code Units. String.length() Let’s take a look at the Javadoc of the length() method: public int length() Returns the length of this string. The length is equal to the number of Unicode code units in the string. So if you have one supplementary character which consists of two code units, the length of that single character is two. // Mathematical double-struck capital A String str = "\uD835\uDD38"; System.out.println(str); System.out.println(str.length()); //prints 2 Which is correct according to the documentation, but maybe it’s not expected. ~Solution You need to count the code points not the code units: String str = "\uD835\uDD38"; System.out.println(str); System.out.println(str.codePointCount(0, str.length())); See: codePointCount(int beginIndex, int endIndex) References/Sources The Java Language Specification Unicode Glossary: Code Point Wiki: Code Point Unicode Glossary: Code Unit Wiki: Code Unit Wiki: Unicode Wiki: UTF-16 Supplementary Characters in the Java Platform Wiki: Unicode Planes
April 21, 2014
by Jonatan Ivanov
· 18,115 Views · 7 Likes
  • Previous
  • ...
  • 1503
  • 1504
  • 1505
  • 1506
  • 1507
  • 1508
  • 1509
  • 1510
  • 1511
  • 1512
  • ...
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

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 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×