Eclipse class resolution for automatically generated classes in classes folder - java

We are using a custom "eclipse builder" that generates output class files in the project classes folder (Those are some automatic utility classes).
We are not able to tell eclipse to take these automatically generated classes into consideration to help with our coding. The classes remain invisible to eclipse.
We also tried to manually edit the .classpath file. Even this did not work (only when we renamed the classes folder to something else).
It sounds like this is a scenario that is not uncommon: have custom builders generate some extra code/classes in the classes directory, and then include this into the normal coding process. Btw: in our case there is also a normal build step (outside of eclipse) where the automatic classes are generated with no problems here.
Why eclipse does not see those classes? How can we tell eclipse to include this in its class resolution?
Update: Further context and information
Goal: How to use auto-generated classes (bytecode) without generating source-code (in eclipse)
Description: We are trying to use classes for coding, which do not exist as sources, but whose bytecode is auto-generated (similar to how Lombok generates new methods).
This didn't work:
We use a custom builder that runs before the java builder, and let it write the .class files to the default output folder. But the java builder doesn't consider these classes at all and complains that the referenced class cannot be found.
Apparently the default output folder for java builder (typically "classes") cannot be at the same time input for the java builder. Thus, the solution is to have another folder like "classes_generated", and mark this a library input for the java builder. This can also be exported to be visible to other projects.
Thus, the "problem" is simply that the default output folder for the java builder cannot be used as input for the java builder. Maybe even for a good reason? But, there are workarounds for this.

Related

auto-generated java files in Eclipse

How to understand which are the auto-generated files in a huge Java project developed in Eclipse?
I am a newbie. For example, little by little, I am discovering that many files are generated by using xcore plug-in. Other with xtend. Just going through the code and trying I am learning and that's ok. The question is: is there a way to understand which files to modify to automatically regenerate the others? My error was to start modifying all the files manually.
Usually you set up different source directories for your code and generated code.
For example, a project using Xtend and EMF would have following source directories in its build path:
src contains all Java and Xtend files that you write
xtend-gen contains generated Java files created by Xtend
src-gen contains generated Java files created by EMF
In this setup you should only edit files in src. Files in xtend-gen will be updated automatically if you edit Xtend files in src. Files in src-gen will be updated if you regenerate the model.
I'm not that familiar with Xcore, but since it is based on EMF I think you just have to set the "model directory" property of the genmodel.
This should make the distinction between your code and generated code more clear. You may still feel the need to modify generated code sometimes. EMF actually supports this by adding special annotations in the generated file but I would not recommend this, because it's very hard to see if a file has been modified this way. If you really need to change the generated behavior, the first approach described in this article about properly overriding generated EMF code is better. Basically you extend and override methods of some generated classes and the factory and then use Eclipse extension points to replace the generated factory with your extended one.
If you are looking at a project of someone else and don't know which code generating tools are used:
You should try to ask the authors if possible or check if there is any documentation about building the project. Otherwise I guess you'll need to analyze the project structure to see which plugins are used to generate code. This might be a bit hard if you don't already know which plugins actually can generate code though.
Check the Eclipse "Project Nature" to see which plugins are used to build
Check build configuration (Ant, Maven, Gradle) for plugins that might generate code
Look for special files (xcore, genmodel, etc) and figure out to which
Check if there are any Annotation Processors configured and check if they create any files
(Xtend only) Check if there are Active Annotation and check if they create any files
Check if #Generated annotations is used in the code, which is used to mark generated files
If you have Identified all tools, then try to change the model destination directory and regenerate the code. Then compare the generated files with your original code - all duplicated files are likely generated.

Where to store classes generated at runtime in a java web application?

I've created a project that dynamically writes, compiles and instantiates a new java class at runtime and it works just fine when I run this on the command line or within eclipse. Ultimately my goal is to create a technology very similar to JSP; the user provides a "template" file and I translate it into a java class and instantiate that class. My problem is that I can't seem to instantiate the newly compiled class when in the context of a web application.
The core of my problem is that I don't know where to put my compiled classes so that I can immediately instantiate them.
Here are my goals:
This will be a generic tool for other developers so it can't be specific to my filesystem or my java container.
If the user undeploys their webapp from the container it should also remove these generated classfiles.
Here are my thoughts but I have never done anything like this before:
Do I put these generated classes into one of the existing entries of the classpath, if so which one? Should I let the user provide a path and then my library will add this path onto the classpath? Maybe they provide a path and I just use a custom class loader to read them from that path? The user already provides the path of their "templates" (ex. WEB-INF/templates) so should I put my compiled classes with the original templates? My understanding is that translated JSP files are stored in a proprietary place specific to that java container and therefore I can not follow in the footsteps of JSP files.
Ahh! I'm overwhelmed! Maybe there's an open source java library that does something similar and I can study it to determine where it puts it's generated files??
Basically you will need to define your own classloader and do the loading from there.
See How do you change the CLASSPATH within Java?

