Skip navigation
All Places > Blackboard Developer Community > Blackboard Learn Developers > Blog > Author: mkauffman
1 2 3 4 Previous Next

Blackboard Learn Developers

58 Posts authored by: mkauffman

We've had many developers run into issues around site quotas and rate limits when moving their REST application into production use. To help smooth your transition to production we've published this document Developer Groups, Site Quotas, and Rate Limits  Please read it and give us your comments/questions. I won't say more here, the document should speak for itself! 

I'm writing this to show an easy way to test your REST API calls. This brief video shows you how to go about it. In the video we also answer a question about the Gradebook REST APIs. The question was whether the letter grade shows up in the REST call results when the letter grade is secondary. Watch to the video to find out, and learn how you can quickly troubleshoot REST API calls!


Update: We brought this to the attention of the development team with JIRA ticket API-1084. They've been clear in stating this is functioning as designed. Should you require different behavior, bring it to our attention on

This came up as a question from a developer, "How do I create a course in Learn that has a different course ID than the external Id? (The external Id is also often referred to as the batch UID.) The answer is to use the SIS Flat-File integration capability of Learn that is available on the System Administration tab. You can log in as a Learn administrator on a Learn system and follow along with the example given in this video: Create and Upload Courses Using a Flat File


For reference the documentation is given here:

Student Information System (SIS) | Blackboard Help

Create and Edit SIS Integrations | Blackboard Help

SIS Feed Files | Blackboard Help

Snapshot Flat File Examples | Blackboard Help

Course Examples | Blackboard Help

Hi All,


This topic comes up often regarding Learn versions, "How do I map the Learn release names to the build numbers?" One of our clients referred to finding the answer as "finding the secret decoder ring, or discovering the location of the Rosetta Stone." I'm writing this Blog post to share how I go about finding the answer.


It's simple. Just log in to Behind the Blackboard and use the search tool to look for the most recent release. I just entered "Q2 2017 CU4." There is no such release yet, but Cumulative Update 3 for Blackboard Learn, 9.1 Q2 2017 came up. Now scroll down the page and you will see the Upgrade Paths listed, which also maps the Release Names to the Build Numbers as shown below. And there you have it, your very own Secret Decoder Ring mapping of Learn Release Names to Build Numbers.




Posted by mkauffman Aug 4, 2017

This recently came up as a question from a partner, "In SaaS, can a external program call a JSP in the NOSESSION directory and thereby bypass Bb authentication?  This was possible in self and managed hosting of Learn."


I posted the question to our subject matter experts and got several responses that are quite helpful:

  1. You can just add authentication=“N” as an attribute to the <…Page> tag. Obviously, not recommended, nor ideal. Calling an endpoint remotely should have some sort of protection, even if it’s not via Learn. JSP seems like the worst way to accomplish this.
  2. Other than error pages, the only valid purpose I can see for requests NOT using a BbSession is a server/app/db liveness check, and we already have the /webapps/portal/healthCheck servlet for that purpose (which is a nosession servlet, and the only one we have in the app other than error pages). You really don't want to create a session for such requests that should merely check whether the server is up, but you also really shouldn't bombard the server with a multitude of such checks from different tools, or you're bound to introduce stability issues.
  3. There are other valid reasons I can think of.. The scorm AICC endpoint, the webservice endpoints etc all have their own authentication methods that don’t want a learn session. But I agree that they should be very careful about an unauthenticated endpoint.


Finally, when I mention JSPs being used as endpoints to our architects they all say that it far better to code using an MVC architecture where the endpoints are Java classes* (i.e. a method in a Spring controller) and JSPs are only used for the views. Both the JSP Model 1 and Model 2 architectures described here separate out logic from presentation.


*Not Java classes that are the result of the JSPs being compiled to Java.

When Blackboard migrates a self or managed-hosted system to SaaS, the migration team and client sometimes choose to do a full database migration in order to maintain existing content. Your B2's database tables will be migrated by this process, but if your B2 code relies on any database sequences, you'll need to work with the migration team to ensure that the sequences are correctly set up on the new SaaS system as well.


Bye Bye BBLEARN & bb_bb60

Posted by mkauffman May 14, 2017

Please read carefully. Your integration will break in SaaS if you have issues caused by hard-coded use of BBLEARN and bb_bb60. Though the title is a bit-overdramatic and BBLEARN and bb_bb60 will still be around on self-hosted and managed-hosted systems, they are gone in SaaS.


