I've come into a little problem with some legacy code from the 2016 control system. I'm trying to control the adis16448 board with this library
which compiled fine in the 2016 wpilibj, but doesn't compile in the 2017 version. Now, I'd like to get this up and running quickly without having to wait for the dev to update, and there are actually only two errors.
Relevant code here:
private static class InterruptSource extends DigitalSource {
public InterruptSource(int channel) {
initDigitalPort(channel, true);
}
}
First is that the InterruptSource class has some unimplemented methods from the parent class. I just added empty definitions for these and that error obviously went away. Next is that the method initDigitalPort is not defined from the parent class. This is the part that I get stuck on.
Upon examination of the API Javadoc, the Source Code on github, and the context of this code, I still can't seem to figure out what this does or how to fix it. I'm guessing this has been depreciated in the 2017 wpilibj library.
My question is, what is the replacement method for initDigitalPort?
Forgive me for anything simple I've overlooked, we are a new FRC team so we have 0 experience with using wpilibj.
Also, it might help if I understood what the DigitalSource class actually does, it seems to involve encoders but that can't be right since this board has none. Could someone explain this to me?
Thanks, help is greatly apreciated!
The library in question has now been updated as of this commit. The new class is called DigitalInput and the initDigitalPort method is called in the constructor of this class which is given the parameter for the port.
Ex:
public InterruptSource(int channel) {
initDigitalPort(channel, true);
}
can be subsituted with
DigitalInput m_interrupt = new DigitalInput(10)
and will provide nearly the same functionality including class structure and methods.
private static class InterruptSource extends DigitalInput {
public InterruptSource(int channel) {
super(channel);
}
}
Related
So, this is something of a follow-on of this question. My current code looks something like this:
#Configuration
#EnableAutoConfiguration
#ComponentScan(basePackages = {"base.pkg.name"})
public class MyApp implements ServletContextAware {
private ThingDAO beanThingDAO = null;
public MyApp() {
// Lots of stuff goes here.
// no reference to servletContext, though
// beanThing gets initialized, and mostly populated.
}
#Bean publicD ThingDAO getBeanThingDAO() { return beanThingDAO; }
public void setServletContext(ServletContext servletContext) {
// all references to servletContext go here, including the
// bit where we call the appropriate setters in beanThingDAO
{
}
The problem is, it's not working. Specifically, my understanding was that setServletContext was supposed to be called by various forms of Spring Magic at some point during the startup process, but (as revealed by System.out.println()) it never gets called. I'm trying to finish up the first stage of a major bunch of refactoring, and for the moment it is of notable value to me to be able to handle the access to servletContext entirely inside of the #Configuration file. I'm not looking for an answer that will tell me that I should put it in the controllers. I'm looking for an answer that will either tell me how to get it working inside of the #Configuration file, or explain why that won't work, and what I can do about it.
I just ran into a very similar issue and while I'm not positive it's exactly the same problem I thought I'd record my solution in case it's helpful to others.
In my case I had a single #Configuration class for my spring boot application that implemented both ServletContextAware and WebMvcConfigurer.
In the end it turns out that Spring Boot has a bug (or at least undocumented restraint) that ServletContextAware.setServletContext() will never be called if you also implement WebMvcConfigurer on the same class. The solution was simply to split out a separate #Configuration class to implement ServletContextAware.
Here's a simple project I found that demonstrates and explains more what the problem was for me:
https://github.com/dvntucker/boot-issue-sample
The OP doesn't show that the bean in question was implementing both of these, but given the OP is using simplified example code I thought maybe the fact that the asker could have been implementing both interfaces in his actual code and might have omitted the second interface.
Well, I have an answer. It's not one I'm particularly happy with, so I won't be accepting it, but if someone with my same problem stumbles across this question, I want to at least give them the benefit of my experience.
For some reason, the ServletContextAware automatic call simply doesn't work under those circumstances. It works for pretty much every other component, though. I created a kludge class that looks something like this:
// This class's only purpose is to act as a kludge to in some way get
// around the fact that ServletContextAware doesn't seem to work on MyApp.
// none of the *other* spring boot ways of getting the servlet context into a
// file seem to work either.
#Component
public class ServletContextSetter implements ServletContextAware {
private MyApp app;
public ServletContextSetter(MyApp app) {
this.app = app;
}
#Override
public void setServletContext(ServletContext servletContext) {
app.setServletContext(servletContext);
}
}
Does the job. I don't like it, and I will be rebuilding things later to make it unnecessary so I can take it out, but it does work. I'm going to hold the checkmark, though, in case anyone can tell me either how to make it work entirely inside the #Configuration - decorated file, or why it doesn't work there.
Note that the #Component decorator is important, here. Won't work without it.
I am learning the LibGDX engine in parallel to re-learning java, and have written a simple logging class that has one method with a string argument to be passed to the Gdx.app.log(). while this isn't needed I did so to practice importing and using custom methods and classes, as well as reducing the length of the line needed to send a message to the console. the method looks like so:
import com.badlogic.gdx.Gdx;
public class logging {
public static final String tag="Console";
//contains method for logging to the console during testing.
public void log(String message){
Gdx.app.log(tag, message);
}
}
Then in the class I am using it in, it is imported properly, and a public logging 'con' is created. Up to this point everything seems to work fine because when I type con. in eclipse I get the log(message) as an autocomplete option, however when it is actually called for instance in a screen, under the show() method. when the program tries to step through that point i get a java.lang.NullPointerException which is confusing the hell out of me since everything is written properly. as an example of its use:
con.log("this is a test");
is the exact usage I attempt which seems fine in eclipse before runtime. Is there some simple idea I am failing to grasp here? or a quirk to the Gdx.app.log()? Please no responses with "just use the Gdx.app.log(); where you need to write to the log" as this is not the point of the exercise for me. thank you in advance for all the help!
If you are getting a NullPointerException in this line:
con.log("this is a test");
The only thing that can be null is con. You are probably defining it, but not actually creating it.
Logging con;
and not
Logging con = new Logging();
I think I've discovered a kind of Schrödinger's cat problem in my code. The body of a function is never executed if I change one line within the body of that same function; but if I leave that line alone, the function executes. Somehow the program knows ahead of time what the body is, and decides not to call it...
I'm working on an Eclipse RCP application in Java, and have need to use their Error Handling System. According to the page linked,
There are two ways for adding handlers to the handling flow.
using extension point org.eclipse.ui.statusHandlers
by the workbench advisor and its method {#link WorkbenchAdvisor#getWorkbenchErrorHandler()}.
So I've gone into my ApplicationWorkbenchAdvisor class, and overridden the getWorkbenchErrorHandler method:
#Override
public synchronized AbstractStatusHandler getWorkbenchErrorHandler()
{
System.out.println("IT LIVES!");
if (myErrorHandler == null)
{
AbstractStatusHandler delegate = super.getWorkbenchErrorHandler();
MyStatusHandler otherThing = new MyStatusHandler(delegate);
myErrorHandler = otherThing;
}
return myErrorHandler;
}
The MyStatusHandler is meant to act as a wrapper for the delegate handler. I've re-named the class for anonymity. As it is, above, this function is never called. The println never happens, and even in debug mode with breakpoints, they never trigger. Now the wierd part: If I change the line that assigns the myErrorHandler to
myErrorHandler = delegate;
then the function is called; multiple times, in fact!
This problem has me and two java-savvy coworkers stumped, so I'm hoping the good people of SO can help us!
As it turned out, my problem was that the MyErrorHandler class was defined in a different plugin, which presumably wasn't fully loaded yet. That doesn't seem to add up entirely, but once I moved the class definition of my error handler into the same plugin that was calling it during startup, the problems went away.
I have this warning on most of my classes and not sure why is that. This happens on both public normal classes and final classes which have private constructors, some no constructor at all. I tried changing my private class methods to protected, doesn't help. Any suggestions on how to turn this off?
Here's a class example
public final class PlanBenefitManagerAssembler {
private static final Logger LOGGER = Logger.getLogger(PlanBenefitManagerAssembler.class);
/**
* No Instance of the this class is allowed.
*/
private PlanBenefitManagerAssembler() {
}
public static List<BenefitDecisionDetailsBean> assembleBenefitDecisionDetailsBean(
List<BenefitDetails> benefitDecisionDetailsList, int relationalSequenceNumber) {
LOGGER.debug("Enter assembleBenefitDecisionDetailsBean");
List<BenefitDecisionDetailsBean> benefitDecisionDetailsBeanList = new ArrayList<BenefitDecisionDetailsBean>();
for (BenefitDetails benefitDecisionDetails : benefitDecisionDetailsList) {
BenefitDecisionDetailsBean benefitDecisionDetailsBean = new BenefitDecisionDetailsBean();
benefitDecisionDetailsBean.setBenefitTypeCode(benefitDecisionDetails.getBenefitTypeCode());
benefitDecisionDetailsBean.setRelationSequenceNumber(relationalSequenceNumber);
benefitDecisionDetailsBean.setBenefitStatusDescription(
benefitDecisionDetails.getBenefitStatusDescription());
benefitDecisionDetailsBean.setBenefitStatusCode(benefitDecisionDetails.getBenefitStatusCode());
benefitDecisionDetailsBean.setBenefitUnderwritingStatusCode(
benefitDecisionDetails.getBenefitUnderwritingStatusCode());
benefitDecisionDetailsBean.setBenefitUnderwritingStatusDescription(
benefitDecisionDetails.getBenefitUnderwritingStatusDescription());
benefitDecisionDetailsBean.setBenefitChangeReasonCode(
String.valueOf(benefitDecisionDetails.getBenefitChangeReasonCode()));
benefitDecisionDetailsBean.setBenefitChangeReasonDescription(
benefitDecisionDetails.getBenefitChangeReasonDescription());
benefitDecisionDetailsBean.setComponentNumber(benefitDecisionDetails.getBenefitNumber());
benefitDecisionDetailsBean.setBenefitVisible(benefitDecisionDetails.isExplicitBenefitDecisionRequired());
benefitDecisionDetailsBean.setModelChanged(false);
// * Set BenefitLoading and BenefitExclusion
List<ExclusionDetailsBean> exclusionDetailsBeanList =
PlanBenefitManagerAssembler.assembleExclusionDetailsList(benefitDecisionDetails
.getBenefitExclusionsDetailsList().getBenefitExclusionsDetailsList());
List<LoadingDetailsBean> loadingDetailsBeanList =
PlanBenefitManagerAssembler.assembleLoadingDetailsList(benefitDecisionDetails
.getBenefitLoadingsDetailsList().getBenefitLoadingsDetailsList());
benefitDecisionDetailsBean.setExclusionDetailsBeanList(exclusionDetailsBeanList);
benefitDecisionDetailsBean.setLoadingDetailsBeanList(loadingDetailsBeanList);
benefitDecisionDetailsBeanList.add(benefitDecisionDetailsBean);
}
LOGGER.debug("Exit assembleBenefitDecisionDetailsBean");
return benefitDecisionDetailsBeanList;
}
}
When Checkstyle produces a warning the warning text should include a short rule name which will allow you to look up the exact rule that is being triggered. "DesignForExtension", for example.
Given the rule name, you can look up more detail on what it means in the Checkstyle documentation: http://checkstyle.sourceforge.net/availablechecks.html
Post the full details of the rule being triggered and someone might be able to help.
You can always turn the warnings off, but they generally are here for a reason :)
Do you intend to make them abstract classes ? If so, declare them that way.
Will you need to instantiate them at some point ? If so, add a public constructor.
I'm pretty sure this will solve your problem.
On sourceforge it says that the AbstractClassName rule uses the following regex:
^Abstract.*$|^.*Factory$
This causes classes with a name starting with 'Abstract' or ending with 'Factory' to be flagged. I get the 'Abstract..' part of that, but why should all '..Factory' classes be abstract? Sometimes I create factories which use dependencies to do their work so I need an instance to inject into.
This however does not explain your case. I tried your example class and did not get any Checkstyle warning (I am using the Eclipse Checkstyle Plug-in version 5.3.0.201012121300).
Are you sure you are getting the AbstractClassName warning for this class? Which version of Checkstyle are you using?
I'm getting an anonymous class at compile-time that I'm not expecting. Relevant code follows, then a more detailed explanation:
Entirety of CircuitType.java:
public enum CircuitType { V110A20, V110A30, V208A20, V208A30 }
From Auditor.java, lines 3-9:
public class Auditor {
private String[] fileNames;
private int numV110A20;
private int numV110A30;
private int numV208A20;
private int numV208A30;
From Auditor.java, lines 104-121:
[...]
switch (newCircuit.getType()) {
case V110A20:
this.numV110A20++;
break;
case V110A30:
this.numV110A30++;
break;
case V208A20:
this.numV208A20++;
break;
case V208A30:
this.numV208A30++;
break;
default:
System.err.println("An Error Has Occured.");
System.exit(-1);
break;
}
[...]
From Circuit.java, lines 1-5:
public class Circuit {
private CircuitType myType;
public CircuitType getType() {
return this.myType;
}
[...]
When the command
javac *.java
is executed, an anonymous class Auditor$1.java is generated. The files, obviously, all sit next to each other in a file system directory that contains nothing else.
When lines 104-121 are commented out, no anonymous class is generated.
I at first thought it was a package issue, so put the three classes in a package, but I didn't know enough about packages to get it working. If it's truely a package issue, can someone step me through exactly how to label them? I'd rather not have to package them if I don't have to, though.
The reason the anonymous class is a problem, besides the fact that such classes usually signify a namespace issue, is that it breaks my Makefile I use for automatic compilation.
Update
Attached is a console session which I hope may shed light on this mystery:
% javap 'Auditor$1'
Compiled from "Auditor.java"
class Auditor$1 extends java.lang.Object{
static final int[] $SwitchMap$CircuitType;
static {};
}
I've gone ahead and built a little project containing the source you posted and just enough framework around it to make it compile. I got 3 class files: Circuit.class, CircuitType.class and Auditor.class - as expected.
All this under Java 1.6. But as others have indicated, I think your diagnosis of the problem is off.
Anonymous classes are easy to generate accidentally: Typically a construct like
Circuit myCircuit = new Circuit() {
public CircuitType getCircuitType() {
return XXX;
}
}
will create one, for example. Given more of your code, the good SO folks might be able to pinpoint your error.
It might be interesting and instructive to disassemble your class files with javap or better yet a "real" Java disassembler like JD.
Update
Added your new Auditor code to mine... no change. No anonymous classes.
Your code is of course correct (to the extent we can see it) but the design is not very OO. Some people would point out that you'll have to extend your counter declarations and your switch statement every time a new circuit type appears.
You're also not making much use of the "special features" of enums. I have a much simplified version of your Auditor method:
private int[] counters = new int[CircuitType.values().length];
public void tallySomething() {
Circuit newCircuit = new Circuit();
counters[newCircuit.getType().ordinal()]++;
}
Update 2
I found your javap output quite illuminating. See my comment below.
My conclusions:
Yes, apparently your Java impl is using an anon class for the switch. Lame, but legitimate.
You have the following options:
eliminate the switch
use a different Java implementation
live with the anonymous class; ditch make and use ant to embrace the anon classes and other strangenesses of Java.
Since you're only having problems because of your non-standard compilation setup, I'd go with the last solution and attack the problem there.
It indeed appears that (in certain cases at least) an inner class will be generated for the switch statement:
Java enum and additional class files