Weblogic Authors: Yeshim Deniz, Elizabeth White, Michael Meiner, Michael Bushong, Avi Rosenthal

Related Topics: Weblogic

Weblogic: Article

Easy Java Portlets

Develop and deploy based on JSR 168

A portlet is a Web component that generates fragments - pieces of markup (e.g., HTML, XML) adhering to certain specifications. Fragments are aggregated to form a complete document.

This article introduces the Java Specification Request (JSR) 168 on Java Portlets. It illustrates the creation of Java Portlets using BEA WebLogic Workshop 8.1 SP2 and the deployment of these portlets on BEA WebLogic Portal 8.1 SP2. I'll look at essential concepts such as portal, desktop, and portlets and describe in detail the various portlet modes and window states. I'll also look at designing, implementing, configuring, and executing portlets with Workshop.

JSR 168 defines the specification for Java Portlets. A portal is a Web application and an aggregation of portlets. A portlet container runs portlets and manages their life cycle. JSR 168 defines the contract between a portlet and portlet container. It does not define the contract between a portlet container and a portal. The implementation of the portal is left up to the portal vendors.

BEA WebLogic Portal

The current version of BEA WebLogic Portal (8.1 SP2) supports different types of portlets: JSP/HTML portlets, Java PageFlow portlets, Struts portlets, and Java portlets. In the future, other portlets, such as Web Services for Remote Portlets (WSRP) will be supported. Our focus will be on Java portlets.

WebLogic Portal provides portal capabilities above and beyond those described in JSR 168 including, but not limited to, the organization of portlets in books and pages; multichannel support; and customization using skins, skeletons, and shells.

In order to follow along here, before proceeding to the next section please complete the following:

  • Using the WebLogic Domain Configuration Wizard, create a portal domain (e.g., JSR168PortalDomain).
  • Using WebLogic Workshop create a portal application (e.g., JSR168PortalApp) that uses the above-created domain.
  • Create a portal Web project (e.g., JSR168PortalWebProject) inside the portal application.
  • Create a WebLogic Portal .portal file (e.g., JSR168.portal) inside the portal Web project.
  • Start the server instance.

Creating Your First Java Portlet

The following steps describe creating your first JSR 168 portlet.

  • Using WebLogic Workshop, create a new folder for the portlet (e.g., FirstPortlet) inside a portal Web project (e.g., JSR168PortalWebProject).
  • Create a new portlet by creating the corresponding .portlet file (e.g., First.portlet) using the Wizard inside the new folder.
  • Choose Java Portlet as the portlet type.
  • Specify the title (e.g., First).
  • Specify the definition label (e.g., first).
  • Specify the class name (e.g., com.malani.examples.portlets.jsr168.FirstPortlet).
  • Open the portal (e.g., JSR168.portal).
  • Drag-and-drop the portlet (e.g., First.portlet) onto a page in the portal (e.g,. JSR168.portal).
  • Run the .portal file to test it.

Your first JSR 168 portlet is running successfully! But what does the wizard do underneath the covers?

  • It creates a WebLogic Workshop and WebLogic Portal-specific .portlet file. The .portlet file forms the contract with the Workshop and WebLogic Portal-specific .portal file.
  • The wizard creates a .java file (e.g,. com.malani.examples.portlets.jsr168.FirstPortlet.java) that is placed in the WEB-INF/src directory.
  • The wizard creates a WEB-INF/portlet.xml configuration file and inserts an entry for the portlet into the file. The entry for the portlet looks something like:

    <description>Description goes here</description>

Java Portlet Class

The Portlet Java file generated by the wizard in this example extends the javax.portlet.GenericPortlet class. The GenericPortlet class implements the javax.portlet.Portlet interface. Figure 1 is a Unified Modeling Language (UML) class diagram depicting these relationships. A portlet can be written by directly implementing the portlet interface. However, GenericPortlet is a more convenient way of creating a portlet. First, let's look at the portlet life cycle, portlet modes, and window states.