In Java, should I be creating a new Package, Folder, or Source Folder?

There are a couple of questions on SO that sort of hit this, but I am totally new to Java development and I don't know the correct way to approach this.
I have a C# solution, containing two projects (my app, and a unit test project) and within the app, most things are put into folders eg. Interfaces, Exceptions etc.
I am trying to recreate this in Java / Eclipse, but I don't know how. I ended up with lots of packages, which sounds really bad. I also tried adding a source folder but that ended up being outside of the package.
Could anyone point me in the right direction?
Namely, which of those should I use to represent my unit test project/set of unit tests, and subfolders which exist just for organising stuff.
Edit: It also says use of the default package is not advised. What should I be doing?
Edit 2: Here is what it looks like. Does this look vaguely correct? My original C# solution is on the right.
In a typical java eclipse project, you will have one or more source folders (for example one for app code, one for your unit tests).
Each folder contains a package tree, typically starting with your base package, for example com.mycompany.myapp.
In order to avoid name collisions, packages names are usually start with the domain name of the entity who is the author of the code, starting with the top-level-domain and going backwards (more general to more specific). That way, each class fully qualified name is unique. For example if google creates a class named List, it will be known as com.google.List, and it will not enter in conflict with the existing java.util.List interface.
You can have a unlimited number of packages inside this base package, for example :
com.mycompany.myapp.persistence
com.mycompany.myapp.domain
com.mycompany.myapp.services
com.mycompany.myapp.web
It all depends on your project and the way you want to organize your code and your classes.
At the logical level, packages are named with dots as separator. They contain java classes.
At the physical on disk level, each package is a directory. The java classes are contained in .java files (most frequently one class per file).
In Eclipse a "source folder" is a folder inside your project that is known to Eclipse to contain java source files. It will be compiled included in the output (for example JAR file) when you build your project.
In Eclipse, you usually view them at the logical level, showing packages. When you tell Eclipse to "create a new package", it will create the directory for you. For example, if you tell it to create the com.mycompany.myproject package, it will automatically create a com folder containing a mycompany folder containing a myproject folder.
In java source tree structure must match package structure
so foo.bar package must be laid out in
src/foo/bar
Also default package may not be advised - but you can still use it - better to put things in a package though
In java different project development structure are flowed according to type of project.
So as you are new to java and Eclipse so it's better to install maven plugin and create maven project and choose a archetypes according to your project type like a standalone or web based.
The maven plugin will create the project structure including packages,test packages source folder etc. You can get more about project structure from this
Using the default package may create namespace collisions. Imagine you're creating a library which contains a MyClass class. Someone uses your library in his project and also has a MyClass class in his default package. What should the compiler do? Package in Java is actually a namespace which fully identifies your project. So it's important to not use the default package in the real world projects.

jar libraries and separate .java files in Eclipse

I am programming in java using Eclipse, I am a novice and I'm stuck with the following problem: I have an Eclipse project that uses an external jar library. In this library there is a specific class that needs to be temporarily modified. I have the source code for this class. Is it possible to somehow include the source file for the code into the project, so that it will "override" the corresponding class in the jar file?
Thank you.
Basically, it's not possible to have two classes with the same signature (package + name) in the classpath but it's possible to import this class in your project in different package and use it instead of the original one.
Another way to solve this problem is to edit the .jar file by removing or changing the class that you need to be different.
However, note that changing an API is almost never a good idea.

Public class outside a jar file containing multiple packages

So, I have a Java project containing several packages (like com.myapp.a , com.myapp.b, com.myapp.c) for better readability and I want to build a jar to use as a library in another project.
But I just want to expose only some classes and interfaces from this jar. The problem is that if I don't declare these classes public then they can't be seen inside the jar file between the packages (for example I have a class A in com.myapp.a package that is used in com.myapp.b package).
So how can I expose just what I want outside of the jar when I have multiple packages defined inside?
Currently Java does not address this problem directly.
OSGi adresses this problem by explicitly defining the exported package list.
Also hopefully this will be addressed with the Java 8 Modularity system as well.
So one option is to use OSGi, but this option does not work if the jar file is used directly rather than as an OSGi bundle.
Another option is to use code obfuscation (like Proguard), to obfuscate the packages you do not want to expose.
Eclipse "solved" this problem by making all classes available, but classes that were not intended to be used by clients were placed in packages whose name contains "internal". For example, that might mean that you have packages named "com.myapp.b" and "com.myapp.internal.b". It's made clear to users of the classes that internal classes are not guaranteed to be upwardly compatible or even present in later releases.

Categories