Motivation:
In our code we have a few places where some methods are run by their name. There are some big if-else-if blocks with each function name and call of the corresponding method (I use the term function to describe just names, for example function X01 might correspond to method SomeClass.functionX01). I've been looking into ways to improve that
Goal:
Write just methods that are annotated with some custom annotation, removing the need to update or even include if-else-if blocks in order to run specific function. Have access to any generated code if any code is generated.
What I did:
I've created first prove of concept using runtime annotations and it proved successful, but slower then if-else-if. Next attempt was with source annotation
I've followed this link for an example, however it did not seam to run in IntelliJ. What I wanted is to have - in this case PersonBuilder class generated, instead there was none. In some cases an error was raised Error:java: Bad service configuration file, or exception thrown while constructing Processor object: javax.annotation.processing.Processor: Provider BuilderProcessor not found
After some Googling and failing to find anything I've turned to book (Core Java, Volume II - Advanced Features - 9th Edition, Polish translation) and there was reccomended to run the following commands:
javac [AbstractProcessor implementation]
javac -processor [Compiled Processor] [other source files to compile]
This worked, however is unsatisfactory as it needs to happen inside IDE (NetBeans and IntelliJ to be specific) automatically during build. Code does not need to be generated on the fly, but programmer must have access to it after build (as in - be able to call methods of generated classes)
Question:
How to have and use generated code used in NetBeans and IntelliJ without the need of using external tools? Is it possible, or using reflection, runtime annotations or external tools is the only way?
Additional info (just in case):
Language level: Java 1.8
JVM versions: 12 and 13
IDEs: NetBeans and IntelliJ
Related
I'm working on a module project in NetBeans 8.2, with a GUI and everything. I'm using lots of the IDE functionality to auto-generate code for the GUI.
Every time I do a clean build of my project, I get a warning from the compiler:
warning: No processor claimed any of these annotations:javax.annotation.Generated
Browsing the build directory, I see that the IDE generates a class for me, Bundle.java, and it slaps the given annotation on top of it:
#javax.annotation.Generated(value="org.netbeans.modules.openide.util.NbBundleProcessor")
I need this warning to go away. I tried searching the web for an annotation processor that processes this specific annotation but I had no luck. Does an annotation processor for this specific annotation exist?
If this is a "harmless warning," I need to understand why it is harmless to justify its existence in my build output.
If needed I can include in this question the argument to the -processorpath option that is passed to javac from the IDE; I didn't include it on purpose because it is very long but I can add it if necessary
EDIT #1:
I did a "hacky" modification to the common.xml file under the NetBeans installation directory to make the invocation to javac not include the -processorpath option, and doing so makes the warning dissapear. I still do not understand why that is the case
A simple fix for this is to remove the #Messages annotation from the TopComponent class that is generated by the NetBeans code generator. It is that annotation that is responsible for generating the Bundle class, as per the NbBundle.Messages API Documentation.
As soon as you remove that annotation, you might get warnings from other annotations that rely on the contents of the #Messages annotation (i.e. TopComponent.OpenActionRegistration), so make sure to modify the contents of those annotation as well until nothing in your code depends on that Bundle anymore.
Hopefully nothing else in your code relies on your Bundle.
I can't guess how can I specify class, which is entry-point of my program (therefore shouldn't be obfuscated), and my jar archive. Please show me an command-line example, how to use JBCO when I have /home/example/myJar.jar and within it com.example.EntryPoint class and my external dependency /home/example/dependencies/dependencyJar.jar.
Also, please, does anybody know if this project is still alive and what jdk it supports?
A lot of time have passed, but recently I have passed across the java transformation frameworks and find out that JBCO now is a part of soot framework, hosted on GitHub, but it is #deprecated as for now. There is a wiki where you can get more info about how to use soot/jbco (if you still want to, on your own risk, even though JBCO is deprecated and not under active development it still from time to time accepts PRs from contributors).
As for the command line options it might be:
java -cp .:/home/example/sootclasses-trunk-jar-with-dependencies.jar soot.jbco.Main -process-dir /home/example/compiled -output-dir /home/example/obfuscated -soot-class-path .:/home/example/myJar.jar -output-format class -app -main-class com.example.EntryPoint -t:9:wjtp.jbco_cr
Soot can process your compiled code as class files (then pass it to -process-dir option) or as jar (then pass it as part of soot-class-path) - soot can process many forms of bytecode (java/scala/.. bytecode, android bytecode, jasmin, jimple). There are also options to specify what is library classes and application or argument classes more precisely, for more info please refer to soot's wiki page.
I have a Codename One project on Netbeans using their plugin.
Is there a way to make it work? I enabled it in project's settings and still doesn't show in final jar.
The annotations are in the libraries of the project. and I can see it being done in the output:
warning: Supported source version 'RELEASE_6' from annotation processor 'org.netbeans.modules.openide.util.ServiceProviderProcessor' less than -source '1.8'
I used instructions here: https://netbeans.org/kb/docs/java/annotations-lombok.html
Update:
I thought it was clear but seems it's not. All this is using Netbean's Lookup. Let's say I have one jar as project dependency with one interface in it, let's say ITest. Also a class implementing the interface, for example:
#ServiceProvider(service=ITest.class)
public class Test implements ITest{
..
}
So in the Codenamone Project I call it like this:
Lookup.getDefault().lookupAll(ITest.class);
But it come up empty. I know the system works as it does in other projects, just porting it to Codename one. Seems like it is not seeing the annotations in the dependencies.
I don't know if that will work and I'm pretty curious about it myself. Make sure you created a Java 8 version of the project and you are running on top of Java 8 to get started.
In the past things like this were done using bytecode manipulation e.g. see this code from the work done by Steve.
I'm looking to store Java libraries inside my Oracle database. Note that this is the first time I'm doing that. That library is pd4ml. It is made up of two jars, which contains the compiled classes.
pd4ml.jar
ss_css2.jar (required by pd4ml.jar)
As loading them with Toad did not work (Toad said they were loaded successfully, but did they not show up anywhere) I went command line (loadjava) and managed to load ss_css2.jar successfully. All its classes were loaded and compiled.
The second library, pd4ml.jar, was also loaded, but several classes won't compile. I ran ojvmtc to try to resolve references. I got the following message:
The following classes could not be found:
javax/servlet/http/HttpServletResponseWrapper
org/zefer/pd4ml/npdf/parser/c
The first one, if my understanding is correct, should be part of the JRE that is built-in 11g r2. Browsing the sys schema, it does not appear to exist.
The second one is part of the jar library. Now I'm not exactly sure of the structure of compiled Java, I've never had to look into it before, but I have several .class files inside org/zefer/pd4ml/npdf/parser/, these being: c$_b, c$_c.... to c$_g. There is none that is only c.
The library works well on my local machine when passing command line arguments or running it from Eclipse, so it should work. There is no specific error message that shows up when trying to compile them in Toad. I have a feeling it's a dependencies/classpath issue.
Any hints on how I should ensure that classes contained in pd4ml.jar can properly access those in ss_css2.jar , or any potential causes to investigate? Perhaps a way to get detailed error messages from the Java code?
The strange class names like c$_b, c$_c.... to c$_g are result of JAR file obfuscation. The obfuscation impacts only non-public classes, so it should not harm.
As I see, in your particular case javax/servlet/http/HttpServletResponseWrapper class is missing (and probably few more) - the classes can be found in servlet-api.jar. Just take the file from any J2EE (or Tomcat) distribution and add the file to your project/application.
In usual scenarios the servlet-api classes are required only when WebApp-specific PD4ML methods are called. And the methods are called only when pd4ml.jar is a part of a web application (that means servlet-api.jar is among the application resources).
As I see now, Oracle database Java sub-system scans for all referenced resources (even if they are not needed in a scenario) and panic if anything is missing.
I am trying to get Thrift working in Eclipse and having some issues. The project is a standard maven project.
I used the thrift compiler to compile the thrift file to Java code, which was successful. The generated code was placed under src/main/generated-sources//
(Is this acceptable practise?)
In eclipse, I added the src folder from the build menu, but then I get:
Cannot reduce the visibility of the inherited method from ProcessFuction<I,...
I am not using the maven thrift plugin as the source is already generated and within the source tree (again, is this advisable?).
How should I configure this setup?
seems like the Thrift compiler is not as good as thought.
Cannot reduce the visibility of the inherited method
shows that a inherited method from an abstract class or an interface has originally a higher visibility, e.g. "public" while you have "private" in your code.
I would try to set that to "public" and see what happens. The code might compile sweet, as I expect that mismatch to be generated due to compiling/transformation of code with missing visibility setting on the method as one can write a method header without specifying the visiblitiy:
void doany(){
// nothing
}
The method uses the classes visibility in that case (mostly "public") - which the compiler will have misunderstood.