BBLEARN are bb_bb60 are the schema names used on many self and managed-hosted systems. These are no longer used on SaaS systems. Instead a long string like BB589bd9cca452e is used as the schema name. Every SaaS system will have a different schema name for its database. This means that no external system can make assumptions about the schema name and no B2 code can count on some particular set of values. All code must dynamically determine the schema name, or at the very least it must be set up during configuration. The Learn Java API blackboard.platfomr.plugin.PlugInUtil.getUriStem method can be used to get the complete B2 web application name, including the schema name. For example, on, String uriStem = PlugInUtil.getUriStem("bbdn", "bblogbackb2"); currently returns the string: /webapps/bbdn-bblogbackb2-BB56d7008520956/ See GitHub - mark-b-kauffman/bbdn-bblogbackb2: Demo the use of Logback to create log files.   for example use code.


Should your B2 be exposing Web Service endpoints and your external server assumes the endpoint is either BBLEARN or bb_bb60, the fact that SaaS now uses a different schema name on every SaaS system will cause problems for your integration. You external server must now be given either programmatically, or during configuration, the actual schema name so that it can make calls to valid URIs for each Learn system.  The more dynamic you make your code, the better.


The other case that will cause issues is if your B2 code refers to itself on the Learn system using URIs that it assumes contain either bb_bb60 or BBLEARN. The code must no longer make that assumption. Instead use PlugInUtil.getUriStem() to determine the actual value.


A brief video explanation - 2017-05-18_1526

Please read ALL FILES No More

For self-hosted Unix installations see How much longer will Red Hat 5 be supported?


Blackboard Learn Mobile

Posted by mkauffman Mar 7, 2017

We've had several developers ask about registering Mobile Web Services. The first step is to read this article on how to Configure and Register Blackboard Mobile Web Services. After reading, the common roadblock is filling out the registration form, hitting submit, and then the page reloads with the default values, like nothing happened. What's wrong? The answer is that the server must be on the public internet and have a valid SSL certificate installed. This has to be because the Mobile service is a cloud service that talks back to your Learn instance.

This just in. bb-manifest.xml files will not upload to SaaS when the XML does not meet the standard: Extensible Markup Language (XML) 1.0 (Second Edition) .As we don't check this in Self and Managed-hosted systems, you may have had URLs in your bb-manifest.xml file using the following format:

<url value="itemanalysis/showItemAnalysis?action=display&;course_id=@X@course.pk_string@X@" />


These should be written as follows because the & character in XML must be encoded:

<url value="itemanalysis/showItemAnalysis?action=display&amp;course_id=@X@course.pk_string@X@" />

I’m writing this to let you know that we’ve run into a new issue with the SAML B2 on a few Learn systems that then causes problems for other B2s that make outbound connections from Learn. We're still working to determine the Learn & SAML B2 versions affected. To date we've seen this on a Q2 2016 system with the 3000.1.0 version of SAML, and a SaaS 3100.9 system running version 3100.9 of SAML.


If the lines shown below are found in the stdout-stderr logs, please open a ticket using your Behind the Blackboard account, include the logs, the Learn version, and the version of the SAML authorization B2. Reference LRN-121348 early in the case description so that support is aware that this is a known issue. While you're on Behind the Blackboard, be sure to subscribe to the Learn support bulletins (Top menu, My Account, MY SUBSCRIPTiONS).


Here are the lines your will see in the stdout-stderr files on an affected system; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'keyManager' defined in ServletContext resource [/WEB-INF/config/saml/securityContext.xml]: Invocation of init method failed; nested exception is java.lang.RuntimeException: Unable to load aliases from keyStore


There may be other exceptions that the SAML B2 throws that will cause the issue. The above is one example. The main point is that for this issue to occur the SAML B2 must throw an exception and stop running.


... then later in the log file ...

INFO   | jvm 2    | < information about your B2 wil be here>  threw exception [Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/httpclient/params/HttpConnectionParams] with root cause

INFO   | jvm 2    | 2017/02/15 18:55:54 | java.lang.NoClassDefFoundError: org/apache/commons/httpclient/params/HttpConnectionParams

INFO   | jvm 2    | 2017/02/15 18:55:54 |     at

INFO   | jvm 2    | 2017/02/15 18:55:54 |     at


The main point of the above is that we can see that your B2 threw an error because the system was incorrectly handing it the SAML socket factory.

This came up in a recent case with a Partner. Their B2 is exposing a new endpoint in Learn for their external server make calls to. (Example: webapps/abc-myb2-VeryLogSaaSDBschemaName/MyEndpoint) Everything worked fine on their test system. But when they deployed to a recent 3100 build, the calls the external server made were not getting through to Learn. Why? Because newer builds of Learn have the 'Security Management: Cookie Disclosure' B2 installed and active. This B2 forces you to accept Blackboard's Cookie Disclosure Agreement before logging in. It also blocks incoming calls to endpoints like that described. There is no impact on our REST APIs. I've not checked our Web Service SOAP APIs yet... In any case, how do you work around it? Put a cookie in your cookie jar. Just set a cookie with name="COOKIE_CONSENT_ACCEPTED" and path="/" in your cookie jar, so it's sent with every request. Hope this helps the next developer who runs into this one!