Unexpected Character $ - Java Binding error - java

I am trying java binding to a Xamarin forms project and the jar contains class name having $ and also variable names with $. I am getting "Unexpected Character $" error. I am trying to solve it by editing the metadata.xml file. It seems that I am doing it wrong, please check the following entries,
For the class names containing $. I am using,
<attr path="/api/package[#name='com.wed.therace']/class[#name='CarDetails$']"
name="obfuscated">false</attr>
for the variables containing $,
<attr path="/api/package[#name='com.wed.therace']/class[#name='CarDetails$']/fie ld[#name='machineParts$']"
name="obfuscated">false</attr>
What is the correct way? I got this from https://developer.xamarin.com/guides/android/advanced_topics/binding-a-java-library/customizing-bindings/java-bindings-metadata
Thanks in advance,

The sample you tried disables obfuscation for certain types or members. But $ doesn't necessary mean the code has been obfuscated. Here's the common flow for you of what to do in such cases:
Navigate to the error source to see the generated output C# code. In your error message you'll most likely see something like Error: obj/Debug/src/234.cs (30, 50). Look into this file and see what happens in it on line 30. In your case you'll see a field containing $ in its name which leads to compilation error. Pay attention there is a generator comment line in this file starting with // Metadata.xml XPath ... path="/api/package[#name=...]", like this. You can just copy the path="..." part to use it for configurations in manifest.xml.
Look into generated api.xml file located in obj/Debug (or obj/Release depending or your current config). Try looking for the member definition you have issue in. You should be able to find your field, method or another member there with all its attributes like static, deprecated, obfuscated etc. That's what you can affect with metadata transformations.
Now depending on your situation try one of the following:
If you don't need this type or member in your code, just get rid of it by using remove-node metadata element. Get the path value from the generated sources as described above. Remember you can either remove the error member or the whole type if you don't need it.
If you do need this member, define a rename transformation in metadata like this: <attr path="<copied_from_sources>" name="managedName">ValidNameHere</attr>.
Sometimes you'll need to clean the obj folder to make changes applied. Usually it works correct though.

Related

Why does importStatic Eclipse template variable need a namespace?