Portlet Life Cycle
To successfully create portlets, you have to follow the portlet life cycle. The methods in the javax.portlet.Portlet interface define that life cycle. The life-cycle methods are init(), render(), processAction(), and destroy(). The init() method is called when an instance of the portlet is deployed. It is used to obtain any needed expensive resources, such as back-end connections, and perform other one-time activities. The destroy() method is used to release those resources when an instance of the portlet is undeployed.

The portlet specification makes a clear distinction between render requests and action requests. Figure 2 depicts a UML class diagram of portlet requests and responses. A render request on the portal page results in the calling of the render() method on each portlet on the displayed page. When a user invokes an action on a particular portlet, typically an HTML form submission, the processAction() method of that portlet is invoked. The render() methods of all portlets on the same page are also invoked. Thus, an action request by the user translates into one invocation of a processAction() method and multiple invocations of render() methods. Figure 3 is a sequence diagram depicting the effect of invoking processAction() method and subsequent invocations of render() methods for the portlets on the same page. For further information, refer to the section on Processing Actions.

There are two overloaded init() methods, one with no-arguments and the other with an instance of javax.portlet.PortletConfig class. Note: There is a peculiar caveat about the init(PortletConfig) method. Failure to invoke super.init(aPortletConfig) results in a NullPointerException. The Init portlet in the included source code example illustrates this behavior (the source code is online at www.sys-con.com/weblogic/source.cfm).

Portlet Mode
JSR 168 defines three Portlet Modes: VIEW, EDIT, and HELP. A portlet instance can be in exactly one portlet mode at any time. Other custom portlet modes, such as config and source, are possible. The VIEW mode is the default mode. The portlet specification recommends that the EDIT mode allow the user of the portlet to customize the portlet instance and the HELP mode display the usage information about the portlet. A portlet must support the VIEW mode but the support of the EDIT mode and HELP mode in a portlet is optional. For example, the First portlet example does not support the EDIT mode or HELP mode.

Window State
JSR 168 defines three Window States: NORMAL, MINIMIZED, and MAXIMIZED. The portlet instance can be in exactly one window state at any time. Other custom window states, such as half-page, are also possible. In the NORMAL state, the portlet occupies a small part of the screen real estate. The screen real estate is shared with other portlets. In the MINIMIZED state, the contents of the portlet are hidden. In the MAXIMIZED state, the contents of the portlet occupy most of the screen real estate. Other portlets sharing the same page are hidden in the MAXIMIZED state. For example, the First portlet example supports all three Window States.

GenericPortlet Class
Most of the portlets you create will extend the javax.portlet.GenericPortlet class instead of directly implementing the javax.portlet.Portlet interface. The GenericPortlet class implements the render() method. If the portlet's window state is minimized, then the render() method doesn't do anything. If the portlet's window state is other than minimized, then the render() method sets the title specified in the portlet.xml file and invokes the doDispatch() method. Depending upon the Portlet Mode, the doDispatch() method invokes doView(), doEdit(), and doHelp() methods appropriately. Thus, the GenericPortlet class is more convenient to extend than the Portlet interface is to implement because the GenericPortlet class helpfully implements the render() method and provides easy doView(), doEdit(), and doHelp() methods to override.

Consider the First portlet example. The FirstPortlet class extends GenericPortlet. FirstPortlet overrides the doView() method:


  public void doView(RenderRequest request, RenderResponse response)
    throws PortletException, IOException
    response.getWriter().write("<p>Hello World</p>");

Note: Calling the getWriter() method before calling setContentType() method results in a java.lang.IllegalStateException.

Implementing Portlet Modes
The VIEW mode is mandatory but the EDIT and HELP modes are optional. In order to implement the EDIT and HELP portlet modes, implement the appropriate doEdit() and doHelp() methods in the portlet class. Refer to Mode portlet included in the source code example (source code for this article is online at www.sys-con.com/wldj/sourcec.cfm). In addition, you must configure the modes in the portlet.xml as follows:


Note: Changing the portlet.xml configuration file, but not implementing the corresponding methods in the portlet class, results in a javax.portlet.PortletException.

Implementing Window States
JSR 168 does not describe a way to disable support for Window States. However, WebLogic Portal implements the disabling of them. To disable a portlet's support for Window states, exclude the Window states in the weblogic-portlet.xml:


