I'm looking for a way to mask specific code lines in the IDE. I prefer doing it in eclipse, but intellij would be fine also.
The purpose is, that when I have a method like this:
public String serialize() {
log.info("Starting to serialize");
StringBuilder sb = new StringBuilder();
sb.append("name: " + this.name);
sb.append("age: " + this.age);
sb.append("sex: " + this.sex);
log.info("Finished serializing. The result is: " + sb.toString());
return sb.toString();
}
I will make it look like this:
public String serialize() {
StringBuilder sb = new StringBuilder();
sb.append("name: " + this.name);
sb.append("age: " + this.age);
sb.append("sex: " + this.sex);
return sb.toString();
}
This is of course only an example. I work with code that contains a lot of log lines and a lot of metrics for better monitoring of the app. This clutters the code massively and I wish to only see code logic when I code.
Does either of the mentioned IDE (or another one) enable this feature?
That is which aspect oriented programming is for. This is a simple thing, only same programmer/marketing people gave it this flam name.
You should hook the serialize() function/method with your logging chunk. Quiet simple.
I suggest you start some googling for "AspectJ".
Related
I am making a permissions plugin, and want to replace the name of a player with their rank tag. For this, I have the following code:
public void playerChat(AsyncPlayerChatEvent e) {
Player target = e.getPlayer();
String message = e.getMessage().replaceAll(target.getName(), colorize(rFile.getString("players." + target)) + " " + target.getName());
e.setMessage(message);
}
Whenever I send a message to chat, it appears like it would normally.
What am I doing wrong here?
Additionally, I am using a config file (cFile) and a ranks.yml file (rFile).
First off, make sure you include the #EventHandler annotation.
#EventHandler
public void playerChat(AsyncPlayerChatEvent e) {
[...]
}
Next, check if the listener is registered in your onEnable()method.
getServer().getPluginManager().registerEvents(new YourListener(...), this);
(Replace the YourListener with this in case it's your main class)
Finally, as Luftbaum said, use AsyncPlayerChatEvent#setFormat within the event.
Example Usage:
e.setFormat(colorize(rFile.getString("players." + target)) + ": " + e.getMessage());
Edit:
In order to translate color codes such as '&3' to Bukkit's ChatColor format, you can use the ChatColor#translateAlternativeColorCodes method.
ChatColor.translateAlternateColorCodes('&', stringThatContainsCodes);
Useevent.setFormat(playerRank + ": " + event.getMessage());
This basically formats the message to be the way you want. You can use ChatColor to do colors. Also make sure you have #EventHandler.
I'm trying to write some Bytecode manipulation in my web application now when I try to inject my code into my methods it always throws me the error
javassist.CannotCompileException: [source error] ) is missing
I don't know why and what this is ... I've googled a bit and some people say It's a bug from version 1.0 javassist but I thinks that's really unrealistic.
private void changeMethod(CtMethod method) throws NotFoundException,
CannotCompileException {
if (method.hasAnnotation(Loggable.class)) {
method.getName();
method.insertBefore("long startTime = 0;" +
"long startTime = System.currentTimeMillis();" +
" Thread thread1 = new Thread(new Runnable(){\n" +
" #Override\n" +
" public void run() {\n" +
" threadLogger.info(\"Testlog\");\n" +
"\n" +
" try {\n" +
" threadLogger.logCall(Webservice.this.getClass().getMethod(startThread0), \"Thread\");\n" +
" \n" +
" } catch (Exception e) {\n" +
" e.printStackTrace();\n" +
" }\n" +
"\n" +
" }\n" +
" });\n" +
" thread1.start();");
}
}
enter code here
As you can read in the Javassist documentation, section 4.7 Limitations (bold is mine):
Inner classes or anonymous classes are not supported. Note that this
is a limitation of the compiler only. It cannot compile source code
including an anonymous-class declaration. Javassist can read and
modify a class file of inner/anonymous class.
You are attempting to inject an anonymous Runnable class, so it won't work. Your best way around this issue is to extract the Runnable class code to a new class that is available in the classpath at injection and runtime and use that class in the injection code.
Refers to compilation errors in the source code inside the string. The first problem I can spot is that you have
long startTime = 0;
long startTime = System.currentTimeMillis();
You are defining the variable twice and this won't compile.
Overall the easiest way I have found to write Javassist code is to copy this from your IDE class. This will help you spot most of the problems and can save you some time debugging code in Strings. Of course it is not perfect because most of the time the code won't compile in the IDE because it is referencing something that will work only in code insertion point but it will find problems like double variable etc.
I wrote a Method now and just injectet the method with bytecode manipulation ... was the simplest resolution.
I am struggling for a couple of hours now on how to link a discid to a musicbrainz mbid.
So, using dietmar-steiner / JMBDiscId
JMBDiscId discId = new JMBDiscId();
if (discId.init(PropertyFinder.getProperty("libdiscid.path")))
{
String musicBrainzDiscID = discId.getDiscId(PropertyFinder.getProperty("cdrom.path"));
}
or musicbrainzws2-java
Disc controller = new Disc();
String drive = PropertyFinder.getProperty("cdrom.path");
try {
DiscWs2 disc =controller.lookUp(drive);
log.info("DISC: " + disc.getDiscId() + " match: " + disc.getReleases().size() + " releases");
....
I can extract a discid for freedb or musicbrainz easily (more or less), but I have not found a way on calculating the id I that I need to download cover art via the CoverArtArchiveClient from last.fm.
CoverArtArchiveClient client = new DefaultCoverArtArchiveClient();
try
{
UUID mbid = UUID.fromString("mbid to locate release");
fm.last.musicbrainz.coverart.CoverArt coverArt = client.getByMbid(mbid);
Theoretically, I assume, I could you the data collected by musicbrainzws2-java to trigger a search, and then use the mbid from the result ... but that cannot be the best option to do.
I am happy about any push into the right direction...
Cheers,
Ed.
You don't calculate the MBID. The MBID is attached on every entity you retrieve from MusicBrainz.
When getting releases by DiscID you get a list. Each entry is a release and has an MBID, accessible with getId():
for (ReleaseWs2 rel : disc.getReleases()){
log.info("MBID: " + rel.getId() + ", String: " + rel.toString());
}
You then probably want to try the CoverArtArchive (CAA) for every release and take the first cover art you get.
Unfortunately I don't know of any API documentation for musicbrainzws2 on the web. I recommend running javadoc on all source files.
I believe that most of you would be thinking that this is the same question you have heard multiple times (and answered ) about string concatenation in Java. But trust me, it is different. In fact, so different that I am even hesitant in posting it here. But anyways, here it is. I have some piece of code which goes like:
public void handleSuccess(String result)
{
result = result.trim();
MessageBox.alert("Information","Result after trimming: '" + result + "'");
result = result.substring(result.indexOf('\n') + 1);
MessageBox.alert("Information","Result after substring: '" + result + "'");
String returns = getReturns();
MessageBox.alert("Information","Returns: '" + returns + "'");
String action = getAction();
MessageBox.alert("Information","Action: '" + action + "'");
String finalResult = result + returns + action;
MessageBox.alert("Information","Final result: '" + finalResult + "'");
}
Now the situation here is that, all of these : getReturns(), result and getAction() return non blank values, and in fact the string finalResult contains the concatenated value after the last line is executed.
So, at Line 1, "result" contains "12/03/2013|04-AERTY|". The value of result remains same at end of line 1,2. getReturns() returns value 12.4724. So at end of line 3, finalResult contains "12/03/2013|04-AERTY|12.4724". getAction() returns "expt". So, at end of line 5, finalResult contains "12/03/2013|04-AERTY|12.4724|expt"
This is , when I debug or run the application in eclipse. As soon as build the same application on a UNIX system to generate a "war" file, and deploy the war on a tomcat server, the problem rears it's ugly head. When I run the application on the deployed war, the last line does not contain the concatenated value. So at the end of line 5, finalResult contains just "12/03/2013|04-AERTY|12.4724". I expected it to contain "12/03/2013|04-AERTY|12.4724|expt" as it does while running in eclipse.
I have tried stringbuffer, stringbuilder and the "+" operator as well, but nothing seems to work. I am not even getting an exception.
Can somebody help me in fixing this or at least enlightening me in what I might be doing wrong here?
Just to stress again, the code on eclipse(which is on a windows machine) and UNIX machine are exactly same. I have done a diff on them.
Here is what I get after putting the message-boxes:
Message-box 1: "Result after trimming: '12/03/2013|04-AERTY|'"
Message-box 2: "Result after substring: '12/03/2013|04-AERTY|'"
Message-box 3:"Returns: '12.4724'"
Message-box 4:"Action: '|expt'"
Message-box 5:"Final result: '12/03/2013|04-AERTY|12.4724|expt'"
Message-box 5 output is the one I receive when I execute code using eclipse
When running on deployed war, Message-box 1-4 have the same output as above, but Message-box 5 says: "Final result: '12/03/2013|04-AERTY|12.4724"
It's not clear where the extra "|" is meant to come from - if getAction() just returns expt, the result would be 12/03/2013|04-AERTY|12.4724|expt.
Anyway, I think it's safe to say that string concatenation will be working fine, and something else is wrong. You should add more diagnostics, logging everything:
public void handleSuccess(String result) {
result = result.trim();
log.info("Result after trimming: '" + result + "'");
result = result.substring(result.indexOf('\n') + 1);
log.info("Result after substring: '" + result + "'");
String returns = getReturns();
log.info("Returns: '" + returns + "'");
String action = getAction();
log.info("Action: '" + action + "'");
// It's not clear what this is meant to do. I suggest you remove it and
// use logging instead.
MessageBox.alert("Information", "The selected action is " + action, null);
String finalResult = result + returns + action;
log.info("Final result: '" + finalResult + "'");
I suspect you'll find that action is an empty string in the broken case.
Note that I've added quotes round each of the logged values, very deliberately. That means that if there's some unprintable character at the end of a string which causes problems, you should be able to detect that in the logging.
EDIT: As per the comment thread, when these were turned into message boxes (as it turns out this is running in GWT) it looks like there's something wrong with the early strings, as the closing ' isn't seen in diagnostics, in the broken case. The OP is going to investigate further.
I have a program which scans a Java file for errors. I call the compiler from Eclipse and run a scan on the Java file and get the line numbers, start position and end positon as output. I have written a program to extract the error from the file.
What I want to do is to have access to the quickfix component in eclipse, have a list of possible fixes for the problem, and print that list to the console.
Below is a portion of the program of how I called the compiler and got the details printed on the console:
Iterable fileObjects = fileManager.getJavaFileObjectsFromStrings(
Arrays.asList(fileToCompile));
CompilationTask task = compiler.getTask(null, fileManager, listener, null,
null, fileObjects);
Boolean result = task.call();
if(result == true) {
System.out.println("Compilation has succeeded");
}
myerrors = listener.getlistofErrors();
for (CaptureErrors e : myerrors) {
System.out.println("Code: " + e.getCode());
System.out.println("Kind: " + e.getKind());
System.out.println("Line Number: " + e.getLinenumber());
// System.out.println("Message: "+ e.getMessage(Locale.ENGLISH));
// System.out.println("Source: " + diagnostic.getSource());
System.out.println("End position"+ e.getEndposition());
System.out.println("Position: "+ e.getPosition());
System.out.println("\n");
}
class MyDiagnosticListener implements DiagnosticListener {
List<CaptureErrors> errors = new ArrayList<CaptureErrors>();
public void report(Diagnostic diagnostic) {
CaptureErrors single_error = new CaptureErrors(diagnostic.getCode(),
diagnostic.getKind(), diagnostic.getLineNumber(),
diagnostic.getMessage(Locale.ENGLISH), diagnostic.getPosition(),
diagnostic.getEndPosition());
errors.add(single_error);
}
public List<CaptureErrors> getlistofErrors() {
return errors;
}
}
I also have a program to go to the line numbers and extract the text(error) at specific positions.
How can I call eclipse quickfix solutions for the specific errors that I find?
Yes, it is possible. The exact details are a bit larger than can easily be encompassed in even a StackOverflow answer.
Eclipse is extended through the use of plug-ins. A "Hello World" plugin is detailed here, and after you get through the initial learning curve, you can download other plugins to get a feel for how eclipse works internally.
I imagine that you would do well to examine the current code highlighting capabilities of eclipse and read the source code for those plugins as a guide, but only after you get some idea of how plugin development works.