I'm trying to use Eclipse templates (in Juno) to generate statements for both regular and static imports and ran into something odd.
After consulting the docs my first attempt was this
${:import(org.junit.Test)} //ok
${:importStatic('org.junit.Assert.*')} //gives error
:import works fine, but :importStatic gives this error
Template variable '' has incompatible types
But the syntax above is exactly how it's presented in the docs, where :importStatic is identical to :import in the left-hand column.
I noticed the example in the right-hand column, which uses a namespace is in front of :importStatic
${is:importStatic(...
So I added that namespace, the error went away, and the template works
However I'm a little bugged by this magical unexplained is namespace - I can't find any explanation in the docs of where it comes from. In fact, playing around a little it seems there's nothing special about is at all - turns out any namespace in front of :importStatic will work.
${donkey:importStatic(... //works fine...
So, does anyone know why a namespace is necessary for :importStatic but not :import?
Is the error and the fact it won't save without a namespace just a bug in the template editor or am I missing something?
This is not a namespace, it is an id for the variable used in the template - except that import and importStatic should not need a variable.
I believe what you are see is Eclipse bug 336989 where leaving out the id on two statements causes this problem. As you have found the workaround is to specify an id even though it is not required.

Java find where a class is used in the code - programmatically

I have a List of classes which I can iterate through. Using Java is there a way of finding out where these classes are used so that I can write it out to a report?
I know that I can find out using 'References' in Eclipse but there are too many to be able to do this manually. So I need to be able to do this programmatically. Can anyone give me any pointers please?
Edit:
This is static analysis and part of creating a bigger traceability report for non-technical people. I have comprehensive Javadocs but they are not 'friendly' and also work in the opposite direction to how I need the report. Javadocs start from package and work downwards, whereas I need to start a variable level and work upwards. If that makes any sense.
You could try to add a stacktrace dump somewhere in the class that isolates the specific case you are looking for.
public void someMethodInMyClass()
{
if (conditions_are_met_to_identify)
{
Thread.dumpStack();
}
// ... original code here
}
You may have to scan all the sources, and check the import statements. (Taking care of the * imports.. having to setup your scanner for both the fully Qualified class name and its packagename.*)
EDIT: It would be great to use the eclipse search engine for this. Perhaps here is the answer
Still another approach (probably not complete):
Search Google for 'java recursively list directories and files' and get source code that will recursively list all the *.java file path/names in a project.
For each file in the list:
1: See if the file path/name is in the list of fully qualified file names you are interested in. If so, record is path/name as a match.
2: Regardless if its a match or not, open the file and copy its content to a List collection. Iterate through the content list and see if the class name is present. If found, determine its path by seeing if its in the same package as the current file you are examining. If so, you have a match. If not, you need to extract the paths from the *.import statements, add it to the class name, and see if it exists in your recursive list of file path/names. If still not found, add it to a 'not found' list (including what line number it was found on) so you can manually see why it was not identified.
3: Add all matches to a 'found match' list. Examine the list to ensure it looks correct.
Not sure what you are trying to do, but in case you want to analyse code during runtime, I would use an out-of-the box profiler that shows you what is loaded and what allocated.
#Open source profilers: Open Source Java Profilers
On the other hand, if you want to do this yourself (During runtime) you can write your own custom profiler:
How to write a profiler?
You might also find this one useful (Although not exactly what you want):
How can I list all classes loaded in a specific class loader
http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html
If what you are looking is just to examine your code base, there are really good tools out there as well.
#see http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis

Can I put comments in between or after multiline properties in a Java Properties file?

I've got a properties configuration file with properties that have many values separated by commas. I want to put comments next to some of them, but it seems that this is not possible?
I want to be able to do something like this:
property: value1,\
value2,\
...
value44,\
value45,\
# value45 comment
...
value89,\ # another comment
value90
Clarification: I'm supplying the config to a web service I don't own, so I can't use one of the extensions to the properties format like bracket-properties
Unfortunately, it's not possible as Java properties files can have only single line # comments.
However, you might be aware that you can also define properties in xml format and the XML syntax will let you enter multi-line comments.
If you decide to give XML a chance then you will need to call Properties#loadFromXML(InputStream) to load your XML property file.
This is not possible. A comment must appear on a line by itself, and it consists of optional white space followed by the "#" or "!" character, and then arbitrary text up to the end-of-line. You can find the full specification of Java Properties files in the Javadoc documentation for the load(java.io.Reader reader) method of the java.util.Properties class.

How to get the path string from a java.nio.Path?

Rewrote question with more info
I have some code that creates a Path object using relative paths, like this: Paths.get("..", "folder").resolve("filename"). Later, I want to get the path string "..\folder\filename" from it (I'm on windows, so backslashes). When I run this code using manual compile or from Eclipse, this works fine.
However, when I run it using Maven, it doesn't work any more. The toString() method returns [.., folder, filename] instead of an actual path string. Using path.normalize() doesn't help. Using path.toFile().getPath() does return what I'm looking for, but I feel there should be a solution using just the nio.path API.
Use:
Paths.get(...).normalize().toString()
Another solution woul be:
Paths.get(...).toAbsolutePath().toString()
However, you get strange results: Paths.get("/tmp", "foo").toString() returns /tmp/foo here. What is your filesystem?
To complete the the fge's answer, I would add some info:
normalize() simply removes redundant pieces of strings in your path, like .
or ..; it does not operate at the OS level or gives you an absolute path from a relative path
toAbsolutePath() on the contrary gives you what the name says, the absolute path of the Path object. But...
toRealPath() resolves also soft and hard links (yes they exists also on Windows, so win user, you're not immune). So it gives to you, as the name says, the real path.
So what's the best? It depends, but personally I use toRealPath() the 99% of the cases.
As pointed out by Roberto Bonvallet, since toRealPath() throws an exception if the file does not already exist because, for example, you want to create it. In this case I prefer toAbsolutePath().
Source: Official javadoc

Can I automatically refactor an entire java project and rename uppercase method parameters to lowercase?

I'm working in a java project where a big part of the code was written with a formatting style that I don't like (and is also non standard), namely all method parameters are in uppercase (and also all local variables).
On IntellJ I am able to use "Analyze -> Inspect Code" and actually find all occurrences of uppercase method parameters (over 1000).
To fix one occurrence I can do "refactor > rename parameter" and it works fine (let's assume there is no overlapping).
Is there a way to automagically doing this refactor (e.g: rename method parameter starting with uppercase to same name starting with lowercase)?
Use a Source Parser
I think what you need to do is use a source code parser like javaparser to do this.
For every java source file, parse it to a CompilationUnit, create a Visitor, probably using ModifierVisitorAdapter as base class, and override (at least) visit(MethodDeclaration, arg). Then write the changed CompilationUnit to a new File and do a diff afterwards.
I would advise against changing the original source file, but creating a shadow file tree may me a good idea (e.g. old file: src/main/java/com/mycompany/MyClass.java, new file src/main/refactored/com/mycompany/MyClass.java, that way you can diff the entire directories).
I'd advise that you think about a few things before you do anything:
If this is a team effort, inform your team.
If this is for an employer, inform your boss.
If this is checked into a version control system, realize that you'll have diffs coming out the wazoo.
If it's not checked into a version control system, check it in.
Take a backup before you make any changes.
See if you have some tests to check before & after behavior hasn't changed.
This is a dangerous refactoring. Be careful.
I am not aware of any direct support for such refactoring out of the box in IDEs. As most IDEs would support name refactoring (which is regularly used). You may need to write some IDE plugin that could browse through source code (AST) and invoke rename refactoring behind the scene for such parameter names matching such format.
I have done a lot of such refactorings on a rather large scale of files, using TextPad or WildPad, and a bunch of reg-ex replace-all. Always worked for me!
I'm confident that if the code is first formatted using an IDE like Eclipse (if it is not properly formatted), and then a reg-ex involving the methods' signature (scope, return-type, name, bracket, arg list, bracket) can be devised, your job will be done in seconds with these tools. You might need more than one replace-all sets of reg-ex.
The only time-taking activity would be to come up with such a set of reg-ex.
Hope this helps!

Categories

Resources