Refer to the State portlet included in the source code example.

Including JavaServer Pages (JSPs)
Consider the doView() method of the First portlet. This method gets the instance of the Writer and directly outputs HTML fragments. Outputting direct HTML fragments is usually not recommended for various reasons, such as trying to achieve a separation between Java logic and HTML view presentation. The recommended way is to display the view using a JSP. The methods in the portlet class execute business logic, set the render parameters, and include the JSP. To include a particular JSP, first get the PortletContext. From the PortletContext instance, get an instance of PortletRequestDispatcher by calling the getRequestDispatcher() method. Include the JSP by invoking the include() method. For example:

// execute the necessary logic here...
PortletRequestDispatcher aDispatcher =
aDispatcher.include(aRequest, aResponse);

Note: A portlet may use a PortletRequestDispatcher object only when executing the render() method.

Refer to the Include portlet in the source code. A JSP page, such as includeView.jsp, does not contain root HTML tags such as <html>, <title>, and <body> since the tags are provided by the portal framework. The JSP page contains only the HTML fragments necessary to display the portlet.

Processing Actions

In a standard Web application an HTML form submission results in executing some business logic. The results of business processing are either set in the request or session as attributes and forwarded or included to the next JSP.

In a JSR 168 portlet, what should the action URL for an HTML form be? JSR 168 defines a JSP tag library, known as portlet taglib. The action URL for an HTML form is generated using the actionURL portlet tag. For example (refer to favoriteColorEdit.jsp file):

<form action="<portlet:actionURL/>" method="post">

Submitting the HTML form results in invoking the processAction(ActionRequest aRequest, ActionResponse aResponse) method of the portlet. As usual, form parameters can be obtained by invoking getParameter() method of the request object. Note: Invoking the action by submitting the form, but not having the processAction() method in the portlet, results in a javax.portlet.PortletException.

The processAction() method sets the values in the response object. Do not use the setAttribute() method of the ActionRequest or ActionResponse object. The values will not be propagated from the processAction() to the render() method and will not be available in the JSP. Instead, use the setRenderParameter() method of the ActionResponse object. These render parameters will be available for all subsequent render requests and are quite different from typical Web application request attributes. The typical Web application request attributes are only valid for a request. On the other hand, the render parameters are valid for many subsequent render requests. The render parameters remain valid until the value is explicitly changed or removed by re-execution of the action.

Consider the FavoriteColor portlet. It displays a user's favorite color in the VIEW mode, but can be changed in the EDIT mode. Submitting the favorite color choice in the EDIT mode invokes the processAction() method. This method gets the favorite color request parameter and sets it as the render parameter. Thus, the favorite color render parameter is available in all subsequent render requests.

How are the rendered parameters displayed on the JSP? Use the defineObjects tag from the portlet taglib to define portlet objects. This tag makes renderRequest, renderResponse, and portletConfig portlet objects available in the page. A parameter is displayed by invoking the getParameter() method of the renderRequest object. Refer to favoriteColorView.jsp in the included source code example.

The FavoriteColor portlet demonstrates other concepts as well. The first is how to programmatically change the portlet mode in the processAction() method. Invoke the setPortletMode() method of the ActionResponse object to change the portlet mode. The second concept is how to change the portlet mode using an HTML link. The link URL is generated using the renderURL tag from the portlet taglib. The value for the portletMode attribute is specified as the desired portlet mode. Refer to FavoriteColorPortlet class and favoriteColorView.jsp page included in the source code example.

Portlet Preferences

Portlet preferences are the basic configuration data for portlets. A preference is a name and value pair. The type of name is a string, whereas the type of value is either a string or an array of strings. A portlet preference is not suited for storing arbitrary data. The portlet container provides persistence for portlet preferences. In WebLogic Portal, the persistence for preferences works only when both of the following conditions are true:

  • The portal is running in the desktop instead of DOT portal mode.
  • A user is logged in.

Desktop Versus DOT Portal Mode
When a .portal file is created in WebLogic Workshop, items such as books, pages, and portlets are dragged-and-dropped into the .portal file and the .portal file can be run directly from within Workshop. However, certain features, like storing of preferences, are not available when running in this DOT portal mode. (DOT portal mode is also known as Single File Mode.)

