Friday
June 29
Protected: Course Cartridge Confirmation Email
By gaudette
Enter your password to view comments.
Friday
June 29
By gaudette
Enter your password to view comments.
Tuesday
June 23
By gaudette
Attempting to load assessment in Course Documents of (http://blackboard.bu.edu/webapps/bb-selfpeer-bb_bb60/contentType/view.jsp?course_id=_1155_1&content_id=_103827_1) results in the following. Proceding with restart of nodes. Error noticed on n4.
null
java.lang.NullPointerException at blackboard.web.contentType.view_jsp._jspService(view_jsp.java:80) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98) at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) at sun.reflect.GeneratedMethodAccessor5924.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:244) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAsPrivileged(Subject.java:517) at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:276) at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:162) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:262) at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:52) at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:171) at java.security.AccessController.doPrivileged(Native Method) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:167) at blackboard.platform.servlet.ContentTypeFilter.doFilter(ContentTypeFilter.java:56) at sun.reflect.GeneratedMethodAccessor2394.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:244) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAsPrivileged(Subject.java:517) at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:276) at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:218) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:52) at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:171) at java.security.AccessController.doPrivileged(Native Method) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:167) at blackboard.platform.servlet.RequestSessionFilter.handleRequest(RequestSessionFilter.java:351) at blackboard.platform.servlet.RequestSessionFilter.doFilter(RequestSessionFilter.java:177) at sun.reflect.GeneratedMethodAccessor2393.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:244) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAsPrivileged(Subject.java:517) at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:276) at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:218) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:52) at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:171) at java.security.AccessController.doPrivileged(Native Method) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:167) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174) at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:200) at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:283) at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:773) at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:703) at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:895) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689) at java.lang.Thread.run(Thread.java:595)
By gaudette
I have figured out the problem with making jsp changes appear, and learned a good deal about jsp compilation.
There is a component of tomcat called Jasper that is responsible for dynamically compiling jsp pages. In its default settings (“development” mode), it checks a jsp everytime it is loaded to see if it has changed since last compiled. If it has, it recompiles it. These are the java classes that show up in $tomcat/work/. The settings for this are in the $tomcat/conf/web.xml file, in the <servlet-name>jsp</servlet-
However, most of the jsps used in blackboard are precompiled. This means that the class files are distributed with the application, and rather than have tomcat compile the JSPs automatically there is a servlet mapping for the jsp name to the java class that came with the app. Tomcat does not even look at the jsps in this case, the request is handled directly by the java class according to the mapping. The jsp and java files like top_frame.jsp and top_frame.java are just byproducts of the compilation, we’re lucky they are there at all. This precompilation process is also responsible for the generated_web.xml file. It contained the servlet mappings for each of the precompiled jsps, and at the end of the compilation process is included in the actual web.xml.
So, the right way to fix this would be to use ant’s JSPC task to recompile the modified jsps according to the same method blackboard would have used to compile it. I know little about ant and setting it up seemed like a nightmare. The second best way would probably be to modify the .java file (which was created as an intermediate step in the compilation) and use javac to compile it. However, I couldn’t seem to get the classpath right, so I kept getting all sorts of compile errors and gave up (eventually I suppose we could get it accomplished).
So what I’ve actually done is commented out the servlet mapping for top_frame.jsp and top_frame_small.jsp, so that rather than using the precompiled classes it compiles them dynamically like an ordinary jsp. Every time the page is loaded, it checks the date on the class file in $tomcat/work against the date on the jsp to see if it needs to be recompiled. This incurs some overhead, probably not much but then again this is a frame that will likely get loaded on just about every page view. What I had hoped to do was take the resulting class file out of the work directory, put it in with the other precompiled classes and replace the servlet mappings. However, this caused an error because when tomcat compiles the class itself it changes the package hierarchy from com/blackboard/whatever/class to org/apache/tomcat/jsp/top_frame.class.
The upside of keeping it dynamic, of course, is that any future modifications will take effect immediately.
Tuesday
March 31
By gaudette
New BU section in authentication.properties (note – This can be left in place even if module is not in use as configured by bb-config.properties):
########################################################
##
## BU Authentication Properties
##
## Extends ExternalAuthModule (Web Server Delegation)
##
########################################################
auth.type.bu.impl=blackboard.authentication.buAuthModule
# Acceptable entries for user_account are: reconcile, create, deny
auth.type.bu.user_account=deny
# Enter the allowed domains ( separated by commas )
auth.type.bu.allowed_domains=DC,AZ
# Accepted values for def_key are BatchUid or UserRegistry
auth.type.bu.def_key=BatchUid
# If users succeed in authenticating to WebLogin but are not in the Blackboard system redirect here:
auth.type.bu.url_for_error_page=’http://www.bu.edu/webcentral/help/courseware/’
Wednesday
March 25
By gaudette
We are doing load-balancing by using the built-in load-balancing features of Apache 2.2.11.
To do this, we had to assign a unique value on each server for the “jvmRoute” attribute in the <Engine> tag
in the file at [blackboard]/apps/tomcat/conf/server.xml. All three of our application servers’ Tomcat servers were configured by the Blackboard 8 installer to use the value “root” for the jvmRoute attribute. As a result, all three were producing JSESSIONID cookies with a content value ending in .root. I found no Blackboard documentation indicating that the jvmRoute should be updated to be unique, however it seems entirely necessary.
The explanation I got from Blackboard support implies that they expect the responding server to communicate directly with the load balancer (in their example, hardware), allowing the load balancer to determine the IP address of the responding server and then modify the cookie to include the IP address of the responding server. Our back-end servers reply directly to the end-user. Perhaps the stock Apache front-end that ships with Apache would have worked that way, though I can’t imagine Tomcat communicating with the front-end server for outbound traffic (responses).
Additionally, some simple logic was added to the Apache load balencer to properly route traffic based on what it finds in the cookie — it does pattern matching on our unique jvmRoute values which are (surprise) “n2″, “n3″, and “n4″.
Wednesday
March 25
By gaudette
The default Blackboard home page is an ugly page with buttons to go to Login or browse the catalog. We want to start at the portal tab we have relabeled “My Courses”. This is easily accomplished (once you have deciphered Blackboard’s series of riddles) by replacing the contents of the file at [blackboard]/service/blackboard/webapps/portal/gateway.jsp with a JS redirect:
<script language=”javascript”>location.href=”/webapps/portal/frameset.jsp”</script>
Ignore the various index.[whatever] pages, as well as the frameset.jsp, etc.
Wednesday
March 25
By gaudette
Here is the (edited) history of my commands to back up files – file list derived from earlier blog entries mostly.
1 5:01 whoami
3 5:02 cd ~bbuser
5 5:02 mkdir bkup-for-upgrade
6 5:02 cd bkup-for-upgrade/
7 5:03 mkdir 8.0.209.0
8 5:03 cd 8.0.209.0/
10 5:04 mkdir -p content/vi/bb_bb60/branding
12 5:04 setenv bb ‘/local/services/blackboard’
14 5:05 cp -pir $bb/content/vi/bb_bb60/branding/* ./content/vi/bb_bb60/branding/
17 5:06 mkdir -p apps/tomcat/conf
18 5:06 cp $bb/apps/tomcat/conf/server.xml apps/tomcat/conf/
19 5:07 mkdir -p content/images/console/tabcorners
21 5:08 find $bb/content/images/console/tabcorners/ -mtime -300
23 5:09 find $bb/content/images/console/tabcorners/ -type f -mtime -300 -exec cp {} content/images/console/tabcorners/ \;
28 5:10 mkdir config
29 5:10 cp -pir $bb/config/* ./config/
30 5:10 mkdir -p docs/ui/styles
31 5:11 cp $bb/docs/ui/styles/blackboard.css ./docs/ui/styles/
32 5:11 cp $bb/docs/ui/styles/palette.css ./docs/ui/styles/
33 5:15 mkdir -p content/ui/
34 5:16 cp -pir $bb/content/ui/logout.htm ./content/ui/
35 5:16 cp -pir $bb/content/ui/jx.js ./content/ui/
36 5:17 mkdir -p config/internal/
38 5:17 cp $bb/config/internal/images-*c*.txt ./config/internal/
39 5:18 mkdir -p webapps/portal/
40 5:18 cp $bb/webapps/portal/gateway.jsp ./webapps/portal/
Tuesday
March 10
By gaudette
Thank you for contacting Blackboard support regarding the “Error loading Content System status.” that is repeating in the bb-services-log.txt
Here is Blackboard’s response:
If you don’t have Content System, please implement the provided workaround of inserting the application record.
INSERT INTO application (pk1, application, enabled_mask, ssl_ind, relabel_ind, label, type, allow_guest_mask, allow_observer_mask, name, can_relabel_ind, can_allow_guest_ind, can_allow_observer_ind, can_configure_ind)
VALUES (application_seq.nextval, ‘bbcms’, 0, ‘N’, ‘Y’, ‘bbcms.label’, ‘SHARED’, 0, 0, ‘bbcms.label’, ‘Y’, ‘N’, ‘N’, ‘N’);
Note that the SQL syntax was just a little off — I think the issue was the lack of schema name “INSERT INTO [schema].application”
Friday
February 6
By gaudette
Enter your password to view comments.
Friday
July 18
By gaudette
PurgeAccumulator is broken for our platform – so zeros show for each statistic in the Administrator’s System Reporting results. Technote here.
Basically,
<task-entry key=”bb.stats.purging” version=”60″>
…
</task-entry>
00 1 * * * /usr/local/blackboard/tools/admin/PurgeAccumulator.sh purge-live bb_bb60 180
November 6, 2008