Во-первых, вы не можете избежать повторной разработки вашего кода людьми. Байт-код JVM должен быть простым для выполнения, и существует несколько программ для его обратного проектирования (то же самое относится и к .NET CLR). Вы можете только сделать это все более и более трудным, чтобы поднять барьер (то есть стоимость), чтобы видеть и понимать ваш код.
Обычный способ - запутать источник с помощью какого-либо инструмента. Классы, методы и поля переименовываются по всей кодовой базе, даже с неверными идентификаторами, если вы решите, что делает код почти невозможным для понимания. У меня были хорошие результаты с JODE в прошлом. После запутывания используйте декомпилятор, чтобы увидеть, как выглядит ваш код ...
Рядом с запутыванием вы можете зашифровать ваши файлы классов (все, кроме небольшого начального класса) с помощью какого-либо метода и использовать пользовательский загрузчик классов для их расшифровки. К сожалению, класс загрузчика классов не может быть зашифрован сам, поэтому люди могут выяснить алгоритм дешифрования, прочитав декомпилированный код загрузчика классов. Но окно для атаки на ваш код стало меньше. Опять же, это не мешает людям видеть ваш код, а только усложняет случайному злоумышленнику.
Вы также можете попытаться преобразовать приложение Java в некоторые EXE-файлы Windows, которые бы скрывали подсказку, что это вообще Java (в некоторой степени), или действительно компилировали в машинный код, в зависимости от ваших потребностей в функциях JVM. (Я не пробовал это.)