The other mode is known as desktop mode. Using the Portal Administrator a portal is created. Within the portal, a desktop is created. Items such as books, pages, and portlets are created and placed within the desktop. In this mode, certain features, like storing of preferences, are available. (The desktop mode is also known as Streamed Mode.)

Before we go on, create a desktop:

  • Launch Portal Administration (e.g., http://localhost:7001/JSR168PortalAppAdmin/). One way to launch Portal Administration is directly from Workshop. Select the Portal menu and Portal Administration menu item.
  • Log in to the Portal Administration.
  • Create a new portal (e.g., JSR168).
  • Inside the portal, create a new desktop (e.g., d1).
  • Add the LoginPortlet to one of the pages of the desktop.
  • Add the ContactPortlet to one of the pages of the desktop.

Portlet Preferences Example
The Contact portlet demonstrates Portlet Preferences. Portlet Preferences can be static or dynamic. Static preferences are specified in the portlet.xml file together with the portlet. For example, the ContactPortlet has a preference named contact-preference. The default value of the contact-preference is also specified:


Dynamic preferences are not predefined in the portlet.xml configuration file. These preferences are stored and retrieved as the portlet is running. At runtime, an instance of the javax.portlet.PortletPreferences interface contains the preferences. The instance is obtained by invoking the getPreferences() method on the PortletRequest object. The value of a particular preference is obtained by invoking the getValue() method on the preferences instance.

Invoking the setValue() method of the preferences instance updates a preference value. However, an additional step is required to commit the changes. The store() method of the preferences instance is invoked to persist the preferences. Preferences can only be modified in the processAction() method. Any changes made to the preferences instance are discarded if the store() method is not invoked in the processAction() method. Note: As I mentioned earlier, if the user is not logged in or the portal is in the DOT portal mode, calling the store() method results in a runtime exception.

There are quite a few similarities between portlets and servlets. However, there are crucial differences as well. The portlet specification builds upon the servlet specification. The portlet container resides within the servlet container. Just as servlets are deployed within a Web application, so are portlets. Servlets and Web applications are configured using the web.xml. Portlets are configured using the portlet.xml file. A servlet has an explicit life cycle: init(), doGet(), doPost(), etc. Similarly, a portlet has an explicit life cycle: doView(), doEdit(), processAction(), etc. Methods of servlet and portlet classes must be coded in a thread-safe manner.

However, there are crucial differences as well. Servlets are allowed to do include, forward, and redirect, whereas portlets are only allowed to include. Servlets can render a complete page, whereas portlets render only page fragments. Portlets have well-defined portlet modes and Window states, unlike servlets. Portlets have more formal request handling with render requests and action requests and they have preferences. A portlet is not a servlet!


I started this article by describing the creation of portlets with a simple wizard. I illustrated the life cycle of the portlet and the inner workings of the portlet class implementation and described the structure and semantics of the portlet.xml configuration file and the corresponding weblogic-portlet.xml configuration file. I explained various concepts such as portlet modes and window states. I demonstrated the usage of portlet taglib and form processing in the portlet. Finally, I explained how to leverage and work with portlet preferences. Armed with the knowledge and concepts described in this article you're on your way to creating and deploying your own powerful portlets.


I want to thank Subbu Allamaraju, Max Cooper, Steve Ditlinger, David Lu, Roshni Malani and Alex Toussaint for reviewing this article and providing invaluable feedback.


  • To discuss the article and ask questions start here: www.bartssandbox.com. Free membership is required.
  • Download and read JSR 168: www.jcp.org/en/jsr/detail?id=168
  • Starting point for WebLogic Portal documentation: e-docs.bea.com/wlp/docs81/index.html
  • Building Java Portlets section of the Workshop Help: e-docs.bea.com/workshop/docs81/doc/en/core/index.html
  • Developing JSR 168 Portlets with WebLogic Portal 8.1: dev2dev.bea.com/products/wlportal81/articles/JSR168.jsp
  • Web Services for Remote Portlets (WSRP) specification: www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp
  • Take WSRP for a test drive: dev2dev.bea.com/codelibrary/code/wsrp_supportkit.jsp
  • Single File Mode versus Streamed Rendering Mode: Click Here !
  • Articles on Portlet Specification:
    - Introducing Portlet Specification, Part 1:
    - Introducing Portlet Specification, Part 2:
  • Introduction to JSR 168 whitepaper: Click Here !
  • Java Passion Portlet Lecture Notes: www.javapassion.com/j2eeadvanced/Portlet4.pdf
  • More Stories By Prakash Malani

    Prakash Malani has extensive experience in architecting, designing, and developing object-oriented software and has done software development in many application domains such as entertainment, retail, medicine, communications, and interactive television.He practices and mentors leading technologies such as J2EE, UML, and XML. Prakash has published various articles in industry- leading publications.

    Comments (3) View Comments

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.

    Most Recent Comments
    anjz 01/11/08 03:03:27 AM EST

    hey i am facing problem with action url
    i am getting exception
    the action url is returning null
    i am trying to submit a register form and on sumbit its supposed to print the values entered
    its not working as expected please help

    ANil Grover 02/25/05 12:25:35 AM EST

    I liked it, its really a nice article

    Bhaskar 11/21/04 05:23:36 AM EST

    its very nice keep on writing on this topic...we need more information...All the best

    @ThingsExpo Stories
    SYS-CON Events announced today that Calligo, an innovative cloud service provider offering mid-sized companies the highest levels of data privacy and security, has been named "Bronze Sponsor" of SYS-CON's 21st International Cloud Expo ®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Calligo offers unparalleled application performance guarantees, commercial flexibility and a personalised support service from its globally located cloud plat...
    IoT is at the core or many Digital Transformation initiatives with the goal of re-inventing a company's business model. We all agree that collecting relevant IoT data will result in massive amounts of data needing to be stored. However, with the rapid development of IoT devices and ongoing business model transformation, we are not able to predict the volume and growth of IoT data. And with the lack of IoT history, traditional methods of IT and infrastructure planning based on the past do not app...
    With tough new regulations coming to Europe on data privacy in May 2018, Calligo will explain why in reality the effect is global and transforms how you consider critical data. EU GDPR fundamentally rewrites the rules for cloud, Big Data and IoT. In his session at 21st Cloud Expo, Adam Ryan, Vice President and General Manager EMEA at Calligo, will examine the regulations and provide insight on how it affects technology, challenges the established rules and will usher in new levels of diligence...
    SYS-CON Events announced today that DXWorldExpo has been named “Global Sponsor” of SYS-CON's 21st International Cloud Expo, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Digital Transformation is the key issue driving the global enterprise IT business. Digital Transformation is most prominent among Global 2000 enterprises and government institutions.
    SYS-CON Events announced today that Datera, that offers a radically new data management architecture, has been named "Exhibitor" of SYS-CON's 21st International Cloud Expo ®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Datera is transforming the traditional datacenter model through modern cloud simplicity. The technology industry is at another major inflection point. The rise of mobile, the Internet of Things, data storage and Big...
    In his session at @ThingsExpo, Sudarshan Krishnamurthi, a Senior Manager, Business Strategy, at Cisco Systems, discussed how IT and operational technology (OT) work together, as opposed to being in separate siloes as once was traditional. Attendees learned how to fully leverage the power of IoT in their organization by bringing the two sides together and bridging the communication gap. He also looked at what good leadership must entail in order to accomplish this, and how IT managers can be the ...
    DX World EXPO, LLC., a Lighthouse Point, Florida-based startup trade show producer and the creator of "DXWorldEXPO® - Digital Transformation Conference & Expo" has announced its executive management team. The team is headed by Levent Selamoglu, who has been named CEO. "Now is the time for a truly global DX event, to bring together the leading minds from the technology world in a conversation about Digital Transformation," he said in making the announcement.
    Everything run by electricity will eventually be connected to the Internet. Get ahead of the Internet of Things revolution and join Akvelon expert and IoT industry leader, Sergey Grebnov, in his session at @ThingsExpo, for an educational dive into the world of managing your home, workplace and all the devices they contain with the power of machine-based AI and intelligent Bot services for a completely streamlined experience.
    In the enterprise today, connected IoT devices are everywhere – both inside and outside corporate environments. The need to identify, manage, control and secure a quickly growing web of connections and outside devices is making the already challenging task of security even more important, and onerous. In his session at @ThingsExpo, Rich Boyer, CISO and Chief Architect for Security at NTT i3, discussed new ways of thinking and the approaches needed to address the emerging challenges of security i...
    While the focus and objectives of IoT initiatives are many and diverse, they all share a few common attributes, and one of those is the network. Commonly, that network includes the Internet, over which there isn't any real control for performance and availability. Or is there? The current state of the art for Big Data analytics, as applied to network telemetry, offers new opportunities for improving and assuring operational integrity. In his session at @ThingsExpo, Jim Frey, Vice President of S...
    "DX encompasses the continuing technology revolution, and is addressing society's most important issues throughout the entire $78 trillion 21st-century global economy," said Roger Strukhoff, Conference Chair. "DX World Expo has organized these issues along 10 tracks with more than 150 of the world's top speakers coming to Istanbul to help change the world."
    "We provide IoT solutions. We provide the most compatible solutions for many applications. Our solutions are industry agnostic and also protocol agnostic," explained Richard Han, Head of Sales and Marketing and Engineering at Systena America, in this SYS-CON.tv interview at @ThingsExpo, held June 6-8, 2017, at the Javits Center in New York City, NY.
    "We are focused on SAP running in the clouds, to make this super easy because we believe in the tremendous value of those powerful worlds - SAP and the cloud," explained Frank Stienhans, CTO of Ocean9, Inc., in this SYS-CON.tv interview at 20th Cloud Expo, held June 6-8, 2017, at the Javits Center in New York City, NY.
    "We've been engaging with a lot of customers including Panasonic, we've been involved with Cisco and now we're working with the U.S. government - the Department of Homeland Security," explained Peter Jung, Chief Product Officer at Pulzze Systems, in this SYS-CON.tv interview at @ThingsExpo, held June 6-8, 2017, at the Javits Center in New York City, NY.
    The financial services market is one of the most data-driven industries in the world, yet it’s bogged down by legacy CPU technologies that simply can’t keep up with the task of querying and visualizing billions of records. In his session at 20th Cloud Expo, Karthik Lalithraj, a Principal Solutions Architect at Kinetica, discussed how the advent of advanced in-database analytics on the GPU makes it possible to run sophisticated data science workloads on the same database that is housing the rich...
    Internet of @ThingsExpo, taking place October 31 - November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA, is co-located with 21st Cloud Expo and will feature technical sessions from a rock star conference faculty and the leading industry players in the world. The Internet of Things (IoT) is the most profound change in personal and enterprise IT since the creation of the Worldwide Web more than 20 years ago. All major researchers estimate there will be tens of billions devic...
    What sort of WebRTC based applications can we expect to see over the next year and beyond? One way to predict development trends is to see what sorts of applications startups are building. In his session at @ThingsExpo, Arin Sime, founder of WebRTC.ventures, discussed the current and likely future trends in WebRTC application development based on real requests for custom applications from real customers, as well as other public sources of information.
    "The Striim platform is a full end-to-end streaming integration and analytics platform that is middleware that covers a lot of different use cases," explained Steve Wilkes, Founder and CTO at Striim, in this SYS-CON.tv interview at 20th Cloud Expo, held June 6-8, 2017, at the Javits Center in New York City, NY.
    SYS-CON Events announced today that Massive Networks will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Massive Networks mission is simple. To help your business operate seamlessly with fast, reliable, and secure internet and network solutions. Improve your customer's experience with outstanding connections to your cloud.
    "MobiDev is a Ukraine-based software development company. We do mobile development, and we're specialists in that. But we do full stack software development for entrepreneurs, for emerging companies, and for enterprise ventures," explained Alan Winters, U.S. Head of Business Development at MobiDev, in this SYS-CON.tv interview at 20th Cloud Expo, held June 6-8, 2017, at the Javits Center in New York City, NY.