Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Build classes in same package into separate jars

Tags:

java

build

I have a server application and two Swing-based client applications. We're developing them in eclipse and there's a separate project for each.

Many classes are shared. For example, the my.server package has some classes for both the server and the clients while others are for the server only. Although I prefer to put them in the same package because they are closely related and some of them rely on package visibility, I don't want to distribute classes that an application does not need as not only would it bloat the file size, but also it would be a security risk.

At the moment, each of the server and the clients has the same jars, which is a mess. Ideally, I'd like to automatically create jars based on dependency as following.

Server:

  • server.jar: classes used by Server only
  • server-client1-common.jar: classes shared by Server and Client 1
  • server-client2-common.jar: classes shared by Server and Client 2

Client 1:

  • client1.jar: classes used by Client 1 only
  • server-client1-common.jar: classes shared by Server and Client 1
  • client-common.jar: classes shared by Client 1 and Client 2, but not Server

Client 2:

  • client2.jar: classes used by Client 2 only
  • server-client2-common.jar: classes shared by Server and Client 2
  • client-common.jar: classes shared by Client 1 and Client 2, but not Server

I realize that you can do this manually using ant, but it would be a maintenance disaster. Is there a tool that takes care of such dependency automatically?

like image 397
Tom Tucker Avatar asked Jan 30 '12 15:01

Tom Tucker


2 Answers

What do you mean by "maintenance disaster"? If you create an ANT script, just run it and it will compile and pack the jars for you.

As a more robust alternative, you might use maven. For something more lightweight, the built-in eclipse export tool might work.

like image 163
Marcelo Avatar answered Nov 09 '22 14:11

Marcelo


I cannot present you with a ready-to-go solution. Here's an idea though: create an annotation or a set of annotations like this:

@jarselector(types='server')
class ServerOnly {
   ...
}

@jarselector(types='server,client1')
class ServerAndClient {
   ...
}

Then create your own ant task by extending the jar task (or maven plugin) or write your own task, that takes this annotation and packages classes according to the annotation, which you would then be using as a filter.

You would only have to create the task once - I've done it in the past, it is less complicated than it sounds and the problem sounds big enough to warrant the effort.

Afterwards you have to annotate all your classes once (or depending on your implementation only those classes the clients need, or only those that are not shared by every jar etc.). Whoever sees a class can see immediately what it is used for. When creating a new class you can easily add the annotation.

I really don't think there is a ready made ant task or maven plugin that does this.

Alternatively - if you really cannot change your package structure - you could also use multiple source directories to keep the packages but split the files in different directories. Eclipse doesn't care how many source directories you use. You would then need to adapt your build tool just once for the source directories and could then sort the files that way.

like image 3
Yashima Avatar answered Nov 09 '22 14:11

Yashima