huanghaibin-dev/CalendarView · error
e.printStackTrace()
Error message
e.printStackTrace()
What it means
In the CalendarViewDelegate constructor, Class.forName resolves the custom WeekBar class from app:calendar_week_bar_view. If the class path string names a class not on the classpath, Class.forName throws and printStackTrace hides it, leaving mWeekBarClass as the assignment result of the ternary chain rather than the intended custom class.
Solutions
- Fix app:calendar_week_bar_view in XML to the exact fully-qualified class name (package + class).
- Confirm the class exists and is public in a module included as a dependency.
- Add a keep rule so shrinking tools don't remove/rename the class.
- Check logcat for the ClassNotFoundException stack trace to confirm.
- If no custom week bar is needed, remove the attribute so the default WeekBar is used.
Example fix
// before app:calendar_week_bar_view="com.example.views.WeekBarView" // after (class moved to com.example.ui) app:calendar_week_bar_view="com.example.ui.WeekBarView"
Defensive patterns
Strategy: validation
Validate before calling
// Validate the XML attribute value before inflating the CalendarView:
String path = "com.example.MyWeekBar";
Class<?> cls = Class.forName(path); // will throw ClassNotFoundException early if wrong
if (!WeekBar.class.isAssignableFrom(cls)) throw new IllegalStateException("Not a WeekBar");
Type guard
static boolean isLoadableWeekBar(String path) {
try { return WeekBar.class.isAssignableFrom(Class.forName(path)); }
catch (Throwable t) { return false; }
} Try / catch
// Library swallows the exception; wrap your own initialization to detect it:
try {
setContentView(R.layout.activity_calendar);
} finally {
if (calendarView.getWeekBar() == null) {
Log.e("Calendar", "Custom week bar failed to load; check calendar_week_bar_view");
}
} Prevention
- Copy the fully-qualified class name from the class file/package declaration, never by hand.
- After renaming a package, grep XML/attrs for the old package name.
- Enable -keep rules for classes referenced from XML.
- Verify in a release build with minification enabled before shipping.
When it happens
Trigger: app:calendar_week_bar_view set to a misspelled or renamed fully-qualified class name; the class exists in a different module/dependency not included; class removed by shrinking tools.
Common situations: Copy-pasting a config from a tutorial with a package name that doesn't match the project; refactoring a package without updating XML attributes; release builds with ProGuard stripping the view class.
Related errors
AI-assisted analysis of huanghaibin-dev/CalendarView@f5479ea3ba (2026-09-11).
Data as JSON: /api/errors/1fffa5dd3dfed044.
Report an issue: GitHub.
Appendix: source
Thrown at calendarview/src/main/java/com/haibin/calendarview/CalendarViewDelegate.java:560
array.recycle();
init();
}
private void init() {
mCurrentDate = new Calendar();
Date d = new Date();
mCurrentDate.setYear(CalendarUtil.getDate("yyyy", d));
mCurrentDate.setMonth(CalendarUtil.getDate("MM", d));
mCurrentDate.setDay(CalendarUtil.getDate("dd", d));
mCurrentDate.setCurrentDay(true);
LunarCalendar.setupLunarCalendar(mCurrentDate);
setRange(mMinYear, mMinYearMonth, mMaxYear, mMaxYearMonth);
try {
mWeekBarClass = TextUtils.isEmpty(mWeekBarClassPath) ?
mWeekBarClass = WeekBar.class : Class.forName(mWeekBarClassPath);
} catch (Exception e) {
e.printStackTrace();
}
try {
mYearViewClass = TextUtils.isEmpty(mYearViewClassPath) ?
mYearViewClass = DefaultYearView.class : Class.forName(mYearViewClassPath);
} catch (Exception e) {
e.printStackTrace();
}
try {
mMonthViewClass = TextUtils.isEmpty(mMonthViewClassPath) ?
DefaultMonthView.class : Class.forName(mMonthViewClassPath);
} catch (Exception e) {
e.printStackTrace();
}
try {
mWeekViewClass = TextUtils.isEmpty(mWeekViewClassPath) ?
DefaultWeekView.class : Class.forName(mWeekViewClassPath);
} catch (Exception e) {View on GitHub (pinned to f5479ea3ba)